最近负责微信支付 全栈的开发,有些要点和坑在此做个笔记。
一. java后端
1. 在使用WxPay的SDK时对请求参数进行封装,发现签名失败,后来发现nonce_str随机字符串不需要传递,在SDK里面已经封装好了。
2.timestamp这个时间戳的参数注意,在ios端只支持10位的时间戳,所以统一用10位时间戳来兼容ios
r.put("timestamp", System.currentTimeMillis() / 1000 + "");
3.当支付类型是APP时,特别需要注意文档的一段话:(
先调用【统一下单API】生成预付单,获取到 prepay_id 后将参数再次签名传输给APP发起支付
)
//r为统一下单返回的map
if ("APP".equals(arg.get("trade_type").toString())) {
Map<String, String> signMap = new HashMap<>();
signMap.put("appid", WXPayConfigImpl.getInstance().getAppID());
signMap.put("partnerid", WXPayConfigImpl.getInstance().getMchID());
signMap.put("prepayid", r.get("prepay_id"));
signMap.put("package", "Sign=WXPay");
signMap.put("noncestr", r.get("nonce_str"));
signMap.put("timestamp", r.get("timestamp"));
String appSign = WXPayUtil.generateSignature(signMap, WXPayConfigImpl.getInstance().getKey());
r.put("sign", appSign);
}
4.对于异步返回参数的注意,需要返回的是XML格式:
Map<String, String> returnMap = new HashMap<>();
returnMap.put("return_code", "SUCCESS");
returnMap.put("return_msg", "OK");
return WXPayUtil.mapToXml(returnMap);
二.Android端
1.在微信的网站上所需要的APP签名最好用文档给的gensignature.apk来获取
2.WXPayEntryActivity这个必须要放在自己的app包名根目录下的wxapi文件夹下,配置为如下
<activity android:exported="true" android:launchMode="singleTop" android:name=".wxapi.WXPayEntryActivity" android:theme="@style/Theme.AppCompat.NoActionBar" />
3.微信支付可以不用sdk的jar包直接在dependencies下配置就可以使用:
compile "com.tencent.mm.opensdk:wechat-sdk-android-with-mta:1.1.6"
三. IOS端
1.不光要实现onResp,还一定要加上handleOpenURL
- (void)handleOpenURL:(NSNotification *)notification {
NSURL *url = [notification object];
if ([url isKindOfClass:[NSURL class]] && [url.scheme isEqualToString:[self settingForKey: @"wxappid"]]) {
[WXApi handleOpenURL:url delegate:self];
}
}
2.时间戳timestamp 只支持10位。
四. 前端
1.前端就是二维码扫描支付,思路是后端生成二维码的链接给前端,前端用js去画个二维码显示,由于qrcode是比较老的库,无法使用amd模块化导入所以使用JQ的getScript:
$.getScript("js/qrcode.min.js")
.done(function(script, textStatus) {
var qrcode = new QRCode(document.getElementById("wxpayQrcode"), {
text: url,
width: 230,
height: 230,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
}).fail(function(jqxhr, settings, exception) {
//"获取二维码失败!
});
2. 获取支付结果,思路是调用后端的微信SDK查询订单接口,可使用socket或者setInterval来做,setInterval时必须注意参数被传递进去是作为他内部的一块内存数据。
this.timer=setInterval(this.payOrderQueryRpc,3000,out_trade_no,self);
payOrderQueryRpc(out_trade_no, self) {
if (document.getElementById("pay" + self.payPageId)) {
if (查询订单) {
clearInterval(self.timer);
}
} else {
clearInterval(self.timer);
}
}
五. 公众号
1.trade_type是JSAPI,下单的时候多两个参数,一个openid一个对下单参数签名sign,在返回给前端的参数就坑爹了,appId,nonceStr 等等这些参数和其他trade_type的参数初看时完全一致,但是但是appId的I是大写,所以一定要注意!!!