微信公众号内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!" . "<br>");
} elseif ($this->parameters["body"] == null) {
throw new SDKRuntimeException("缺少统一支付接口必填参数body!" . "<br>");
} elseif ($this->parameters["total_fee"] == null) {
throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!" . "<br>");
} elseif ($this->parameters["notify_url"] == null) {
throw new SDKRuntimeException("缺少统一支付接口必填参数notify_url!" . "<br>");
} elseif ($this->parameters["trade_type"] == null) {
throw new SDKRuntimeException("缺少统一支付接口必填参数trade_type!" . "<br>");
} elseif ($this->parameters["trade_type"] == "JSAPI" &&
$this->parameters["openid"] == NULL
) {
throw new SDKRuntimeException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!" . "<br>");
}
/************************************服务商模式修改***********************************/
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)
// 微信支付调用方法
function weixinpayFun() {
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的支付参数的,这在独立商户模式下是没有问题的,并且是使用了很长一段时间。
改用服务商模式后,奇怪的问题就来了,每次请求从日志中看到统一下单是成功的,也就是说我的参数与签名也都是没有问题的,但是返回给我的错误见下图
从各方了解到,出现这个错误的原因是签名错误,于是我就各种各样的调整签名参数,把sub_appid ,appid 换来换去,或者一起结合起试,都不行。中间有咨询过微信支付的技术人员,对方也是帮忙分析了一下确认是签名错误,但根据他要求提供了相关参数检查后签名是正确的。最终也是没有完全搞定。
今天上午因为要处理另外一个问题,公众号从公众平台授权会引起独立商户支付出错,完全调不出支付界面,(因为之前我们都是让客户填写url,token appid,appsecret之类的参数的,现在改成了公众平台授权) 发现我们在一个初始的地方做了个JSSDK的初始化主要用于调用分享 ,见下面的代码
<script>
window.onload = function onload() {
jwx.initialize({
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" === typeof jwxCallback) {
jwxCallback();
}
});
};
</script>
由于是授权所以没有了appsecret这个参数,导致无法正常获取JSAPI初始化参数,经过一番代码修改,终于授权的公众号可以正常使用独立商户的微信支付了,改完突然想起,中间咨询微信支付的技术大神有提到过config文件中的nonceStr和timestamp,由此想到会不会是这个JSAPI初始参数用的appid与appsecret 用的是子商户的appid和appsecret引起的呢?把他换成服务商的试试呢,这一试可不就把问题给解决了.
3.总结
微信支付使用JSAPI发起支付时要注意: JSAPI初始化参数与调用统一下单时的参数(appid,appsecret)要一致,否则会出现莫名的签名错误
微信公众号内H5调用微信支付国内服务商模式的更多相关文章
- 免费微信公众号专用h5在线电影票API
免费h5在线电影票API,通过嵌套返回的h5页面url,实现电影票购买. 接口文档:https://www.juhe.cn/docs/api/id/252,通过此申请APPKEY 接口备注:通过请求返 ...
- 微信公众号、H5、APP三者各有什么优势?
昨天给大家分享了一个现在很热的H5,众所周知,当下H5手机网站.微信公众号.APP这三种载体都越来越火了,而且三者都有各自的一些优势和劣势. HTML5(H5) H5之所以能引发如此广泛的效应,根本在 ...
- [转]微信小程序、微信公众号、H5之间相互跳转
本文转自:https://www.cnblogs.com/colorful-paopao1/p/8608609.html 转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加 ...
- 微信小程序、微信公众号、H5之间相互跳转
转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息 ...
- 你所误解的微信公众号开发、以及微信公众号网页授权、接收url跳转参数等问题
前言:有一星期没跟新博客了,最近太忙.项目赶进度就没把时间花在博客上:今天来说说所谓的微信公众号开发和填坑记录: 微信公众号:运行在微信终端的应用 (对于开发者来说比较爽的你只需考虑兼容微信浏览器,因 ...
- Java开发微信公众号(五)---微信开发中如何获取access_token以及缓存access_token
获取access_token是微信api最重要的一个部分,因为调用其他api很多都需要用到access_token.比如自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等在请求的时候 ...
- Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装
在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...
- Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理
在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...
- 微信公众号内唤起h5支付详解
1.调用统一下单的接口URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder 2.调用统一下单必传参数: appid:需要进行支付功能的公众号的app ...
随机推荐
- 深入理解KMP算法之续篇
前言: 纠结于KMP已经两天了,相较于本人之前博客中提到的几篇博文,本人感觉这篇文章更清楚地说明了KMP算法的来龙去脉. http://www.cnblogs.com/goagent/archive/ ...
- Liferay 6.2 改造系列之七:关闭使用条款确认、密码提醒、新用户强制修改密码等功能
关闭使用条款确认: 在/portal-master/portal-impl/src/portal.properties配置文件中,有如下配置: # # Set this to true if all ...
- x264源代码 概述 框架分析 架构分析
函数背景色 函数在图中以方框的形式表现出来.不同的背景色标志了该函数不同的作用: 白色背景的函数:不加区分的普通内部函数. 浅红背景的函数:libx264类库的接口函数(API). 粉红色背景函数:滤 ...
- SpringHttpInvoker解析1-使用示例
HTTP invoker是一个新的远程调用模型,作为Spring框架的一部分,来执行基于HTTP的远程调用(让防火墙可以接受),并使用Java的序列化机制. 服务端 定义服务接口UserService ...
- 理解是最好的记忆方法 之 CSS中a链接的④个伪类为何有顺序
理解是最好的记忆方法 之 CSS中a链接的④个伪类为何有顺序 在CSS中,a标签有4种伪类,分别为: a:link, a:visited, a:hover, a:active 对其稍有了解的前端er都 ...
- TeeChart Pro 5.0
这是Delphi7自带例子 C:\Program Files\Borland\Delphi7\Demos\TeeChart 以下为翻译的文字,有部分不准确. TeeChart Pro 5.0是一个库 ...
- vsftpd 创建虚拟用户
1.添加一个宿主用户:useradd vsftpd -s /sbin/nologin2.安装db4-utils,通过本底数据文件实现虚拟用户访问yum install db4-utils3.创建ftp ...
- iOS 获取当前用户的用户路径并写入文件
NSString *path = [[@"~" stringByExpandingTildeInPath] stringByAppendingString: @"/tmp ...
- Mvc网站发布到IIS
网站发布步骤: 这部分是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因. 如有冒犯请联系本人,或删除,或标明出处. 因为好的文章,以前只想收藏,但连接 ...
- Python version 2.7 required, which was not found in the registry
http://blog.csdn.net/zdnlp/article/details/12171687