分享微信支付 JSAPI 开发中遇到的坑
最近开发一个在线商城,其中接入了微信的公众号支付,根据开发文档提供的 SDK 一步步的开发,遇到了不少的坑,这篇文章给大家分享下你也可能遇到这些坑。
订单号 transaction_id 和 out_trade_no
每个第三方在线支付系统中都会有至少两类订单号,其一为支付系统的订单号,我们称为 transaction_id,其二为商户平台的订单号,我们通常称为 out_trade_no,这两个号一般用来对账,在第三方支付平台你可以通过这两个订单号来查询订单的状态,而在商户自己的网站后台,也可以查询它的状态。
- transaction_id 由支付系统生成,并在回调时转回给商户
- out_trade_no 由商户平台生成,自己可以设计自己的规则
在是付费的时候,我们把 out_trade_no 传给第三方支付平台,在支付成功后,第三方会把 out_trade_no 传回来,我们通过 out_trade_no 进行商户系统的其它操作。
配置微信支付 SDK
微信支付提供了不同语言、不用平台开发的 SDK 开发包,PHP 语言的 SDK 下载地址:https://pay.weixin.qq.com/wiki/doc/api/download/WxpayAPI_php_v3.zip。我们将其下载下来解压到我们的项目中。
在 lib/WxPay.Config.php 配置我们商户和公众号信息:
const APPID = 'wx426b3015555a46be'; const MCHID = '1900009851'; const KEY = '8934e7d15453e97507ef794cf7b0519d'; const APPSECRET = '7813490da6f1265e4901ffb80afaa36f';
注意这个地方是使用 const 定义的一个常量,我刚开始是将商户信息保存在数据库中,这样方便切换支付的商户号和公众号,但是看到这样的定义就基本不可能了,const 规定后面跟的值也必须是常量。
这里配置完了,其他的不用修改,将其整个上传到服务器上测试支付,原以为可以完美的运行,但是还是遇到了下面的两个问题:
SSL 连接导致 curl 错误
Fatal error: Uncaught WxPayException: curl出错,错误码:60 in C:\xampp\htdocs\www\curtain\public\WxPay414\lib\WxPay.Api.php:564 Stack trace: #0 C:\xampp\htdocs\www\curtain\public\WxPay414\lib\WxPay.Api.php(62): WxPayApi::postXmlCurl('<xml><appid><![...', 'https: //api.mch...', false, 6) #1 C:\xampp\htdocs\www\curtain\public\WxPay414\Index.php(28): WxPayApi::unifiedOrder(Object(WxPayUnifiedOrder)) #2 {main} thrown in C:\xampp\htdocs\www\curtain\public\WxPay414\lib\WxPay.Api.php on line 564
看样子是 curl 请求地址的时候出错了,解决方法就是编辑 lib/WxPay.Api.php 文件第 537 行:
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
将最后一个参数都修改为 false:
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);//严格校验
超时问题
Fatal error: Uncaught WxPayException: 参数错误 in C:\xampp\htdocs\www\curtain\public\WxPay414\WxPay.JsApiPay.php:73 Stack trace: 0 C:\xampp\htdocs\www\curtain\public\WxPay414\Index.php(29): JsApiPay->GetJsApiParameters(Array) 1 {main} thrown in C:\xampp\htdocs\www\curtain\public\WxPay414\WxPay.JsApiPay.php on line 73
我们在 example/jsapi.php 的 29 行打印一下 $order 变量:
Array( [return_code] => FAIL [return_msg] => time_expire时间过短,刷卡至少1分钟,其他5分钟 )
这个错误是时间的问题,默认情况下 PHP 没有配置 date.timezone ,那么我们获取的时候是 0 时区的时间,和当前时间相差 8 小时,解决方法如下:
- 可以修改 php.ini 文件里的 date.timezone
- 在文件头加上 ini_set('date.timezone','Asia/Shanghai');
如果上面的修改后还是不行,就将 example/jsapi.php 第 31 行注释掉
//注释这行 $input->SetTime_expire(date("YmdHis", time() + 1800));
还遇到了一个未定义变量的警告:
Notice: Use of undefined constant CURLOP_TIMEOUT - assumed 'CURLOP_TIMEOUT
这个错误很好解决,直接将 $this->curl_timeout 修改为60 即可。
修改文件 example/WxPay.JsApiPay.php
位于 99 行
curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
修改为:
curl_setopt($ch, CURLOPT_TIMEOUT, 60); //为等待时间 甚至为 60 就是响应最迟是 60秒
回调地址 notify.php
示例目录里面为我们编写了一个回调地址的页面,在支付成功以后,微信支付会将支付的结果传送给这个页面,我们需要根据我们实际的支付环境,更新我们的订单状态。
刚开始我都不知道这个 notify.php 是怎么运行的,还要官方提供了 LOG 日志文件,查看日志文件可以得知,notify.php 里面的代码会在微信调用的时候自动运行,在第 22 行 if 函数判断返回的订单信息里面 return_code 和 result_code 参数是否为 SUCCESS,如果两个都是 SUCCESS 那么就是支付成功了。
接下来就是在这个 if 函数里面编写我们的后续操作了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论