成xml,这个就很简单了。我们可以考虑把它加到PayService里面(其他地方用不着,你可以考虑私有,相信我,这样会更优雅)。
/**
* 得到统一下单参数的xml形式
*
* @param parameters
* @return
*/
public static String getRequestXml(Map<String, String> parameters) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set es = parameters.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 ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
} else {
sb.append("<" + k + ">" + v + "</" + k + ">");
}
}
sb.append("</xml>");
return sb.toString();
}
于是,我们得到了统一下单的参数,接下来就是去请求微信服务器了。
/**
* 支付接口
* @param body
* @param totalFee
* @param user
* @param response
* @return
* @throws Exception
*/
@PostMapping(value = "/pay")
public RequestResult<Map<String, String>> order(@RequestParam("body")String body,
@RequestParam("totalFee")String totalFee,
@SessionAttribute(name = "user", required = false)User user,
HttpServletResponse response) throws Exception {
//之前我们获得了openId,这里我使用假数据测试
String openId = "oxxjlv1dWSkielTGFfWQGNK-RHSc";
String ip = this.getIpAddress();
String requestParam = payService.getPayParam(openId, totalFee, ip, body);
//stop here ,下面我会讲
Map<String, String> result = payService.requestWechatPayServer(requestParam);
Map<String, String> datas = new TreeMap<>();
if (result.get("return_code").equals("SUCCESS")) {
String prepayId = result.get("prepay_id");
datas.put("appId", weChatConfigBean.getAppId());
datas.put("package", "prepay_id=" + prepayId);
datas.put("signType", "MD5");
datas.put("timeStamp", Long.toString(new Date().getTime()).substring(0, 10));
datas.put("nonceStr", WXUtil.getNonceStr());
String sign = SignatureUtils.signature(datas, weChatConfigBean.getKEY());
datas.put("paySign", sign);
return ResultUtil.success(datas);
}
return ResultUtil.fail();
}
组装调起支付参数
继续上面的控制器,我们已经得到了预支付id,那么我们离成功不远了 请相信我,我没有骗你。然后我们要封装调起支付参数,我们先看一下jssdk调起支付需要的参数。
wx.chooseWXPay({
timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: '', // 支付签名随机串,不长于 32 位
package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: '', // 支付签名
success: function (res) {
// 支付成功后的回调函数
}
});
那么我们就根据这个参数列表来生成参数,不过我很好奇,为什么timeStamp一阵大写一阵小写的,我想估计脑子抽了吧。现在我们看看上面的控制器剩余的代码,其实就是组装这个参数到Map,我想这个应该没有疑惑的地方吧。说到这,微信开发基本结束了,剩下的就是js调起支付,输入密码,微信服务器判断,给你返回结果的过程,处理结果的接口我就不贴了,简单到不行。
结尾
在做微信支付的时候,我有时候真的很无奈,没有好的官方文档,更没有好的博文,这篇博客旨在能讲清楚微信支付的步骤,我知道在这么短的时间讲清楚显然不可能,希望各位多多指正,有问题的可以发邮件给我,StormMaybin@gmail.com。哦对了,最后别忘记配置支付目录,不然会显示url未注册。应部分人的要求,最后写了一个demo,附上链接:https://github.