接上篇,现在已经获取到微信的openid了,下步需要获取prepay_id。
1、继续微信支付的接口API:把必传的参数列出来:
- 公众账号ID appid
- 商户号 mch_id
- 随机字符串 nonce_str
- 签名 sign
- 商品描述 body
- 商户订单号 out_trade_no
- 总金额 total_fee 注意单位是分
- 终端IP spbill_create_ip
- 通知地址 notify_url
- 交易类型 trade_type
- 用户标识 openid 网页支付必传
2、下面构造上述信息;先登录微信商户平台,获取商户号mch_id
3、设置支付密钥、下载证书:
-
注意在设置密钥的时候要注意是否已经设置,重设会影响到线上支付。
4、到此,我们已经拿到了 - 公众账号ID appid
- 商户号 mch_id
- 支付密钥 签名需要
- 用户标识 openid 网页支付必传
5、其它根据自身业务需要构造即可。
6、我们来看签名算法 - 1)、设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
- 2)、拼接API密钥:finalStr=”stringA&key=你设置的支付密钥”;
- 3)、加密:MD5(stringSignTemp).toUpperCase()
7、到此,看回第一篇中提到的构建微信统一支付请求xml串代码
/**
* 构建微信统一支付请求xml串
* @param payParams
* @return str
*/
public static String buildUnifiedOrderReq(Map<String,String> payParams){
String payStr = "";
payStr += "<xml>";
payStr += "<appid>"+payParams.get("appid")+"</appid>";
payStr += "<body>"+payParams.get("body")+"</body>";
payStr += "<mch_id>"+payParams.get("mch_id")+"</mch_id>";
payStr += "<nonce_str>"+payParams.get("nonce_str")+"</nonce_str>";
payStr += "<notify_url>"+payParams.get("notify_url")+"</notify_url>";
payStr += "<openid>"+payParams.get("openid")+"</openid>";
payStr += "<out_trade_no>"+payParams.get("out_trade_no")+"</out_trade_no>";
payStr += "<spbill_create_ip>"+payParams.get("spbill_create_ip")+"</spbill_create_ip>";
payStr += "<total_fee>"+payParams.get("total_fee")+"</total_fee>";
payStr += "<trade_type>JSAPI</trade_type>";
payStr += "<sign>"+payParams.get("sign")+"</sign>";
payStr +="</xml>";
return payStr;
}
8、将业务参数拼接后,我们就能得到要发送的请求串了。
9、请求接口的时候,需要设置证书,注意证书的路径。如果是java开发,这个比较简单。Windows环境的话就要导入证书,这些步骤参照微信支付的帮助文档即可。
10、下一步,需要去微信公众号设置支付测试目录:
参考官方说明即可:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3
11、设置完毕,就到H5微信内调起微信支付了。
12、来到官方说明【注意,有坑】:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
先把示例代码复制:
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId" [:] "wx2421b1c4370ec43b", //公众号名称,由商户传入
"timeStamp"[:]" 1395712654", //时间戳,自1970年以来的秒数
"nonceStr" [:] "e61463f8efa94090b1f366cccfbbb444", //随机串
"package" [:] "prepay_id=u802345jgfjsdfgsdg888",
"signType" [:] "MD5", //微信签名方式:
"paySign" [:] "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {} // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。
}
);
}
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady();
}
- 坑:示例代码中前面部分的冒号:不是英文下的符号,见代码中,已经用[]标出。
请复制下面的代码:
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId" : appId, /* 微信支付,坑一 冒号是中文字符 */
"timeStamp":timeStamp,
"nonceStr": nonceStr,
"package":pckage,
"signType": signType,
"paySign":paySign
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
alert("充值成功");
}else{
alert(res.err_msg);
}
}
);
}
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady();
}
13、到此,已经完成了80%了。把代码部署到测试服务器。访问测试即可。
14、此部分测试微信开发工具调试不了,所以每一步都要自己把好关。不然调试的时候头都大。
15、最后,把遇到的问题列出来,予以分享:
- 1、调起支付的时候,一闪而过?
- 答:请检查签名正确与否
- 2、支付不了?
- 答:请检查自己的微信号是否已经加入了测试号中
- 最后,需要检查费用单位是否是分、支付路径大小写、安全支付域名是否正确。