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

发布于 2018-05-11 11:13:32 字数 3894 浏览 3206 评论 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

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

文章
评论
84963 人气
更多

推荐作者

夢野间

文章 0 评论 0

doggiejohn

文章 0 评论 0

就此别过

文章 0 评论 0

初见终念

文章 0 评论 0

qq_rvKjBH

文章 0 评论 0

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