您当前的位置:首页 > 建站知识 > 编程知识

微信支付退款--原生PHP实现代码

发布时间: 2019-05-15 │ 浏览:3619 

微信支付官方有demo下载,试了一下发现返回一对花括号{},无值难以找原因啊。无奈只好看官方接口文档,过程并不顺利,所以要记录一下:

先看官方文档(https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4),这步可多花些时间,只有看透了在后面写代码时要是碰到问题才不会乱。看后发现有三个重点:签名生成算法,用POST提交xml数据,带证书。

从接口参数表里取出必填字段,其它字段先不取,字段越少,出错的机会越少,我们先要测通。然后以【键值对】按字母升序排序,加上key,之后MD5,最后转成大写。你会发现这几步不难,只要仔细按步就搬即可。

提交xml数据,php有curl可实现,这个心中有数了。

证书从哪来呢,在http://pay.weixin.qq.com/扫码登录,在顶部导航菜单里找到【账户中心】


点击后,左侧导航菜单中会出现【API安全】:

在这里可下载证书,最终得到如下文件:

PHP要的是apiclient_cert.pem和apiclient_key.pem,把这两个文件上传到服务器某目录下,等会要用。

做好了上面的准备工作,下面看实现代码就好理解了:


$appid='wx1234567890'; //这是公众号的appid
$mch_id='1500000000'; //商户号(登录 pay.weixin.qq.com,在【产品中心】-【开发配置】里会看到)
$nonce_str='abcdddddddddddd';//随机字符串,随便一串字母即可
$out_refund_no='r'.time(); //退款单号,不重复即可
$total_fee=1000; //原订单金额,单位不是元,而是分
$refund_fee=200; //退款金额,单位是分,<=$total_fee
$transaction_id="4200000299201905147901111111";//原微信支付交易号
$key="abcde12345";//在pay.weixin.qq.com里设定的密钥

//拼接字段
$stringA='appid='.$appid.'&mch_id='.$mch_id.'&nonce_str='.$nonce_str.'&out_refund_no='.$out_refund_no.'&refund_fee='.$refund_fee.'&total_fee='.$total_fee.'&transaction_id='.$transaction_id;
//加上key
$stringSignTemp=$stringA."&key=".$key;
//MD5
$signValue=MD5($stringSignTemp);
//转大写
$sign=strtoupper($signValue);

$data="xml字符串";//xml格式在html里显示不出,请看最后附图
//var_dump($data);
$url="https://api.mch.weixin.qq.com/secapi/pay/refund";

$ch = curl_init();
//超时时间
curl_setopt($ch,CURLOPT_TIMEOUT,30);
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);
//设置证书
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, 'D:/cert/apiclient_cert.pem'); //证书在服务器上的绝对路径
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY,'D:/cert/apiclient_key.pem'); //证书在服务器上的绝对路径
//post提交方式
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$res = curl_exec($ch);
curl_close($ch);
var_dump($res);