流程图
地址:微信支付开发文档
1. 小程序登录
Message<Map> message = HttpTools.get("https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=" + code + "&grant_type=authorization_code", Map.class);
前端传送code,请求接口获取微信openid
其中,APPID 和 SECRET 在小程序平台查看并写入
2. 调用统一下单接口
统一下单接口api
请求地址:https://api.mch.weixin.qq.com/pay/unifiedorder
请求方式:POST
请求参数:Xml格式的字符串
说明:为了获取下一步的prepay_id
按文档中的要求组装xml
String xml = "<xml>" +
" <appid>APPID</appid>" +
" <attach>测试</attach>" +
" <body>测试</body>" +
" <mch_id>MCH_ID</mch_id>" +
" <nonce_str>nonce_str</nonce_str>" +
" <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>" +
" <openid>openid</openid>" +
" <out_trade_no>out_trade_no</out_trade_no>" +
" <spbill_create_ip>IP</spbill_create_ip>" +
" <total_fee>1</total_fee>" +
" <trade_type>JSAPI</trade_type>" +
" <sign>SIGN</sign>" +
"</xml>";
说明几个参数:
appid:登录公众号后台查找
mch_id: 商户号,在公众号后台查找
nonce_str:随机字符串
notify_url: 通知地址,用于后面自动请求发送回调信息
sign:签名,需要按照格式进行组装和编码。
注:参数参考官方api要求添写,其中必填项已标出,按照要求的顺序进行组装即可。
- 签名要求:签名中,有一个key需要注意,这是一个秘钥key,需要在商户后台进行设置,根据商户号进行查询,然后设置秘钥。如果这个秘钥不正确,会出现签名错误等异常情况,可以在微信的签名验证工具中进行签名的尝试。
微信签名工具
3. 再次签名
再次签名api
将在统一下单中请求后返回的数据进行拼接
appId=APPID&nonceStr=5K8264ILTKCH16CQ2502SI8ZNMTM67VS&package=prepay_id=prepay_id&signType=MD5&timeStamp=1490840662&key=KEY
对该字符串进行签名后返回即可,返回必填参数如下:
其中,package 的参数要注意,返回的参数格式为
package: prepay_id=xxx
至此,微信支付基本可以使用了。可以进行付款等行为,不过还需要进行进一步的完善。
4. 查询结果通知
查询结果通知api
这一步的目的是微信进行检测支付是否成功,然后通知系统,并进行下一步业务处理。
主要步骤是进行签名验证和金额验证。
通过在统一下单时添加的notify_url设置,微信支付成功后会自动调用这个连接。
以流方式进行接收(HttpServletRequest request),POST请求。
@RequestMapping(value = "/callBackUrl", method = RequestMethod.POST)
public String callBackUrl(HttpServletRequest request, HttpServletResponse response) {
InputStream inStream;
String xml = "";
log.info("[weixin pay back msg] " + "支付回调成功");
try {
inStream = request.getInputStream();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
// 获取微信调用我们notify_url的返回信息
String result = new String(outStream.toByteArray(), "utf-8");
//至此获得微信自动给我们返回回来的数据result,也是xml格式的,需要进行xml--->map形式的转化,后续步骤就不在这里说明了。
//......
}catch(Exception e){
e.printStackTrace();
}
if(xxx){
xml = "<xml>"
+ "<return_code>SUCCESS</return_code>"
+ "<return_msg>OK</return_msg>"
+ "</xml>";
}
return xml;
}
验证签名就是将获取到的参数,通过签名规则顺序进行组装,不包括sign,加上设置的api秘钥key,通过MD5得到的签名与返回的参数签名进行比对,如果相同则为验证通过
5. 查询订单
查询订单api
如果没有收到自动发送的消息,可以手动进行订单查询
String stringA = "appid=APPID&mch_id=MCH_ID&nonce_str=" + nonce_str + "&out_trade_no=" + outTradeNo;
String stringSignTemp = stringA + "&key=KEY";
String sign = MD5Tools.md5(stringSignTemp).toUpperCase();
String xml = "<xml>" +
" <appid>APPID</appid>" +
" <mch_id>MCH_ID</mch_id>" +
" <nonce_str>" + nonce_str + "</nonce_str>" +
" <out_trade_no>" + outTradeNo + "</out_trade_no>" +
" <sign>" + sign + "</sign>" +
"</xml>";
请求地址:https://api.mch.weixin.qq.com/pay/orderquery
请求方式:POST
参数:String(xml)