tp5微信开发(五)--- tp5微信企业付款到零钱开发实践

项目需求:客户有一个分销项目,需要对分享获得的奖励直接发放至客户零钱钱包。

开发文档传送门:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1

企业付款到用户零钱开通条件:

  1、商户号(或同主体其他非服务商商户号)已入驻90日

  2、商户号(或同主体其他非服务商商户号)有30天连续正常交易

  3、 登录微信支付商户平台-产品中心,开通企业付款。

企业付款资金来源:

◆ 默认情况下,企业付款到零钱使用商户号基本户(或余额账户)余额。如商户号已开通运营账户,则企业付款到零钱使用运营账户内的资金。

◆ 基本户(或上述其他出款账户)的资金来源,可能是交易结算款项(仅基本户),或给账户充值的资金。当出款账户余额不足时,付款将因余额不足而付款失败。

项目准备:分销关系的建立不做说明,现在假设已建立上下级关系,下级支付后对用户进行佣金奖励。

代码实际上网上已经有很多版本demo,我选了一个并与其他版本进行比对,经过三个小时踩坑和各种调试,总结了一个可运行版本。

代码:

public function sendMoney($amount,$re_openid,$desc='推荐奖励',$check_name=''){
	$total_amount = (100) * $amount;
	$data=array(
        'mch_appid'=> '',//商户账号appid
        'mchid'=> '',//商户号
        'nonce_str'=> $this->createNoncestr(),//随机字符串
        'partner_trade_no'=> date('YmdHis').rand(1000, 9999),//商户订单号
        'openid'=> $re_openid,//用户openid
        'check_name'=>'NO_CHECK',//校验用户姓名选项,
        're_user_name'=> $check_name,//收款用户姓名
        'amount'=>$total_amount,//金额
        'desc'=> $desc,//企业付款描述信息
        'spbill_create_ip'=> '',//Ip地址
    );
    $secrect_key = '';//API密码
    $data = array_filter($data);
    ksort($data);
    $str ='';
    foreach($data as $k=>$v) {
       $str.=$k.'='.$v.'&';
    }
    $str.='key='.$secrect_key;
    $data['sign'] = md5($str);
    $xml = $this->arraytoxml($data);
    $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //调用接口
    $res = $this->wx_curl($xml,$url);
    $return = $this->xmltoarray($res);
	
	$responseObj = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
	echo $res= $responseObj->return_code;  //SUCCESS  如果返回来SUCCESS,则发生成功,处理自己的逻辑
	
	return $res;
}

public function createNoncestr($length =32){
	$chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
	$str ="";
	for ( $i = 0; $i < $length; $i++ )  {  
		$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
	}  
	return $str;
}

public function arraytoxml($data){
	$str='<xml>';
	foreach($data as $k=>$v) {
		$str.='<'.$k.'>'.$v.'</'.$k.'>';
	}
	$str.='</xml>';
	return $str;
}

public function xmltoarray($xml) { 
	//禁止引用外部xml实体 
	libxml_disable_entity_loader(true); 
	$xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); 
	$val = json_decode(json_encode($xmlstring),true); 
	return $val;
} 
 
public function wx_curl($vars,$url,$second = 30, $aHeader = array()) {
	$isdir = ROOT_PATH."cert/";//证书位置
    $ch = curl_init();//初始化curl
    curl_setopt($ch, CURLOPT_TIMEOUT, $second);//设置执行最长秒数
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
    curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);// 终止从服务端进行验证
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//
    curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//证书类型
    curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//证书位置
    curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中规定的私钥的加密类型
    curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//证书位置
    if (count($aHeader) >= 1) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);//设置头部
    }
    curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
    curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);//全部数据使用HTTP协议中的"POST"操作来发送

    $data = curl_exec($ch);//执行回话
    if ($data) {
        curl_close($ch);
        return $data;
    } else {
        $error = curl_errno($ch);
        echo "call faild, errorCode:$error\n";
        curl_close($ch);
        return false;
    }
}

测试方法:新建一个check方法,通过访问域名/index/base/send_check 进行测试:

备注说明:第一个参数是付款金额,第二个参数是收款openid,这个我本身已经存的有所以直接从数据库粘贴过来的。

public function send_check(){
	$this->sendMoney(1,'olrMRuIULa1k_GKC7XwLWPlH0IA8','哎咖啡付款到零钱测试');
}

划重点:

1,付款到零钱需要用到证书,现在微信已经在推行新的api证书,新版证书生成说明传送门:https://kf.qq.com/faq/180824BrQnQB180824m6v2yA.html 操作不难,按照指引,就两个复制粘贴的事,最终点击生成会自动下载一个证书压缩包。

我们是php的,所以用得到下面两个证书文件,在tp5项目根目录下创建 cert 文件夹,并上传两个证书文件【我看有的网友总结说,证书必须要放到根目录而且必须是cert命名,这个我没有求证,不知道是否是强制要求,不过我是的确是这么做的】。

2,在测试过程中,总会踩各种各样的坑,我把我大概的调试过程中遇到的错误进行说明:

   1),打印curl 返回错误 int(58),查询 curl 对应返回码得知是证书问题,我能确定我证书是最新生成的,所以证书是没问题,查文档要求证书文件必须是绝对路径,改之,成功。对于证书文件路径,可在curl请求中打印具体路径值,确保是绝对路径。

  2),提示签名错误,核验方法:一再需要确认商户号,appid以及支付秘钥是否正确,我当时没留意,就这个问题查了一个小时,结果发现是商户号写的是之前测试对应的账户,结果一直都验签不成功,WTF!

  3),支付提示账户余额不足,查客户的基本账户,交易类型设置的是T+1的,可能是这个原因,导致商户收到的钱都直接转到客户指定的银行账号了,点击交易中心->充值->选择银行,充值了测试金,返回继续访问路由,OK,成功。

最终效果:

 

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值