提早说一个重要的坑,不注意掉进去,会浪费一些时间。
php
直接上代码 提现类 并无作验证明现了功能 代码后面有详细的流程介绍!!
算法
<?php /* 微信企业 支付到我的 */ class cash { /** * array转xml */ public function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key => $val)
{ if (is_numeric($val))
{ $xml .= "<".$key.">".$val."</".$key.">"; }else{ $xml .= "<".$key."><![CDATA[".$val."]]></".$key.">"; }
} $xml .= "</xml>"; return $xml; } //使用证书,以post方式提交xml到对应的接口url /** * 做用:使用证书,以post方式提交xml到对应的接口url */ function curl_post_ssl($url, $vars, $second=30) { $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); //如下两种方式需选择一种 /******* 此处必须为文件服务器根目录绝对路径 不可以使用变量代替*********/ curl_setopt($ch,CURLOPT_SSLCERT,"/home/lizi/addons/grow/template/mobile/cash/apiclient_cert.pem"); curl_setopt($ch,CURLOPT_SSLKEY,"/home/lizi/addons/grow/template/mobile/cash/apiclient_key.pem"); curl_setopt($ch,CURLOPT_POST, 1); curl_setopt($ch,CURLOPT_POSTFIELDS,$vars); $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; }
} //企业向我的付款 public function payToUser($openid='oJZJ0w_N_LlTo4AHLnN-cGGtJSeM',$desc='提现成功',$amount='102') { //微信付款到我的的接口 $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; $params["mch_appid"] = ''; //公众帐号appid $params["mchid"] = ''; //商户号 微信支付平台帐号 $params["nonce_str"] = 'longdongzhiye99'.mt_rand(100,999); //随机字符串 $params["partner_trade_no"] = mt_rand(10000000,99999999); //商户订单号 $params["amount"] = $amount; //金额 $params["desc"] = $desc; //企业付款描述 $params["openid"] = $openid; //用户openid $params["check_name"] = 'NO_CHECK'; //不检验用户姓名 $params['spbill_create_ip'] = '123.56.48.18'; //获取IP //生成签名(签名算法后面详细介绍) $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=F5YguNW77Ao4N5yu5wZ8Lb00NKOg1Y04'; //md5加密 转换成大写 $sign = strtoupper(md5($str)); $params["sign"] = $sign;//签名 $xml = $this->arrayToXml($params); return $this->curl_post_ssl($url, $xml); } } /* $cash = new cash; $res = $cash -> payToUser(); var_dump($res); */
字段名 | 变量名 | 必填 | 示例值 | 类型 | 描述 | |
---|---|---|---|---|---|---|
公众帐号appid | mch_appid | 是 | wx8888888888888888 | String | 公众号的appId | |
商户号 | mchid | 是 | 1900000109 | String(32) | 微信支付平台商户号 就是平台帐号 |
|
随机字符串 | nonce_str | 是 | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | String(32) | 随机字符串,随便随机个什么<32位 | |
商户订单号 | partner_trade_no | 是 | 10000098201411111234567890 | String | 订单号,保持惟一性,自定义一个随机订单号 | |
用户 openid |
openid | 是 | oxTWIuGaIt6gTKsQRLau2M0yL16E | String | 商户appid下,某用户的openid | |
校验用户姓名选项 | check_name | 是 | NO_CHECK 不检验 (小额推荐) FORCE_CHEC 强制检验 OPTION_CHECK 自动检验 |
String | NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,没法转帐) OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,能够转帐成功) |
|
收款用户姓名 | re_user_name | 可选 | 马花花 (若是上一个参数为强制检验此为必填项) |
String | 收款用户真实姓名。 若是check_name设置为FORCE_CHECK或OPTION_CHECK,则必填用户真实姓名 |
|
金额 | amount | 是 | 100 单位为分 100就是100分. |
int | 企业付款金额,单位为分 | |
企业付款描述信息 | desc | 是 | 奖金啊,提现成功啊 退款成功啊什么的 |
String | 企业付款操做说明信息。必填。 | |
Ip地址 | spbill_create_ip | 是 | 192.168.0.1 | String(32) | 调用接口的机器Ip地址服务器ip | |
支付密钥
|
key
|
是
|
F5YguNW77Ao4N5yu5wZ8Lb00NKO987ks
|
String(32) |
设置在商户平台上的支付密钥 | |
签名
|
sign |
|
C380BEC2BFD727A4B6845133519F3AD6 |
String(32) |
这个恶心了 下面单独解释 |
而后咱们就要将这些参数填充到xml格式的字符串中去了api
官方示例为数组
<xml> <mch_appid>wxe062425f740c30d8</mch_appid> <mchid>10000098</mchid> <nonce_str>3PG2J4ILTKCH16CQ2502SI8ZNMTM67VS</nonce_str> <partner_trade_no>100000982014120919616</partner_trade_no> <openid>ohO4Gt7wVPxIT1A9GjFaMYMiZY1s</openid> <check_name>OPTION_CHECK</check_name> <re_user_name>张三</re_user_name> <amount>100</amount> <desc>节日快乐!</desc> <spbill_create_ip>10.2.3.10</spbill_create_ip> <sign>C97BDBACF37622775366F38B629F45E3</sign> </xml>
我我的仍是觉的将参数都存到数组里,而后遍历拼接出来比较好例如:
服务器
$params["mch_appid"] = ''; //公众帐号appid $params["mchid"] = ''; //商户号 微信支付平台帐号 $params["nonce_str"] = 'longdongzhiye99'.mt_rand(100,999); //随机字符串 $params["partner_trade_no"] = mt_rand(10000000,99999999); //商户订单号 $params["amount"] = $amount; //金额 $params["desc"] = $desc; //企业付款描述 $params["openid"] = $openid; //用户openid $params["check_name"] = 'NO_CHECK'; //不检验用户姓名 $params['spbill_create_ip'] = '123.56.48.18'; //获取IP //生成签名(签名算法后面详细介绍) $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=F5YguNW77Ao4N5yu5wZ8Lb00NKOg1Y04'; //md5加密 转换成大写 $sign = strtoupper(md5($str)); $params["sign"] = $sign;//签名
而后拼接微信
$xml = "<xml>"; foreach ($paramsas $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; } else{ $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"; } $xml .= "</xml>";
获得$xml。app
到此字符传参数部分完成了,而后还没完呢!还有证书部分/** * 做用:使用证书,以post方式提交xml到对应的接口url */ function curl_post_ssl($url, $xml, $second=30) { $ch = curl_init(); //超时时间 curl_setopt($ch,CURLOPT_TIMEOUT,$second); //将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。 curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_URL,$url); //根据curl版本有不一样默认值 设置一下放心 curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); //如下两种方式需选择一种 双向检测证书 /******* 此处必须为文件服务器根目录绝对路径 不可以使用变量代替*********/ curl_setopt($ch,CURLOPT_SSLCERT,"/home/lizi/addons/grow/template/mobile/cash/apiclient_cert.pem"); curl_setopt($ch,CURLOPT_SSLKEY,"/home/lizi/addons/grow/template/mobile/cash/apiclient_key.pem"); curl_setopt($ch,CURLOPT_POST, 1); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); $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; } }
贴出成功以后返回码
<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[]]></return_msg> <mch_appid><![CDATA[wxec38b8ff840bd989]]></mch_appid> <mchid><![CDATA[10013274]]></mchid> <device_info><![CDATA[]]></device_info> <nonce_str><![CDATA[lxuDzMnRjpcXzxLx0q]]></nonce_str> <result_code><![CDATA[SUCCESS]]></result_code> <partner_trade_no><![CDATA[10013574201505191526582441]]></partner_trade_no> <payment_no><![CDATA[1000018301201505190181489473]]></payment_no> <payment_time><![CDATA[2015-05-19 15:26:59]]></payment_time> </xml>
失败的返回码会提示错误信息 就不作介绍了。curl