分享微信支付 JSAPI 开发中遇到的坑

发布于 2018-05-11 11:13:32 字数 3894 浏览 3195 评论 0

最近开发一个在线商城,其中接入了微信的公众号支付,根据开发文档提供的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

qq_Yqvrrd

文章 0 评论 0

2503248646

文章 0 评论 0

浮生未歇

文章 0 评论 0

养猫人

文章 0 评论 0

第七度阳光i

文章 0 评论 0

新雨望断虹

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文