laravel-wechat^7.1接入微信支付时的调试技巧和一个商户号的问题

542 阅读1分钟

laravel项目接微信支付,能看到的方案都是用easywechat的5.x版本以下,几乎找不到6.x的例子。6.x放弃了对微信官方的接口封装,提供了更好的灵活性,但是文档真的是少的可怜,主要靠领悟,不像之前版本那样直接调就行了。

官方的集成方法就不啰嗦了,肯定都会。

一开始按我理解写的

$app = app('easywechat.pay');
$data = [            "description" => "xiaobu123",            "out_trade_no" => "13323232323",            "notify_url" => $config['notify_url'],            "amount" => [                "total" => 100,                "currency" => "CNY",            ],            "payer" => [                "openid" => "oQA2M60SiO8nZFlx9iBscG9jcMmY",            ],        ];$resp = $api->withAppId()->withMchid()->postJson('/v3/pay/transactions/jsapi', $data);dd($resp->getContent()); // 真实发起请求

直接报400

Symfony\Component\HttpClient\Exception\ClientException: HTTP/1.1 400 Bad Request returned for "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi". in file /var/www/lnmp/www/rent/vendor/symfony/http-client/Response/CommonResponseTrait.php on line 165

除了400什么错也看不到,更别提官方的接口错误了。

搜了下微信支付官方的论坛,看有人提示说同样的参数用postman试下,发现果然,官方的接口你有问题不会简单给你报个400出来的。比如像这样

{    "code": "SIGN_ERROR",    "message": "Http头Authorization值格式错误,请参考《微信支付商户REST API签名规则》"}

反复看文档,检查参数,甚至去设置了jsapi的白名单目录(虽然我知道似乎没有必要,我之前只接过APP的微信支付,jsapi小程序支付还是第一次弄)

但始终只能看到返回400。

去翻symfony/http-client的源码,发现

public function getContent(bool $throw = true): string    {        if ($this->initializer) {            self::initialize($this);        }        if ($throw) {            $this->checkStatusCode();        }

getContent是可以接受一个是否抛出错误的参数,文档里也确实写了 

代码修改为

$content = $resp->getContent(false);dd($content);

再调,这次终于把微信官方的api返回报给我了。很奇葩的错误,文档里从来没提到过。

纯数字的商户号在json里需要被双引号包起来!

不然你将收到一个这样的错误

{    "code": "PARAM_ERROR",    "detail": {        "location": "body",        "value": 1659346105    },    "message": "无法将 JSON 输入源“/body/mchid”映射到目标字段“直连商户号”中,此字段需要一个 string 类型的 Json 值"}

不仅仅是微信接口需要注意,laravel-wechat的预置参数的传递也并不管用(查了composer.lock版本是6.8)

至此关键问题才算解决。

有效写法

$app = app('easywechat.pay');$api = $app->getClient();
$data = [            "appid" => "你的微信支付绑定的小程序appid",            "mchid" => "商户号",            "description" => "商品描述",            "out_trade_no" => "13323232323",            "notify_url" => $config['notify_url'],            "amount" => [                "total" => 100,                "currency" => "CNY",            ],            "payer" => [                "openid" => "oQA2M60**********jcMmY",            ],        ];$resp = $api->postJson('/v3/pay/transactions/jsapi', $data);        $statusCode = $resp->getStatusCode();$content = $resp->getContent(false);dd($content);

成功以后你讲得到

"{"prepay_id":"wx0614422741974651715****36a0ae50000"}"

敏感数据用****代替了。