微信支付技术总结
微信支付开发文档:https://pay.weixin.qq.com/wiki/doc/api/index.html
微信支付代码示例:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1
微信支付的问题与解决
问题一:微信支付通知不成功,PHP 7不支持 HTTP_RAW_POST_DATA
问题描述:
PHP 从 5.x 版本升级到了 7.x 版本后,发现微信支付的通知接口无法接收通知消息
通过打印日志 error_log("msg xxx", 3, "log_file.log"); 查看调用,发现在微信支付的 WxPay.Api.php 文件中的函数 public static function notify($callback, &$msg) 有一个参数无法获取通知的数据:$xml = $GLOBALS['HTTP_RAW_POST_DATA'];
因为 PHP 7.x 版本后,已经不支持 $GLOBALS['HTTP_RAW_POST_DATA'],导致 $xml 返回的参数为空,无法处理返回的通知结果
解决方案:
使用 file_get_contents("php://input") 替代 $GLOBALS['HTTP_RAW_POST_DATA'],解决后的代码如下:
1)编辑微信支付文件
vim lib/WxPay.Api.php
2)修改后的代码如下
/** * * 支付结果通用通知 * @param function $callback * 直接回调函数使用方法: notify(you_function); * 回调类成员函数方法:notify(array($this, you_function)); * $callback 原型为:function function_name($data){} */ public static function notify($callback, &$msg) { //获取通知的数据 $xml = $GLOBALS['HTTP_RAW_POST_DATA']; // PHP 7 不再支持 HTTP_RAW_POST_DATA, 使用 file_get_contents 替代 if(empty($xml)) { $xml = file_get_contents("php://input"); // PHP 7以后,使用 file_get_contents 替代 HTTP_RAW_POST_DATA } // error_log(sprintf("[%s] - xml: %s", basename(__FILE__)." - ".__LINE__, $xml), 3, "wxpay-log.log"); //如果返回成功则验证签名 try { $result = WxPayResults::Init($xml); } catch (WxPayException $e){ $msg = $e->errorMessage(); return false; } return call_user_func($callback, $result); }
说明:
上面的代码涉及到了微信支付、小程序支付、app支付中,以前使用 HTTP_RAW_POST_DATA 来获取微信支付异步处理结果的,升级到 php 7.x 后一定要记得按照上面的方法改过来,否则支付功能使用不了,没法获取处理异步通知返回的数据。
问题二:微信退款请求不成功,报错 52 或 58
问题描述:
微信支付发起退款请求,发现没有成功,调试发现 WxPay.Api.php 文件中的函数 private static function postXmlCurl($xml, $url, $useCert = false, $second = 30) 中的 $error = curl_errno($ch); 报错状态为 52,PHP的curl请求执行不成功,进一步测试发现是 pem 授权文件使用了相对路径,没有使用绝对路径导致的签名错误,不过微信支付的提示也太low了,没有明确文字提示签名失败
解决方案:
1)在配置文件里,写入绝对路径
vim lib/WxPay.Config.php
const SSLCERT_PATH = '/../cert/apiclient_cert.pem'; const SSLKEY_PATH = '/../cert/apiclient_key.pem';
2)在退款调用文件里,写入绝对路径 dirname(__FILE__).xxx
vim lib/WxPay.Api.php
修改 private static function postXmlCurl($xml, $url, $useCert = false, $second = 30) 函数中的 pem 授权绝对路径
if($useCert == true){ //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT, dirname(__FILE__).WxPayConfig::SSLCERT_PATH); curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY, dirname(__FILE__).WxPayConfig::SSLKEY_PATH); }
pem 授权文件使用绝对路径后,退款问题解决
说明:微信支付的查询、退款都要用到签名,但是微信支付不用签名
参考推荐:
版权所有: 本文系米扑博客原创、转载、摘录,或修订后发表,最后更新于 2020-01-26 05:36:57
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!
转载注明: 微信支付技术总结 (米扑博客)