2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > wxPay微信支付订单提交提示「订单号重复」问题

wxPay微信支付订单提交提示「订单号重复」问题

时间:2021-09-06 20:28:28

相关推荐

wxPay微信支付订单提交提示「订单号重复」问题

文章目录

1 摘要2 问题复现3 解决办法3.1 解决思路3.2 核心代码3.3 Github项目源码

1 摘要

在项目中使用微信、支付宝等第三方支付的时候,可能会遇到各种偶然性问题,本文将记录关于接入微信支付过程中出现的订单号重复的问题

2 问题复现

微信支付官方文档: https://pay./wiki/doc/api/index.html

常用的微信支付方式包括JSAPI支付、Native支付、APP支付、小程序支付等,对于商户而言,一般都有自己的订单系统,只是支付需要外接第三方,因此商户会有自己的订单编号,一个订单对应一个订单编号,那么会出现这样的场景,商家的用户在平台上下了一个订单,然后使用Native支付的方式提交过一次订单(调用微信的「统一下单接口」),但是未支付,然后再切换到APP支付/小程序支付,由于在微信支付系统中,一个商户的同一个订单号只能选择一种支付方式提交,当这个订单第二次使用不同的方式进行提交时便会出现「订单号重复」的错误

此时如果依旧使用原来的支付方式进行提交,则可以成功,但是切换到其他支付方式,就会返回「订单号重复」的错误

支付宝支付没有这种现象

3 解决办法

3.1 解决思路

将微信支付的每一种支付方式使用一个常量进行标识,在调用微信「统一下单」接口时,将商户自身系统的订单号后边追加支付方式标识,即:

微信「统一下单」订单号 = 商户订单号 + 微信支付方式标识

在微信支付回调时,将获取到的微信「统一下单」订单号还原到商户系统的订单号,然后再进行操作

这样,即使同一个订单通过不同的不同的微信支付方式进行提交,也不会再出现「订单号重复」的错误了(当然,每一次提交订单时也不要忘了校验订单是否已经支付/取消等等)

3.2 核心代码

支付方式标识常量

./src/main/java/com/ljq/demo/pay/common/constant/PayTypeConst.java

package com.ljq.mon.constant;/*** @Description: 支付方式常量* @Author: junqiang.lu* @Date: /4/17*/public class PayTypeConst{/*** 支付方式* 1 : 支付宝支付数字标识* 11: 支付宝电脑网站支付* 12: 支付宝手机网站支付* 13: 支付宝 APP 支付* AliPay: 支付宝支付文字说明** 2: 微信支付标识* 21: 微信 NATIVE 支付(二维码支付)* 22: 微信 JSAPI 支付* 23: 微信 H5 支付* 24: 微信 APP 支付* WxPay: 微信支付文字说明*/public static final int ORDER_PAY_TYPE_ALIPAY = 1;public static final int ORDER_PAY_TYPE_ALIPAY_PC = 11;public static final int ORDER_PAY_TYPE_ALIPAY_WAP = 12;public static final int ORDER_PAY_TYPE_ALIPAY_APP = 13;public static final String ORDER_PAY_TYPE_ALIPAY_NOTE = "AliPay";public static final int ORDER_PAY_TYPE_WX = 2;public static final int ORDER_PAY_TYPE_WX_NATIVE = 21;public static final int ORDER_PAY_TYPE_WX_JSAPI = 22;public static final int ORDER_PAY_TYPE_WX_H5 = 23;public static final int ORDER_PAY_TYPE_WX_APP = 24;public static final String ORDER_PAY_TYPE_WX_NOTE = "WxPay";}

订单支付业务层示例

./src/main/java/com/ljq/demo/pay/service/impl/PayServiceImpl.java

package com.ljq.demo.pay.service.impl;import com.alipay.api.AlipayApiException;import com.alipay.api.internal.util.AlipaySignature;import com.ljq.demo.pay.bean.PayBean;import com.ljq.mon.api.ApiResult;import com.ljq.mon.api.ResponseCode;import com.ljq.mon.constant.PayTypeConst;import com.ljq.mon.util.*;import com.ljq.demo.pay.configure.AliPayConfig;import com.ljq.demo.pay.configure.WxPayConfig;import com.ljq.demo.pay.service.PayService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.util.StringUtils;import javax.servlet.http.HttpServletRequest;import java.io.IOException;import java.io.InputStream;import java.util.HashMap;import java.util.Map;import java.util.Objects;/*** @Description: 支付业务具体实现* @Author: junqiang.lu* @Date: /7/10*/@Service("payService")@Slf4jpublic class PayServiceImpl implements PayService {@Autowiredprivate WxPayConfig wxPayConfig;@Autowiredprivate AliPayConfig aliPayConfig;/*** 创建支付订单** @param payBean json 格式参数* @return*/@Overridepublic ApiResult createPayOrder(PayBean payBean) throws Exception {// 微信支付金额换算int amountWxPay = CalculateUtil.multiply(Double.valueOf(payBean.getAmount()), 100, 2).intValue();// 返回结果Map<String, String> resultMap = new HashMap<>(16);// 创建支付订单switch (payBean.getPayType()) {case PayTypeConst.ORDER_PAY_TYPE_ALIPAY_PC:// 支付宝电脑网站支付String aliPayPCForm = AliPayManager.createPCOrder(payBean.getOrderNo(),String.valueOf(payBean.getAmount()), aliPayConfig);if (!StringUtils.isEmpty(aliPayPCForm)) {resultMap.put("prePayOrderInfo",aliPayPCForm);return ApiResult.success(resultMap);}break;case PayTypeConst.ORDER_PAY_TYPE_ALIPAY_WAP:// 支付宝手机网站支付String aliPayWapForm = AliPayManager.createWapOrder(payBean.getOrderNo(),String.valueOf(payBean.getAmount()), aliPayConfig);if (!StringUtils.isEmpty(aliPayWapForm)) {resultMap.put("prePayOrderInfo",aliPayWapForm);return ApiResult.success(resultMap);}break;case PayTypeConst.ORDER_PAY_TYPE_ALIPAY_APP:// 支付宝 APP 支付String aliPayAppForm = AliPayManager.createAppOrder(payBean.getOrderNo(),String.valueOf(payBean.getAmount()), aliPayConfig);if (!StringUtils.isEmpty(aliPayAppForm)) {resultMap.put("prePayOrderInfo",aliPayAppForm);return ApiResult.success(resultMap);}break;case PayTypeConst.ORDER_PAY_TYPE_WX_NATIVE:// 微信 NATIVE 支付(二维码)Map<String,String> wxPayNativeMap = WxPayManager.createNativeOrder(wxPayConfig,payBean.getOrderNo() + PayTypeConst.ORDER_PAY_TYPE_WX_NATIVE,amountWxPay, payBean.getIp());if (wxPayNativeMap != null &&Objects.equals(wxPayNativeMap.get("pre_pay_order_status"), wxPayConfig.getResponseSuccess())) {resultMap.put("prePayOrderInfo",wxPayNativeMap.get("code_url"));return ApiResult.success(resultMap);}break;case PayTypeConst.ORDER_PAY_TYPE_WX_JSAPI:// 微信 JsAPI 支付(公众号)if (StringUtils.isEmpty(payBean.getOpenId())) {return ApiResult.failure(ResponseCode.PAY_SUBMIT_ERROR);}Map<String, String> wxPayJsAPIMap = WxPayManager.createJsAPIOrder(wxPayConfig,payBean.getOrderNo() + PayTypeConst.ORDER_PAY_TYPE_WX_JSAPI,amountWxPay, payBean.getIp(), payBean.getOpenId());if (wxPayJsAPIMap != null &&Objects.equals(wxPayJsAPIMap.get("pre_pay_order_status"), wxPayConfig.getResponseSuccess())) {return ApiResult.success(wxPayJsAPIMap);}break;case PayTypeConst.ORDER_PAY_TYPE_WX_H5:// 微信 H5 支付Map<String, String> wxPayH5Map = WxPayManager.createH5Order(wxPayConfig,payBean.getOrderNo() + PayTypeConst.ORDER_PAY_TYPE_WX_H5,amountWxPay, payBean.getIp());if (wxPayH5Map != null &&Objects.equals(wxPayH5Map.get("pre_pay_order_status"), wxPayConfig.getResponseSuccess())) {resultMap.put("prePayOrderInfo",wxPayH5Map.get("mweb_url"));return ApiResult.success(resultMap);}break;case PayTypeConst.ORDER_PAY_TYPE_WX_APP:// 微信 APP 支付Map<String, String> wxPayAppMap = WxPayManager.createAppOrder(wxPayConfig,payBean.getOrderNo() + PayTypeConst.ORDER_PAY_TYPE_WX_APP,amountWxPay, payBean.getIp());if (wxPayAppMap != null &&Objects.equals(wxPayAppMap.get("pre_pay_order_status"), wxPayConfig.getResponseSuccess())) {return ApiResult.success(wxPayAppMap);}break;case PayTypeConst.ORDER_PAY_TYPE_WX_MINI:// 微信 小程序 支付if (StringUtils.isEmpty(payBean.getOpenId())) {return ApiResult.failure(ResponseCode.PAY_SUBMIT_ERROR);}Map<String, String> wxPayMiniMap = WxPayManager.createJsAPIOrder(wxPayConfig,payBean.getOrderNo() + PayTypeConst.ORDER_PAY_TYPE_WX_MINI,amountWxPay, payBean.getIp(), payBean.getOpenId());if (wxPayMiniMap != null &&Objects.equals(wxPayMiniMap.get("pre_pay_order_status"), wxPayConfig.getResponseSuccess())) {return ApiResult.success(wxPayMiniMap);}break;default:return ApiResult.failure(ResponseCode.PAY_TYPE_ERROR);}return ApiResult.failure(ResponseCode.PAY_SUBMIT_ERROR);}/*** (主动)获取支付结果** @param payBean 订单信息(json 格式参数)* @return*/@Overridepublic ApiResult getPayResult(PayBean payBean) throws Exception {// 返回结果Map<String, String> resultMap;switch (payBean.getPayType()) {case PayTypeConst.ORDER_PAY_TYPE_ALIPAY_PC:case PayTypeConst.ORDER_PAY_TYPE_ALIPAY_WAP:case PayTypeConst.ORDER_PAY_TYPE_ALIPAY_APP:resultMap = AliPayManager.getPayResult(aliPayConfig, payBean.getOrderNo());break;case PayTypeConst.ORDER_PAY_TYPE_WX_NATIVE:case PayTypeConst.ORDER_PAY_TYPE_WX_JSAPI:case PayTypeConst.ORDER_PAY_TYPE_WX_H5:case PayTypeConst.ORDER_PAY_TYPE_WX_APP:case PayTypeConst.ORDER_PAY_TYPE_WX_MINI:resultMap = WxPayManager.getPayResult(wxPayConfig, payBean.getOrderNo() + payBean.getPayType());break;default:return ApiResult.failure(ResponseCode.PAY_TYPE_ERROR);}if (MapUtil.isEmpty(resultMap)) {return ApiResult.failure(ResponseCode.PAY_STATUS_ERROR);}return ApiResult.success(resultMap);}/*** 微信支付结果通知** @param request 微信支付回调请求* @return 支付结果*/@Overridepublic String wxPayNotify(HttpServletRequest request) {String result = null;try {InputStream inputStream = request.getInputStream();/*** 读取通知参数*/String strXML = FileUtil.getStringFromStream(inputStream);Map<String,String> reqMap = MapUtil.xml2Map(strXML);if(MapUtil.isEmpty(reqMap)){log.warn("request param is null");return wxPayConfig.getResponseFail();}/*** 校验签名*/if(!SignUtil.signValidate(reqMap, wxPayConfig.getKey(), wxPayConfig.getFieldSign())){log.warn("wxPay sign is error");return wxPayConfig.getResponseFail();}String orderNo = reqMap.get("out_trade_no").substring(0,reqMap.get("out_trade_no").length()-2);log.debug("微信支付回调,订单编号: {}", orderNo);// TODO 其他业务处理Map<String, String> resultMap = new HashMap<>(16);resultMap.put("return_code",wxPayConfig.getResponseSuccess());resultMap.put("return_msg","OK");result = MapUtil.map2Xml(resultMap);} catch (IOException e) {log.error("get request inputStream error",e);return wxPayConfig.getResponseFail();} catch (Exception e) {log.error("resolve request param error",e);return wxPayConfig.getResponseFail();}return result;}/*** 支付宝支付结果通知** @param request 支付宝回调请求* @return*/@Overridepublic String aliPayNotify(HttpServletRequest request) {// 读取通知参数Map<String, String> params = AliPayManager.getNotifyParams(request.getParameterMap());if(MapUtil.isEmpty(params)){return aliPayConfig.getResponseFail();}try {// 签名校验if(!AlipaySignature.rsaCheckV1(params, aliPayConfig.getAlipayPublicKey(),aliPayConfig.getCharset(), aliPayConfig.getSignType())){return aliPayConfig.getResponseFail();}String orderNo = params.get("out_trade_no");log.debug("支付宝回调,订单编号: {}",orderNo);// TODO 其他业务处理} catch (AlipayApiException e) {log.error("支付宝回调验证失败",e);return aliPayConfig.getResponseFail();}return aliPayConfig.getResponseSuccess();}/*** 支付宝支付同步通知返回地址* @param request* @return*/@Overridepublic String aliPayReturnUrl(HttpServletRequest request) {// 读取通知参数Map<String, String> params = AliPayManager.getNotifyParams(request.getParameterMap());if(MapUtil.isEmpty(params)){return "alipay_fail_url";}try {// 签名校验if(!AlipaySignature.rsaCheckV1(params, aliPayConfig.getAlipayPublicKey(),aliPayConfig.getCharset(), aliPayConfig.getSignType())){return "alipay_fail_url";}} catch (AlipayApiException e) {log.error("支付宝回调验证失败",e);return aliPayConfig.getResponseFail();}return "alipay_success_url";}}

3.3 Github项目源码

GitHub项目源码: /Flying9001/pay

个人公众号:404Code,记录半个互联网人的技术与思考,感兴趣的可以关注.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。