引言:之前的项目中涉及了微信支付,今天在这里整理下记录下来。废话不多说,直接上demo
一、首先需要开通微信支付功能
小程序认证以后,可以在小程序后台,微信支付菜单栏,申请微信支付。
二、官方文档
(多读几遍文档也是很简单的)
https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
三、大致的把支付流程分成如下步骤
(1)小程序向服务端发起支付请求
略
(2)服务端向微信服务器发起统一下单
官网统一下单文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
扫描二维码关注公众号,回复:
10909285 查看本文章
Tips:
1)微信提供了支付的demo和工具包:
工具包:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1
里面有如下文件,我这里只用了WXPayUtil、WXPayXmlUtil,(需要对里面报错提示的地方进行修改补充)
2)用户的openid(支付用户的openid哟)
private final String UNIFIED_ORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";
private ResultInfo prePayOrder() {
ResultInfo resultInfo = new ResultInfo();
String appid = AppConstantsUtil.getWeixinMiniProgramAppId();//小程序appid
final String WXPAY_KEY = AppConstantsUtil.getWeixinPayKey();//商户支付密钥
final String timeStamp = WXPayUtil.getCurrentTimestamp()+"";//时间戳,需要多次使用
Map<String,String> orderParamsMap=new HashMap<>();
orderParamsMap.put("appid",appid);
orderParamsMap.put("body","商品名称");
orderParamsMap.put("detail","商品描述");
orderParamsMap.put("mch_id",AppConstantsUtil.getWeixinMchId());//商户号
String nonceStr = WXPayUtil.generateNonceStr();//随机字符串,需要多次使用
orderParamsMap.put("nonce_str",nonceStr);
orderParamsMap.put("notify_url","订单回调通知地址,外网必须能够访问");
orderParamsMap.put("openid","用户的openid");
orderParamsMap.put("out_trade_no", "商户自定义订单号");
orderParamsMap.put("spbill_create_ip","127.0.0.1");//终端ip
orderParamsMap.put("total_fee","金额,单位是分");
orderParamsMap.put("trade_type","JSAPI");
try {
// 微信支付工具包提供的方法(参数排序、加密签名、转为xml字符串)
String paramXmlStr = WXPayUtil.generateSignedXml(orderParamsMap, WXPAY_KEY);
// 向微信发起post请求
String orderResultStr = postCommand(UNIFIED_ORDER, paramXmlStr);
// 微信支付工具包提供的方法(返回的xml字符串转为map)
Map<String, String> orderResultMap = WXPayUtil.xmlToMap(orderResultStr);
// 下单成功
if("SUCCESS".equals(orderResultMap.get("return_code")) && "SUCCESS".equals(orderResultMap.get("result_code"))){
Map<String,String> payParamsMap=new HashMap<>();
// 这里有坑需要注意:上面发起订单的时候是appid,这里是appId
payParamsMap.put("appId",appid);
payParamsMap.put("nonceStr",nonceStr);//上面用到的随机字符串
payParamsMap.put("package","prepay_id="+orderResultMap.get("prepay_id"));//订单号
payParamsMap.put("signType","MD5");
payParamsMap.put("timeStamp",timeStamp);//上面用到的时间戳
System.out.println("payParamsMap"+payParamsMap.toString());
// 微信支付工具包提供的方法,参数排序并且MD5加密生成签名
String paySign = WXPayUtil.generateSignature(payParamsMap, WXPAY_KEY);
payParamsMap.put("paySign",paySign);
// 返回给小程序
return ResultInfo.success(payParamsMap,"微信预支付下单成功!");
}else {
logger.info("创建预支付订单失败,{}",orderResultMap.get("err_code_des"));
ResultInfo.error("创建订单失败");
}
} catch (Exception e) {
e.printStackTrace();
}
return resultInfo;
}
(3)服务端响应小程序(1)步请求,拉起支付界面
// 服务端返回的数据res
wx.requestPayment({
'timeStamp': res.data.timeStamp,
'nonceStr': res.data.nonceStr,
'package': res.data.package_,
'signType': 'MD5',
'paySign': res.data.paySign,
success (res) {
console.info(res)
},
fail (res) {
console.info(res)
},
complete (res) {
console.info(res)
}
})
(4)支付结果通知(用户在小程序端支付成功后,微信服务端回调通知商户)
商户对订单状态进行修改
public void wxPayCallback(HttpServletRequest request, HttpServletResponse response){
logger.info("微信通知回调。。");
try {
StringBuffer sb = new StringBuffer();
InputStream inputStream = request.getInputStream();
String s ;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null){
sb.append(s);
}
in.close();
inputStream.close();
Map<String, String> stringStringMap = WXPayUtil.xmlToMap(sb.toString());
logger.info("订单通知回调{}",stringStringMap.toString());
Map<String, String> resultMap = new HashMap<>();
if ("SUCCESS".equals(stringStringMap.get("result_code"))){
// 验证签名防止被篡改
boolean signatureValid = WXPayUtil.isSignatureValid(stringStringMap, AppConstantsUtil.getWeixinPayKey());
if (signatureValid) {
logger.info("订单:{}支付成功!",stringStringMap.get("out_trade_no"));
// 处理自己的相关业务
//sxqOrderService.dealOrder(stringStringMap);
// 返回success给微信服务端,不然微信会认为你没收到会重发共十次
resultMap.put("return_code","SUCCESS");
resultMap.put("return_msg","OK");
}else{
resultMap.put("return_code","FAIL");
resultMap.put("return_msg","签名失败");
}
}else {
logger.error("支付失败");
resultMap.put("return_code","FAIL");
resultMap.put("return_msg","支付失败");
}
PrintWriter writer = response.getWriter();
writer.write(WXPayUtil.mapToXml(resultMap));
writer.flush();
writer.close();
} catch (Exception e) {
logger.error("参数异常");
e.printStackTrace();
}
}
总结:理清整个支付流程,用上微信提供的工具包,自己只需要提供相应的数据就ok了,还是很简单。
希望对你有所微薄的帮助。
向上的路并不拥挤,而大多数人选择了安逸