php微信服务商h5支付,微信公众号内H5调用微信支付国内服务商模式

最近在折微信公众号内H5用JSAPI调用微信支付,境内服务商版支付,微信支付给出的官方文档以及SDK不够详细,导至我们走了一些弯路,把他分享出来,我这边主要是用PHP开发,所以未加说的话示例都是PHP代码

微信的官方文档  https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=7_1

1.服务商模式下调用统一下单

独立商户模式统一下单:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

服务商模式下统一下单:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_1

统一下单与与独立商户模式之间有一点点修改,两个参数,sub_mch_id,sub_appid,原来的openid 参数改为sub_openid

**

* 文件:WxPayPubHelper.php

* 统一支付接口类

* Class UnifiedOrder_pub

*/

class UnifiedOrder_pub extends Wxpay_client_pub

{

public function __construct()

{

//设置接口链接

$this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

//设置curl超时时间

$this->curl_timeout = WxPayConf_pub::getParams('curl_timeout');

}

/**

* 生成接口参数xml

* @return string|void

*/

public function createXml()

{

try {

//检测必填参数

if ($this->parameters["out_trade_no"] == null) {

throw new SDKRuntimeException("缺少统一支付接口必填参数out_trade_no!" . "
");

} elseif ($this->parameters["body"] == null) {

throw new SDKRuntimeException("缺少统一支付接口必填参数body!" . "
");

} elseif ($this->parameters["total_fee"] == null) {

throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!" . "
");

} elseif ($this->parameters["notify_url"] == null) {

throw new SDKRuntimeException("缺少统一支付接口必填参数notify_url!" . "
");

} elseif ($this->parameters["trade_type"] == null) {

throw new SDKRuntimeException("缺少统一支付接口必填参数trade_type!" . "
");

} elseif ($this->parameters["trade_type"] == "JSAPI" &&

$this->parameters["openid"] == NULL

) {

throw new SDKRuntimeException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!" . "
");

}

/************************************服务商模式修改***********************************/

if(WxPayConf_pub::getParams('sub_mchid')){ //服务商模式

$this->parameters["sub_mch_id"] = WxPayConf_pub::getParams('sub_mchid');

$this->parameters["sub_appid"] = WxPayConf_pub::getParams('sub_appid');

$this->parameters["sub_openid"] = $this->parameters["openid"];

unset($this->parameters["openid"]);//去掉原来的openid

}

/************************************服务商模式修改结束***********************************/

$this->parameters["appid"] = WxPayConf_pub::getParams('appid');//公众账号ID

$this->parameters["mch_id"] = WxPayConf_pub::getParams('mchid');//商户号

$this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//终端ip

$this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串

$this->parameters["sign"] = $this->getSign($this->parameters);//签名

return $this->arrayToXml($this->parameters);

} catch (SDKRuntimeException $e) {

die($e->errorMessage());

}

}

2.服务商模式下JSAPI调用微信支付

官方给出H5调用API支付文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=7_7&index=6

而我们之前一直立商户模式,用的是JSSDK :https://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

调试统一下单时还算比较顺利,因为获取prepay_id不成功无非就是参数的问题,并且返回给我们的错误也非常详细,可以很快定位问题。可是这个JSAPI可就把我弄惨了,先看代码(javascript)

//微信支付调用方法

functionweixinpayFun() {

var buildformUrl = 'http://local.test/pay/getparams?orderid=订单号';//获取微信支付相关参数

$.post(buildformUrl, {},function(res) {

$.hideLoading();if(res.status) {var wxpayParam =res.data;//发起一个支付请求

wx.chooseWXPay({

timestamp: wxpayParam.timeStamp,

nonceStr: wxpayParam.nonceStr,

package: wxpayParam.package,

signType: wxpayParam.signType,

paySign: wxpayParam.paySign,

trigger:function(res) {

},

complete:function(res) {

},

success:function(res) {

$.alert('支付成功');},

cancel:function(res) {

$.alert('支付已取消');

},

fail:function(res) {

alert(JSON.stringify(res));

$.alert('支付失败');

}

});

}else{

$.alert('微信支付失败!');

}

},'json');

}

由这段代码可以看到,我们是通过Ajax方式调用微信支付统一下单并获取到JSAPI的支付参数的,这在独立商户模式下是没有问题的,并且是使用了很长一段时间。

改用服务商模式后,奇怪的问题就来了,每次请求从日志中看到统一下单是成功的,也就是说我的参数与签名也都是没有问题的,但是返回给我的错误见下图

10b834911a5cca7384228d4184713a6c.png

从各方了解到,出现这个错误的原因是签名错误,于是我就各种各样的调整签名参数,把sub_appid ,appid 换来换去,或者一起结合起试,都不行。中间有咨询过微信支付的技术人员,对方也是帮忙分析了一下确认是签名错误,但根据他要求提供了相关参数检查后签名是正确的。最终也是没有完全搞定。

今天上午因为要处理另外一个问题,公众号从公众平台授权会引起独立商户支付出错,完全调不出支付界面,(因为之前我们都是让客户填写url,token appid,appsecret之类的参数的,现在改成了公众平台授权) 发现我们在一个初始的地方做了个JSSDK的初始化主要用于调用分享 ,见下面的代码

appId:'{$sys_params.jsapi_param.appId}',

timestamp:'{$sys_params.jsapi_param.timestamp}',

nonceStr:'{$sys_params.jsapi_param.nonceStr}',

signature:'{$sys_params.jsapi_param.signature}'},function() {

jwx.setShareData({

title:'分享标题',

desc:'描述',

link: "分享的链接",

imgUrl:'分享显示的图片'});if ("function" === typeofjwxCallback) {

jwxCallback();

}

});

};

由于是授权所以没有了appsecret这个参数,导致无法正常获取JSAPI初始化参数,经过一番代码修改,终于授权的公众号可以正常使用独立商户的微信支付了,改完突然想起,中间咨询微信支付的技术大神有提到过config文件中的nonceStr和timestamp,由此想到会不会是这个JSAPI初始参数用的appid与appsecret 用的是子商户的appid和appsecret引起的呢?把他换成服务商的试试呢,这一试可不就把问题给解决了.

3.总结

微信支付使用JSAPI发起支付时要注意: JSAPI初始化参数与调用统一下单时的参数(appid,appsecret)要一致,否则会出现莫名的签名错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值