看到Tx的WeChatPay的文档真是无语了,感觉乱七八糟的……这里自己稍微整理下我的流程。这里的业务流程主要针对于公众号支付
设置
https://pay.weixin.qq.com
在这取得
MchId--商户号
apiKey--商户Key
https://mp.weixin.qq.com
在这取得
AppID-应用ID
在页面的->微信支付->开发配置->公众号支付
设置对应的支付授权目录、测试授权目录、已经将自己的微信号添加到白名单
统一下单
买家在在提交订单以后,将向微信生成支付订单,在微信生成支付订单;
生成Sign值
根据文档的说明,要产生一张订单,WeChat的接口需要我们Post一段带有订单信息的XML给他们。
在自己的商城生成了该订单的相关信息以后,首先根据WeChat的Sign签名算法的生成签名,将要post过去除了sign以外的所有信息(一定是所有!这里特别强调下,我在这里给误导了好久以为只用把官方文档上要的Sign进行前面算法),进行官方的Sign签名算法(详情见微信文档),通过签名算法计算得出的签名值。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public static String getWXPayMD5(SortedMap<String, String> packageParams, String apiKey) { StringBuffer sb = new StringBuffer(); Set es = packageParams.entrySet() Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey() String v = (String) entry.getValue() if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&") } } sb.append("key=" + apiKey) return MD5(sb.toString()).toUpperCase() }
|
notify_url——异步接收微信支付结果通知的回调地址
既然是支付,支付成功以后,微信就要告诉你卖家已经支付成功,也就是支付结果的通知,notify_url 就是拿来设置微信在哪里告诉你买家已经支付成功的地方。
后台发送订单信息
当生成Sign的签名值生成和回调的接口设置好以后,后台需要发送订单要生成的订单信息,并接受生成好订单信息;后台需要将Xml信息整合在一起在后台Post到微信的接口上,并且接收回调信息,这是他会告诉你订单是否接受成功,并且把微信支付订单的相关信息告诉你。(特别注意:这里要发起Https的请求)
Post过去的信息举例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <xml> <appid>公众账号的ID</appid> <attach>支付测试</attach> <body>JSAPI支付测试</body> <mch_id>商户号</mch_id> <nonce_str>随机字符串</nonce_str> <notify_url>你要回调的地址接口</notify_url> <openid>用户标识-用户的openid</openid> <out_trade_no>你自己系统内部的订单号</out_trade_no> <spbill_create_ip>14.23.150.211</spbill_create_ip> <total_fee>1</total_fee> <trade_type>JSAPI</trade_type> <sign>你其他信息合在一起的sign签名值</sign> </xml>
|
Post成功后微信会在后台生成微信支付订单
回调的信息举例如下:
1 2 3 4 5 6 7 8 9 10 11 12
| <xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> <appid><![CDATA[wx2421b1c4370ec43b]]></appid>提交订单的公众账号ID <mch_id><![CDATA[10000100]]></mch_id>提交订单的商户号 <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str> <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid> <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign> <result_code><![CDATA[SUCCESS]]></result_code> <prepay_id><![CDATA[wx20141110174]]></prepay_id>微信生成的订单号 <trade_type><![CDATA[JSAPI]]></trade_type> </xml>
|
生成paySign,回调订单信息给网页端
当支付订单生成以后,需要生成paySign给网页端,准备让网页端调用支付的API;将appId、
timeStamp、nonceStr、package(特别注意格式prepay_id=XXXX)、signType、进行paySign签名生成,生成的方法和Sign一样。之后将这些信息返回给网页端;
网页端调起支付API
当支付订单生成以后,得到了加密的PaySign以后,将appI、timeStamp、nonceStr、package、signType、paySign填写正确以后,微信将调用支付页面,买家将可以进行付款
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId":"wx2421b1c4370ec43b", "timeStamp":"1395712654", "nonceStr":"e61463f8efa94090b1f366cccfbbb444", "package":"prepay_id=u802345jgfjsdfgsdg888", "signType":"MD5", "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" }, function(res){ if(res.err_msg == "get_brand_wcpay_request: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(); }
|
接受支付成功信息
当买家支付成功以后,微信会Psot一段信息到你的服务器上,之前notify_url——就是异步接收微信支付结果通知的回调地址,这种时候就需要写一个接口,让微信把支付成功的数据Post过来,我们需要接收处理这段数据,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。
当收到这段信息以后,需要回调一段信息,告诉微信已经收到支付成功的信息了!不用再发了!
1 2 3 4
| <xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> </xml>
|
否则微信会通过一定的策略定期重新发起通知(通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒),
告诉微信收到支付信息的同时,我们就可以处理其他业务信息了。~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @RequestMapping(value = "/payresponse", method = RequestMethod.POST) @ResponseBody public String Payresponse(@RequestBody String PayResponse) { public void run(){ /*开多个处理其他业务*/ } String WXresult = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"; return WXresult; } }
|
————完
世界上本没有坑,都是自己挖的!……