开发微信JSAPI付出过程中,遇到一些问题小结
前语,可能对于小白或者第一次触摸微信付出的JY有帮助。以下内容中遇到的问题都是以v2版别的基础上开发的。
V2和V3版别
微信付出全体上是分为V2和V3版别的,看事务需求,自主选择适宜的。大致上V2是传输的数据格局是XML的,V3传输的数据格局JSON的。V3版别再装备时,有必要带上商户证书。详细操作过程能够检查 什么是商户API证书?怎么获取商户API证书?
统一下单接口V2: api.mch.weixin.qq.com/pay/unified…
统一下单接口V3: api.mch.weixin.qq.com/v3/pay/tran…
V2版别官方文档
V3版别官方文档
详细V2与V3的其他区别 ,能够检查 V2与V3的不同
无法将输入源“/body/xml/total_fee”映射到目标字段“标价金额”中?
呈现这个问题的原因是 total_fee类型是int,单位为分,检查一下你的传参。
意思便是你传的数,不能是小数,是整数,这个整数的单位便是分,比方,你想支出0,01元,参数便是1。
微信付出提示 调用付出JSAPI短少参数:appId,timeStamp
能够从三方面去排查一下:
1:装备授权目录了
2:前端搭档确认json不是字符串转成object了
3:appId也传了的
timeStamp 这个缺失的参数,只在苹果手机上呈现,安卓手机上没有呈现,我要着重说一下。
$.ajax({
url:"{:url('wap/order/commit')}",
data:{ // 参数依据接口需求自行替换
goods_id:goods_id,
products_id:products_id,
goods_num:goods_num,
name:name,
phone:phone,
message:message
},
type:'post',
success:function (res){
if (res.code===0){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":res.data.appId, //大众号ID
"timeStamp":(res.data.timeStamp).toString(), //时刻戳,这儿时刻戳转化为字符串格局,不然IOS调用会提示短少参数timeStamp,并且此处的时刻戳有必要和生成微信预付出订单运用的时刻戳保持共同
"nonceStr":res.data.nonceStr, //随机串,随机串有必要和生成微信预付出订单运用的随机串保持共同
"package":res.data.package, // 生成微信预付出订单回来的prepay_id,格局为:'prepay_id=微信回来的prepay_id'
"signType":res.data.signType, //微信签名方式:默认MD5
"paySign":res.data.sign //微信签名
},
function(wx_res){
if(wx_res.err_msg == "get_brand_wcpay_request:ok" ){
// 循环查询订单是否付出成功
timer = self.setInterval("checkOrderStatus("+ res.data.order_number +")",1000)
}else{
layer.open({content: '付出失利',skin: 'msg',time: 2}); //提示内容,依据自己项目自行替换功用提示框函数
}
});
}else{
layer.open({content: '下单失利',skin: 'msg',time: 2}); //提示内容,依据自己项目自行替换功用提示框函数
}
}
})
微信付出接口报【签名过错】
我是在二次签名(客户端签名过错)的过程中,参数有误,导致的过错,检查全网最全v2接口签名报错排查指引!!!!这篇文章,才有思路排查出过错。第一次签名(服务端签名正常经过),在第一次签名校验东西验证经过的情况下。我还认为第2次签名也是正常的,就没有往签名东西(网上找的)上想,其实是错的,坑死我了。两次签名最好拿校验东西都验证一下,并且签名的时分,参数大小写看好,顺序也要留意,以及再拼接上key。 微信签名校验东西
签名东西类:
/**
* 生成微信付出签名
*
* @param params 参数调集,需求包含 appid、mch_id、nonce_str、sign_type 和 key 等参数
* @param signType 签名类型,如 "MD5" 或 "HMAC-SHA256"
* @param key 商户密钥(API 密钥)
* @return 生成的签名字符串
*/
public static String generateSignature(Map<String, Object> params, String signType, String key) {
SortedMap<String, Object> sortedMap = new TreeMap<>(params);
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, Object> entry : sortedMap.entrySet()) {
String k = entry.getKey();
Object v = entry.getValue();
// 排除空值和签名参数
if (v != null && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k).append("=").append(v).append("&");
}
}
sb.append("key=").append(key);
String signTemp = sb.toString();
String sign = "";
try {
MessageDigest md = MessageDigest.getInstance(signType);
byte[] bytes = md.digest(signTemp.getBytes());
sign = byteArrayToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
// 处理异常
e.printStackTrace();
}
return sign.toUpperCase();
}
private static String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
sb.append("0");
}
sb.append(hex);
}
return sb.toString();
}
没有排查思路的话,也能够检查 微信付出接口报【签名过错】,看这一篇就够了
关于统一下单那个接口spbill_create_ip这个参数
微信官网上说终端用户ip,我看客服解释说是服务器ip 。我自己的系统是在内网布置,还有域名用的阿里云的,还有一个公网的ip。
- 内网服务器 IP:假如你的服务器布置在内网环境中,并且该服务器能够直接与微信付出接口进行通信,则能够将内网服务器的 IP 地址作为
spbill_create_ip
。 - 域名服务器 IP:假如你运用了域名解析或者 CDN(内容分发网络)等服务,并且用户拜访你的网站时会经过域名服务器,则能够将域名服务器的 IP 地址作为
spbill_create_ip
。 - 公网 IP:假如你的服务器直接连接到公网,并且用户拜访你的网站时能够直接获取到公网 IP 地址,则能够将公网 IP 作为
spbill_create_ip
我感觉是这个三个ip 都能够,我再排查签名过错的时分,都试过,第一次签名都能够回来正常的状况。
微信网页授权怎么传递多个参数?redirect_uri怎么包含参数
例如 咱们在授权时的redirect_uri为www.baidu.com?a=123&b=678 ,需求传入a 和 b的参数
能够经过重定向的地址redirect_uri运用encodeURIComponent办法来进行编码,让浏览器认为redirect_uri是一个参数而不是地址符号。
let local ="http://www.baidu.com?a=123&b=678";
window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=*&redirect_uri="+encodeURIComponent(local)+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
redirect_uri 域名与后台装备不共同 10003(填坑解决方案
前端 获取openid 的办法
详细能够参阅如下文章:
前端 获取openid 的办法
大众号付出报错:“当前页面的URL未注册”
用户实践的付出目录有必要和在微信付出商户渠道设置的共同,不然会报错”当前页面的URL未注册:”
留意 1.4中说的,付出授权目录校验规则说明中的第二点,便是你付出授权的目录是什么页面便是什么,比方你页面是form 页面,到大众号里有必要 from/ 才干装备成功,装备上又无法拜访这个页面。
所以直接装备顶级域名就能够了。
微信付出成功后,重复回调
第一,接受回调信息后,需求再回来 以下信息
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
</xml>
第二,留意格局 有必要是xml,不然,还会一向回调,response.setContentType(“text/xml”);
/**
* 付出接口回调
*/
@PostMapping(value = "wxCallback")
@ResponseBody
public String H5wxCallback(HttpServletRequest request, HttpServletResponse response) {
InputStream is = null;
String xmlBack = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml> ";
try {
is = request.getInputStream();
// 将InputStream转换成String
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
response.setContentType("text/xml");
xmlBack = weChatService.notify(sb.toString());
} catch (Exception e) {
System.out.println("微信付出回调通知失利:" + e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return xmlBack;
}
最后
提供一下,查找排查文章的思路,网上搜了很多,看了许多排查相同问题的文章,质量真实不敢恭维,详细咱们直接在微信付出客服哪里查找高质量的答案。