应用场景:

有这么一个返现的系统,当前端客户发起提现的时候,后端就要通过审核这笔返现订单,才可以返现到客户的账号里。

来看看下面的截图

这里的业务场景就是经过两轮审核:销售审核,财务审核都通过后,后端就会付款一笔钱到客户,当然,这里财务审核会有很多种情况,不通过与通过,通过后直接付款又有很多种情况,详细可以查看微信付款到零钱的文档。下面就来看看具体你的代码实现

微信支付配置

1,数据表大概如下

CREATE TABLE `zmq_weixin_config` (
`id` int(1) unsigned NOT NULL AUTO_INCREMENT COMMENT '微信公众平台编号,自增id',
`weixin_name` varchar(10) NOT NULL COMMENT '微信公众平台名称',
`token` varchar(100) NOT NULL,
`appid` char(18) NOT NULL,
`appsecret` char(32) NOT NULL,
`access_token` varchar(300) NOT NULL,
`api_ticket` varchar(300) DEFAULT NULL COMMENT '微信卡包api_ticket',
`api_ticket_expired_at` datetime DEFAULT NULL COMMENT '微信卡包api_ticket过期时间',
`mchid` varchar(20) DEFAULT NULL COMMENT '商户号',
`mchkey` varchar(50) DEFAULT NULL COMMENT '支付密钥',
`expired_at` timestamp NULL DEFAULT NULL COMMENT 'access_token过期时间,会自动更新',
`updated_at` timestamp NULL DEFAULT NULL COMMENT '记录更新时间',
`created_at` timestamp NULL DEFAULT NULL COMMENT '创建时间',
`sort_order` smallint(5) NOT NULL DEFAULT '' COMMENT '排序',
`points_url` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='微信配置表';

2 .config的配置方法

/**
* 获取微信支付配置
* 这里我是把配置信息存储在数据表里,方便调用
* $param是从controller里传值过来:weixin_config_id,notify_url
* @return array
*/
public function getWechatConfig($param)
{
$weixin = WeixinConfigBaseModel::find($param['weixin_config_id']);
if (empty($weixin)) {
throw new Exception('微信配置ID错误');
} return [
'wechat' =>[
$app_id => $weixin->appid,
'mch_id' => $weixin->mchid,
'notify_url' => empty($param['notify_url']) ? '' : $param['notify_url'], //回调url
'key' => $weixin->mchkey,
'cert_client' => resource_path().'/wechat/'.$weixin->id.'/apiclient_cert.pem', //证书与key
'cert_key' => resource_path().'/wechat/'.$weixin->id.'/apiclient_key.pem',
]
];
}

企业付款到个人零钱核心代码

/**
* Function:企业付款到个人零钱
* Author:cyw0413
* @param $openid
* @param $trade_no
* @param $money
* @param $desc
* @return array
*/
public function weixinPay($input){ $config = $this->getWechatConfig($input); $params["mch_appid"]= $config['wechat']['app_id'];
$params["mchid"] = $config['wechat']['mch_id'];
$params["nonce_str"]= date("YmdHis").mt_rand(100,999);
$params["partner_trade_no"] = $input['trade_no']; //商户订单号
$params["amount"] = $input['amount'];
$params["desc"] = $input['desc'];
$params["openid"] = $input['openid'];
$params["check_name"]= 'NO_CHECK';
$params['spbill_create_ip'] = $_SERVER['SERVER_ADDR']; //生成签名
$str = 'amount='.$params["amount"].'&check_name='.$params["check_name"].'&desc='.$params["desc"].'&mch_appid='.$params["mch_appid"].'&mchid='.$params["mchid"].'&nonce_str='.$params["nonce_str"].'&openid='.$params["openid"].'&partner_trade_no='.$params["partner_trade_no"].'&spbill_create_ip='.$params['spbill_create_ip'].'&key='.$config['wechat']['key'];
//md5加密 转换成大写
$sign = strtoupper(md5($str));
//生成签名
$params['sign'] = $sign; //构造XML数据
$xmldata = $this->array_to_xml($params); //数组转XML
$url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //发送post请求
$res = $this->curl_post_ssl($url, $xmldata, $input['weixin_config_id']); //curl请求
if(!$res){
throw new \Exception("服务器连接失败");
} //付款结果分析
$content = $this->xml_to_array($res); //xml转数组
return $content;
} /**
* curl请求
**/
public function curl_post_ssl($url, $xmldata, $weixin_config_id,$second=30,$aHeader=[]){
$ch = curl_init();
//超时时间
curl_setopt($ch,CURLOPT_TIMEOUT,$second);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); //默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
//绝对地址可使用 dirname(__DIR__)打印,如果不是绝对地址会报 58 错误
curl_setopt($ch,CURLOPT_SSLCERT, resource_path().'/wechat/'.$weixin_config_id.'/apiclient_cert.pem');
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY,resource_path().'/wechat/'.$weixin_config_id.'/apiclient_key.pem');
if( count($aHeader) >= 1 ){
curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
}
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata);
$data = curl_exec($ch);
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
echo "call faild, errorCode:$error\n";
//die();
curl_close($ch);
return false;
}
} /**
* array 转 xml
* 用于生成签名
*/
public function array_to_xml($arr){
$str='<xml>';
foreach($arr as $k=>$v) {
$str.='<'.$k.'>'.$v.'</'.$k.'>';
}
$str.='</xml>';
return $str; } /**
* xml 转化为array
*/
public function xml_to_array($xml){
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$xmlString = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
$val = json_decode(json_encode($xmlString),true);
return $val;
}

财务审核,也就是微信返现到零钱,这个时候会返回成功结果,或者是各种不成功的结果

这里我用一个方法封装

//财务审核
if($param['status'] == 2){ //判断返现金额与修改后的金额
if($before_rebate_amount != $param['rebate_amount']){
//返现金额不相等,则出款金额改变
$out_amount = $param['rebate_amount'] - $before_rebate_amount ;
$this->outMount($business->business_id,$out_amount);
} if($param['rebate_status'] == 9){
//财务拒绝通过
$business->audit_status = $param['rebate_status'];
$business->rebate_amount = $param['rebate_amount'];
$business->status = 6;
$business->save(); //生成日志
$this->insertWithdrawLog($param['withdraw_id'], $business->status, $business->audit_status, $param['rebate_remark'], $param['admin_id']); }else{
//提现的各种返回结果
$this->payReturnResult($business,$param);
}
}
/**
* Function:微信提现返回的各种结果
* Author:cyw0413
* @param $res
* @param $business
* @param $param
*/
public function payReturnResult($business,$param)
{
$input = [
'weixin_config_id' => 20 ,
'openid' => $business->business->open_id,
'amount' => $param['rebate_amount'] * 100,
'trade_no' => $business->order_sn, //商户订单号
'desc' => "微信提现"
]; $pay = new PayLogBaseService();
$res = $pay->weixinPay($input); if($res['result_code']=="SUCCESS"){
//提现成功
$business->audit_status = 4;
$business->status = 4;
$business->rebate_amount = $param['rebate_amount'];
$param['rebate_remark'] = "已付款(".$param['rebate_amount'].")"; }elseif ($res['err_code'] == "MONEY_LIMIT"){
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,已达到付款给此用户额度上限";
//throw new \Exception($param['rebate_remark']); }elseif ($res['err_code'] == "AMOUNT_LIMIT"){
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,低于最低付款金额或者高于最高付款金额";
//throw new \Exception($param['rebate_remark']);
egdf
}elseif ($res['err_code'] == "NOTENOUGH"){
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,付款帐号余额不足或资金未到账";
//throw new \Exception($param['rebate_remark']); }elseif ($res['err_code'] == "SIGN_ERROR"){
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,签名错误"; }elseif ($res['err_code'] == "PARAM_ERROR"){
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,参数错误"; }elseif ($res['err_code'] == "OPENID_ERROR"){
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,Openid错误"; }elseif ($res['err_code'] == "FATAL_ERROR"){
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,两次请求参数不一致"; }elseif ($res['err_code'] == "CA_ERROR"){
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,商户API证书校验出错"; }elseif ($res['err_code'] == "V2_ACCOUNT_SIMPLE_BAN"){
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,无法给非实名用户付款"; }else{
$business->audit_status = 3;
$business->status = 3;
$param['rebate_remark'] = "提现失败,服务器繁忙,请稍后再试";
//throw new \Exception($param['rebate_remark']);
} $business->save(); }

当微信平台余额不足或者出现各种错误而提现失败的时候,这里还有支持重新付款的功能:其实就是点击按钮后重新调用付款到零钱的功能,知道成功付款

/**
* Function:重新付款
* Author:cyw0413
* @param $param
* @throws \Exception
*/
public function repay($param)
{
if(empty($param)){
throw new \Exception("参数错误");
} $business = GroupBusinessWithdrawBaseModel::find($param['withdraw_id']);
if(empty($business)){
throw new \Exception("不存在!");
} if($business->audit_status != 3){
throw new \Exception("状态有错误");
} //提现的各种返回结果
$this->payReturnResult($business,$param); }

PHP实现财务审核通过后返现金额到客户的更多相关文章

  1. 微信机器人 返现机器人 pc版本 移动版本 java开发 小范省钱

    微信机器人 返现机器人 pc版本 移动版本 java开发 小范省钱 微信搜索微信号 fanli-x 或 扫描下方二维码,可查看效果. 非web版微信,pc/移动版微信 支持新号24小时 不封号! 有任 ...

  2. SNF快速开发平台MVC-审核流,审核完成后会给下一个审核人发邮件,下一个审核人可以不登录系统,在邮件里进行审核处理

    审核流设计和使用参考以下资料: 审核流设计 http://www.cnblogs.com/spring_wang/p/4874531.html 审核流实例 http://www.cnblogs.com ...

  3. Oracle 函数 “把当前的用户(审核人,审核通过后)插入到数据表中”

    create or replace function mcode_apply_update_personnel(p_mca_no VARCHAR2, -- 参数(实参) p_action VARCHA ...

  4. 最新消息,CDRX7冰点价再返现,你知道么?

    一年一度的七夕又到来了,这不很多的单身狗朋友们都已经自备好了狗粮,准备在家里宅上一天呢? 开个玩笑今天小编就为各位带来了 一个劲爆大消息... Deng/deng/deng/deng..就是备受万众瞩 ...

  5. 22.一个球从100m高度自由下落,每次落地后返跳回原高度的一半,再反弹。求它在第10次落地时,共经过多少米,第10次反弹多高。

    #include <stdio.h> #include <stdlib.h> int main() { ,hn=sn/; int i; ;i<=;i++) //注意i是从 ...

  6. 进入做Mvc项目的时候 返现某个文件夹下面css js png等静态文件都访问不了

    原来是我在该文件夹下面添加了一个web.config 里面 静止了所有的文件 直接访问 <system.web>    <httpHandlers>      <add ...

  7. 服务器上装filezilla server后,本地的ftp客户端连接不上去

    公司一台服务器,上面装了filezilla server后,按平常配置好了,但是在本地用FTP客户端不管怎么连接都连接不上,本地FTP客户端总提示连接失败,远程filezilla server的界面也 ...

  8. 转一个财务方面常用到的数字金额转成汉字大写金额 php类

    系统里有牵扯到财务.合同等方面的处理时,常常需要把数字金额转成汉字大写金额(貌似这样正规),转一个转换的php class吧!<?php// 诸海加(ALPHA .z)// 2000-7-19 ...

  9. 安装 mysql 8.0后;root用户在客户端连接不上

    --- mysql workbench Failed to Connect to MySQL at 10.211.55.6:3306 with user root Authentication plu ...

随机推荐

  1. 理解 uptime 的:“平均负载”? 如何模拟测试

    每次发现系统变慢时,我们通常做的第一件事,就是执行 top 或者 uptime 命令,来了解系统的负载情况.比如像下面这样,我在命令行里输入了 uptime 命令,系统也随即给出了结果. [root@ ...

  2. python初级(302) 6 对象(一)

    作业: 1.编写一个Dog类,并生成对象dog,属性包含颜色,大小,重量,可以汪汪叫,摇尾巴,跑 # -*- coding: utf-8 -*- class Dog: def __init__(sel ...

  3. 隐马尔科夫模型的Python3实现代码

    下面给出计算隐马尔科夫模型的编程代码: from hmmlearn.hmm import GaussianHMM import datetime import numpy as np from mat ...

  4. 【Spring Cloud学习之二】服务注册和发现

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 Spring Cloud 1.2 一.EurekaEureka是Netflix开源的一个RESTful服务,主要用于服 ...

  5. cmake安装与使用

    CMake(cross platform make)是一个开源的跨平台工具系列,旨在构建,测试和打包软件. 使用指定名为CMakeLists.txt的配置文件可以控制软件的构建.测试和打包等流程. 通 ...

  6. Retrofit 二次封装实践

    首先感谢这位大神的博客:https://blog.csdn.net/u014569233/article/details/67639522,在他的基础上根据自己项目进行了修改最后成为现在项目使用的样子 ...

  7. 【常用技巧】标准模板库(STL)

    [常用技巧]标准模板库(STL) 在前几个章节中我们已经使用了诸如队列.堆.堆栈.vector 等标准模板库中的模板,切身感受到了它给我们带来的极大便利.在本节中,我们还要介绍两种标准模板——stri ...

  8. 删除lvm时出现"Logical volume contains a filesystem in use"

    问题描述: k8s环境中需要重新创建lvm:/dev/mapper/test-vg-test-storage,该lvm挂载在/data/prometheus下面,在删除出现"Logical ...

  9. LeetCode 5214. 最长定差子序列(Java)HashMap

    题目: 5214. 最长定差子序列 给你一个整数数组 arr 和一个整数 difference,请你找出 arr 中所有相邻元素之间的差等于给定 difference 的等差子序列,并返回其中最长的等 ...

  10. Java jms学习

    /** * <html> * <body> * <P> https://github.com/Jasonandy </p> * <p> Al ...