摘要:微信商户向个人退款转账零钱入账本屌一向抱着开源精神的态度,为大家分享文章和技巧,当然分享出来的代码都是可以直接。。。。
微信商户向个人退款(转账)---零钱入账
本屌一向抱着开源精神的态度,为大家分享文章和技巧,当然~分享出来的代码都是可以直接copy in。。。。望大家看完后点赞打赏收藏!谢谢~!如果有写的不对或者描述不正确的,欢迎大家给我留言指出错误,我将立即修改,以免误导大众!
此篇文章如题,实现商户向个人支付,零钱入账。下面我还是老规矩,一行代码一行注释,请大家注意看,在文章最后会附上完整代码!~定义函数,首先进行基本信息的定义
/** * 微信企业付款 * @param [type] $openid 商户appid下,某用户的openid * @param [type] $username 收款用户真实姓名。 * @param [type] $desc 企业付款操作说明信息。必填。 * @param [type] $money 企业付款金额,单位为分 * @author appyjj <--1121099600@qq.com--> */ function pay($openid="", $username="", $desc="", $money=0){ $apiUrl = $this->APPURL;//企业付款接口url $Parameters=array(); $Parameters["amount"] = $money;//企业付款金额,单位为分 $Parameters["check_name"] = "NO_CHECK";//NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功) $Parameters["desc"] = $desc;//企业付款操作说明信息。必填。 $Parameters["mch_appid"] = $this->APPID;//微信分配的公众账号ID $Parameters["mchid"] = $this->MCHID;//微信支付分配的商户号 $Parameters["nonce_str"] = $this->createNoncestr();//随机字符串,不长于32位 $Parameters["openid"] = $openid;//商户appid下,某用户的openid $Parameters["partner_trade_no"] = "saso".time().rand(10000, 99999);//商户订单号,需保持唯一性 $Parameters["re_user_name"] = $username;//收款用户真实姓名。 如果check_name设置为FORCE_CHECK或OPTION_CHECK,则必填用户真实姓名 $Parameters["spbill_create_ip"] = $_SERVER["SERVER_ADDR"];//调用接口的机器Ip地址 $Parameters["sign"] = $this->getSign($Parameters);//签名 $xml = $this->arrayToXml($Parameters); $res = $this->postXmlSSLCurl($xml,$apiUrl); $return = $this->xmlToArray($res); var_dump($return); //return $res; }
格式化参数,在签名过程中需要使用到
function formatBizQueryParaMap($paraMap, $urlencode) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if($urlencode) { $v = urlencode($v); } //$buff .= strtolower($k) . "=" . $v . "&"; $buff .= $k . "=" . $v . "&"; } $reqPar; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; }
此处代码很简单~不做过多注释。就一个排序、循环和字符串长度判断。
生成签名---这里很重要~撸主也弄了好一会~请大家务必认真看注释
function getSign($Obj) { foreach ($Obj as $k => $v) { $Parameters[$k] = $v; } //签名步骤一:按字典序排序参数 ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //echo "【string1】".$String.""; //签名步骤二:在string后加入KEY $String = $String."&key=1231231231234321abcdxingaaabb235";//此处请填写商户平台中的 API密钥 //echo "【string2】".$String.""; //签名步骤三:MD5加密 $String = md5($String); //echo "【string3】 ".$String.""; //签名步骤四:所有字符转为大写 $result_ = strtoupper($String); //echo "【result】 ".$result_.""; return $result_; }
排序的规则,没理解的请看这: ◆ 参数名ASCII码从小到大排序(字典序); ◆ 如果参数的值为空不参与签名; ◆ 参数名区分大小写; ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。 ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段 第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。 举例:
假设传送的参数如下:
appid: wxd930ea5d5a258f4f mch_id: 10000100 device_info: 1000 body: test nonce_str: ibuaiVcKdpRxkhJA 第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下: stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
第二步:拼接API密钥:
stringSignTemp="stringA&key=192006250b4c09247ec02edce69f6a2d" sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7"
最终得到最终发送的数据:
wxd930ea5d5a258f4f 10000100 1000 test ibuaiVcKdpRxkhJA 9A0A8659F005D6984697E2CA0A9CF3B7
**以上示例摘抄自微信支付官方文档**
产生随机字符串,长度不超过32位
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; }
太过简单,不做叙述!
数组转xml
function arrayToXml($arr) { $xml = ""; foreach ($arr as $key=>$val) { if (is_numeric($val)) { $xml.="<".$key.">".$val."".$key.">"; } else $xml.="<".$key.">".$key.">"; } $xml.=" "; return $xml; }
xml转数组
function xmlToArray($xml) { //将XML转为array $array_data = json_decode(json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA)), true); return $array_data; }
好的,下面是最后一步,请求
使用证书,以POST的方式提交xml到对应接口的URL
function postXmlSSLCurl($xml,$url,$second=30) { $ch = curl_init(); //超时时间 curl_setopt($ch,CURLOPT_TIMEOUT,$second); //这里设置代理,如果有的话 //curl_setopt($ch,CURLOPT_PROXY, "8.8.8.8"); //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE); //设置header curl_setopt($ch,CURLOPT_HEADER,FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE); //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLCERTTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLCERT, $this->SSLCERT_PATH); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLKEY, $this->SSLKEY_PATH); //post提交方式 curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "curl出错,错误码:$error"."
"; curl_close($ch); return false; } }
程序执行的时候往往没有一次性成功的~下面给大家附上返回的错误信息对照查询表
更详细的信息~请参考微信官方说明文档:[传送门][2]
下面是完整代码示例
直接copy后,修改一下参数既可以使用!
pay("这里填写收款人的openid", "姓名", "这里是描述(如果报utf8的错误,请把这里改为数字,此参数最好是传值过来)", 100); //最后这里的100为金额 (单位为分:即100 = 1元) class wxPay{ //=======【证书路径设置】===================================== //证书路径,注意应该填写绝对路径 protected $SSLCERT_PATH = "cert/apiclient_cert.pem";//请各位大爷自己修改一下路径 protected $SSLKEY_PATH = "cert/apiclient_key.pem";//请各位大爷自己修改一下路径 //=======【基本信息设置】===================================== //微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看 protected $APPID = "wx123123123123";//填写您的appid。微信公众平台里的 //受理商ID,身份标识 protected $MCHID = "123123123";//商户id //商户支付密钥Key。审核通过后,在微信发送的邮件中查看 protected $KEY = "192006250b4c09247ec02edce69f6a2d"; //JSAPI接口中获取openid,审核后在公众平台开启开发模式后可查看 protected $APPSECRET = "123123123123123123123123123123"; //JSAPI接口地址 protected $APPURL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; /** * 微信企业付款 * @param [type] $openid 商户appid下,某用户的openid * @param [type] $username 收款用户真实姓名。 * @param [type] $desc 企业付款操作说明信息。必填。 * @param [type] $money 企业付款金额,单位为分 * @author appyjj <--1121099600@qq.com--> */ function pay($openid="", $username="", $desc="", $money=0){ $apiUrl = $this->APPURL;//企业付款接口url $Parameters=array(); $Parameters["amount"] = $money;//企业付款金额,单位为分 $Parameters["check_name"] = "NO_CHECK";//NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功) $Parameters["desc"] = $desc;//企业付款操作说明信息。必填。 $Parameters["mch_appid"] = $this->APPID;//微信分配的公众账号ID $Parameters["mchid"] = $this->MCHID;//微信支付分配的商户号 $Parameters["nonce_str"] = $this->createNoncestr();//随机字符串,不长于32位 $Parameters["openid"] = $openid;//商户appid下,某用户的openid $Parameters["partner_trade_no"] = "saso".time().rand(10000, 99999);//商户订单号,需保持唯一性 $Parameters["re_user_name"] = $username;//收款用户真实姓名。 如果check_name设置为FORCE_CHECK或OPTION_CHECK,则必填用户真实姓名 $Parameters["spbill_create_ip"] = $_SERVER["SERVER_ADDR"];//调用接口的机器Ip地址 $Parameters["sign"] = $this->getSign($Parameters);//签名 $xml = $this->arrayToXml($Parameters); $res = $this->postXmlSSLCurl($xml,$apiUrl); $return = $this->xmlToArray($res); var_dump($return); //return $res; } /** * 作用:格式化参数,签名过程需要使用 */ function formatBizQueryParaMap($paraMap, $urlencode) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if($urlencode) { $v = urlencode($v); } //$buff .= strtolower($k) . "=" . $v . "&"; $buff .= $k . "=" . $v . "&"; } $reqPar; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; } /** * 作用:生成签名 */ function getSign($Obj) { foreach ($Obj as $k => $v) { $Parameters[$k] = $v; } //签名步骤一:按字典序排序参数 ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //echo "【string1】".$String.""; //签名步骤二:在string后加入KEY $String = $String."&key=guoyaojituanfengliaoxing82093235"; //echo "【string2】".$String.""; //签名步骤三:MD5加密 $String = md5($String); //echo "【string3】 ".$String.""; //签名步骤四:所有字符转为大写 $result_ = strtoupper($String); //echo "【result】 ".$result_.""; return $result_; } /** * 作用:产生随机字符串,不长于32位 */ 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; } /** * 作用:array转xml */ function arrayToXml($arr) { $xml = ""; foreach ($arr as $key=>$val) { if (is_numeric($val)) { $xml.="<".$key.">".$val."".$key.">"; } else $xml.="<".$key.">".$key.">"; } $xml.=" "; return $xml; } /** * 作用:将xml转为array */ function xmlToArray($xml) { //将XML转为array $array_data = json_decode(json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA)), true); return $array_data; } /** * 作用:使用证书,以post方式提交xml到对应的接口url */ function postXmlSSLCurl($xml,$url,$second=30) { $ch = curl_init(); //超时时间 curl_setopt($ch,CURLOPT_TIMEOUT,$second); //这里设置代理,如果有的话 //curl_setopt($ch,CURLOPT_PROXY, "8.8.8.8"); //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE); //设置header curl_setopt($ch,CURLOPT_HEADER,FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE); //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLCERTTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLCERT, $this->SSLCERT_PATH); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLKEY, $this->SSLKEY_PATH); //post提交方式 curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "curl出错,错误码:$error"."
"; curl_close($ch); return false; } } }
ok!此文半抄半写~总之代码没问题的~!分享创造动力,撸主继续干活了!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/22647.html
摘要:本文是浅析微信支付系列文章的第十二篇,主要讲解在商户存在的提现商户付款到微信用户零钱或者银行卡需求。应用场景微信支付已上线企业付款至银行卡功能。企业付款到银行卡发票与交易手续费发票为拆分单独开具。 本文是【浅析微信支付】系列文章的第十二篇,主要讲解在商户存在的提现、商户付款到微信用户零钱或者银行卡需求。 浅析微信支付系列已经更新十二篇了哟~,没有看过的朋友们可以看一下哦。 浅析微信支...
摘要:对于微信支付订单以及退款订单可以根据微信支付的流水号进行查询。 payment 项目2.0版本 微信并未提供一个统一的查询接口。对应每种查询均需要不同的api。为了便于大家在项目中使用,忽略细节。对以上三种进行了封装。通过工厂的方式降低调用成本。 $wxconfig = [ app_id => wxxxx, // 公众账号ID mch_id => xxx...
摘要:本文是浅析微信支付系列文章的第三篇,主要会讲一下在开发前的一些注意事项。浅析微信支付系列已经更新两篇了哟,没有看过的朋友们可以看一下。开通微信支付需要注册登陆微信商户平台,微信支付相关的信息都需要在这个平台上进行操作。 本文是【浅析微信支付】系列文章的第三篇,主要会讲一下在开发前的一些注意事项。 浅析微信支付系列已经更新两篇了哟~,没有看过的朋友们可以看一下。 浅析微信支付:前篇大纲...
阅读 3488·2021-11-18 10:07
阅读 1587·2021-11-04 16:08
阅读 1504·2021-11-02 14:43
阅读 1084·2021-10-09 09:59
阅读 840·2021-09-08 10:43
阅读 1076·2021-09-07 09:59
阅读 957·2019-12-27 11:56
阅读 996·2019-08-30 15:56