From f85b141037a451e2fadb63651dcb711578a2c20a Mon Sep 17 00:00:00 2001 From: xiaohanzi Date: Wed, 10 Jun 2020 13:49:37 +0800 Subject: [PATCH] fix weixin pay bug --- .../helper/WxPayOrderServiceHelper.java | 146 ++++++++++++++++++ .../service/impl/WxPayOrderServiceImpl.java | 104 +++++-------- 2 files changed, 185 insertions(+), 65 deletions(-) create mode 100644 mallinkService/src/main/java/com/iformall/service/helper/WxPayOrderServiceHelper.java diff --git a/mallinkService/src/main/java/com/iformall/service/helper/WxPayOrderServiceHelper.java b/mallinkService/src/main/java/com/iformall/service/helper/WxPayOrderServiceHelper.java new file mode 100644 index 000000000..827a8f52a --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/helper/WxPayOrderServiceHelper.java @@ -0,0 +1,146 @@ +package com.iformall.service.helper; + +import java.util.Date; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.iformall.common.ErrorCode; +import com.iformall.common.Result; +import com.iformall.common.ResultData; +import com.iformall.domain.po.WxAppinfo; +import com.iformall.domain.po.WxMerchantBUser; +import com.iformall.domain.po.WxOrder; +import com.iformall.domain.po.WxPayAccount; +import com.iformall.domain.po.WxPayOrder; +import com.iformall.enums.EnumOrderStatus; +import com.iformall.enums.EnumPayEndFrom; +import com.iformall.enums.EnumPayMode; +import com.iformall.enums.EnumPayStatus; +import com.iformall.exception.MallinkException; +import com.iformall.pay.WxPay; +import com.iformall.pay.WxPayOrderQ; +import com.iformall.pay.WxPayOrderSQ; +import com.iformall.pay.WxPayment; +import com.iformall.utils.BeanUtils; +import com.iformall.utils.Utility; + +public class WxPayOrderServiceHelper { + + private static final Logger logger = LoggerFactory.getLogger(WxPayOrderServiceHelper.class); + /** + * 微信订单是否可以支付 + */ + public static int wxOrderPayStatus(WxPayOrder record,WxOrder order,WxAppinfo appInfo,WxPayAccount payAccount) { + if (record == null) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "wxPayOrder is null."); + } + if (StringUtils.isBlank(record.getPayOrderNo())) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "payOrderNo not found"); + } + if (order == null) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "Order not found"); + } + + String response = wechatPayOrderQuery(appInfo, record,payAccount); + + logger.info("pay order query, " + record.toString() + ", response: " + response); + Map returnMap = WxPayment.xmlToMap(response); + String return_code = returnMap.get("return_code"); + if ("SUCCESS".equalsIgnoreCase(return_code)) { + + String result_code = returnMap.get("result_code"); + + if ("SUCCESS".equals(result_code)) { + String trade_state = returnMap.get("trade_state"); + //SUCCESS—支付成功,REFUND—转入退款,NOTPAY—未支付,CLOSED—已关闭,REVOKED—已撤销(刷卡支付),USERPAYING--用户支付中,PAYERROR--支付失败(其他原因,如银行返回失败) + if ("SUCCESS".equals(trade_state)) { + return EnumPayStatus.PAY_STATUS_SUCCESS.getCode(); + }else if ("REFUND".equals(trade_state)) { + return EnumPayStatus.PAY_STATUS_REFUND.getCode(); + }else if ("NOTPAY".equals(trade_state)) { + return EnumPayStatus.PAY_STATUS_NOTPAY.getCode(); + }else if ("CLOSED".equals(trade_state)) { + return EnumPayStatus.PAY_STATUS_CLOSE.getCode(); + }else if ("REVOKED".equals(trade_state)) { + return EnumPayStatus.PAY_STATUS_REVERSE.getCode(); + }else if ("USERPAYING".equals(trade_state)) { + return EnumPayStatus.PAY_STATUS_WAIT.getCode(); + }else if ("PAYERROR".equals(trade_state)) { + return EnumPayStatus.PAY_STATUS_FAIL.getCode(); + } + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询微信支付状态非法["+trade_state+"]"+record.getPayOrderNo()); + }else { + String errCode = returnMap.get("err_code"); + String errCodeDes = returnMap.get("err_code_des"); + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询微信支付状态失败["+errCode+":"+errCodeDes+"]"+record.getPayOrderNo()); + } + } else { + String return_msg = returnMap.get("return_msg"); + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询微信支付状态失败"+return_msg); + } + } + + + public static String wechatPayOrderQuery(WxAppinfo appInfo, WxPayOrder record ,WxPayAccount payAccount) { + if (payAccount == null) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "WxPayAccount not found"); + } + // get payAccount + if (payAccount.getType() == EnumPayMode.MCH.getCode()) { + // 普通商户号模式 + WxPayOrderQ payOrderQ = new WxPayOrderQ(); + String noncestr = Utility.generate32UUID(); + payOrderQ.setAppid(appInfo.getAppId()); + payOrderQ.setMch_id(payAccount.getMchId()); + payOrderQ.setNonce_str(noncestr); + if (StringUtils.isNotBlank(record.getTransactionId())) { + payOrderQ.setTransaction_id(record.getTransactionId()); + } else { + payOrderQ.setOut_trade_no(record.getPayOrderNo()); + } + + try { + Map map = BeanUtils.toStringMap(payOrderQ); + payOrderQ.setSign(WxPayment.createSign(map, payAccount.getApiKey())); + map = BeanUtils.toStringMap(payOrderQ); + String response = WxPay.orderQuery(map); + return response; + } catch (RuntimeException e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } catch (Exception e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } + } else { + // 服务商模式 + WxPayOrderSQ payOrderSQ = new WxPayOrderSQ(); + String noncestr = Utility.generate32UUID(); + payOrderSQ.setAppid(appInfo.getParentAppId()); + payOrderSQ.setSub_appid(appInfo.getAppId()); + payOrderSQ.setMch_id(payAccount.getMchId()); + payOrderSQ.setSub_mch_id(payAccount.getSubMchId()); + payOrderSQ.setNonce_str(noncestr); + if (StringUtils.isNotBlank(record.getTransactionId())) { + payOrderSQ.setTransaction_id(record.getTransactionId()); + } else { + payOrderSQ.setOut_trade_no(record.getPayOrderNo()); + } + payOrderSQ.setSign_type("HMAC-SHA256"); + + try { + Map map = BeanUtils.toStringMap(payOrderSQ); + payOrderSQ.setSign(WxPayment.createSignHMAC(map, payAccount.getApiKey())); + map = BeanUtils.toStringMap(payOrderSQ); + + String response = WxPay.orderQuery(map); + return response; + } catch (RuntimeException e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } catch (Exception e) { + throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); + } + } + } +} diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java index 636db98aa..5ae6bca6b 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java @@ -17,6 +17,7 @@ import com.iformall.exception.MallinkException; import com.iformall.mapper.*; import com.iformall.pay.*; import com.iformall.service.*; +import com.iformall.service.helper.WxPayOrderServiceHelper; import com.iformall.utils.*; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -234,11 +235,39 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { if (oldRecord.getPayOrderStatus()==EnumPayStatus.PAY_STATUS_SUCCESS.getCode()) { logger.error("已支付>>>" + order); throw new MallinkException(ErrorCode.PAY_ORDER_EXIST); + //如果是支付中的,则调用微信接口查询支付状态 }else if (oldRecord.getPayOrderStatus()==EnumPayStatus.PAY_STATUS_WAIT.getCode()) { - logger.error("支付中,等待微信同步状态>>>" + order); - throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"订单支付中,等待微信同步状态,防止重复支付!"); - }else { - //如果是其他状态的,可以重复支付,把状态更新为支付中,不再新增订单 + int wxpaystatus = WxPayOrderServiceHelper.wxOrderPayStatus(oldRecord, order, appInfo, payAccount); + if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode()==wxpaystatus) { + oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); + wxPayOrderMapper.updateById(oldRecord); + throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"该订单已经支付,请勿重复支付!"); + }else if (EnumPayStatus.PAY_STATUS_REFUND.getCode()==wxpaystatus) { + oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_REFUND.getCode()); + wxPayOrderMapper.updateById(oldRecord); + throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"该订单已经退款,无法支付!"); + }else if (EnumPayStatus.PAY_STATUS_CLOSE.getCode()==wxpaystatus) { + oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_CLOSE.getCode()); + wxPayOrderMapper.updateById(oldRecord); + throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"该订单已经关闭,无法支付!"); + }else if (EnumPayStatus.PAY_STATUS_REVERSE.getCode()==wxpaystatus) { + oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_REVERSE.getCode()); + wxPayOrderMapper.updateById(oldRecord); + throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"该订单已撤销,无法支付!"); + }else if (EnumPayStatus.PAY_STATUS_WAIT.getCode()==wxpaystatus) { + throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"该订单支付中,请勿重复支付!"); + }else if (EnumPayStatus.PAY_STATUS_FAIL.getCode()==wxpaystatus) { + oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); + oldRecord.setPayOrderNo(String.valueOf(idworker.nextId())); + int sqlRow0 =wxPayOrderMapper.updateById(oldRecord); + if (sqlRow0 != 1) { + logger.error("pay order update error: " + record.toString()); + throw new MallinkException(ErrorCode.DB_FAIL); + } + record = oldRecord; + } + //如果是支付错误,可以重新支付 + }else if(oldRecord.getPayOrderStatus()==EnumPayStatus.PAY_STATUS_FAIL.getCode()) { oldRecord.setPayOrderStatus(EnumPayStatus.PAY_STATUS_WAIT.getCode()); //重新设置支付no oldRecord.setPayOrderNo(String.valueOf(idworker.nextId())); @@ -248,6 +277,8 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { throw new MallinkException(ErrorCode.DB_FAIL); } record = oldRecord; + }else { + throw new MallinkException(ErrorCode.PAY_ORDER_PAYING.getCode(),"该订单状态不允许支付!"); } }else { { @@ -666,65 +697,6 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { } } - - private String wechatPayOrderQuery(WxAppinfo appInfo, WxPayOrder record) { - // get payAccount - WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); - if (payAccount.getType() == EnumPayMode.MCH.getCode()) { - // 普通商户号模式 - WxPayOrderQ payOrderQ = new WxPayOrderQ(); - String noncestr = Utility.generate32UUID(); - payOrderQ.setAppid(appInfo.getAppId()); - payOrderQ.setMch_id(payAccount.getMchId()); - payOrderQ.setNonce_str(noncestr); - if (StringUtils.isNotBlank(record.getTransactionId())) { - payOrderQ.setTransaction_id(record.getTransactionId()); - } else { - payOrderQ.setOut_trade_no(record.getPayOrderNo()); - } - - try { - Map map = BeanUtils.toStringMap(payOrderQ); - payOrderQ.setSign(WxPayment.createSign(map, payAccount.getApiKey())); - map = BeanUtils.toStringMap(payOrderQ); - String response = WxPay.orderQuery(map); - return response; - } catch (RuntimeException e) { - throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); - } catch (Exception e) { - throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); - } - } else { - // 服务商模式 - WxPayOrderSQ payOrderSQ = new WxPayOrderSQ(); - String noncestr = Utility.generate32UUID(); - payOrderSQ.setAppid(appInfo.getParentAppId()); - payOrderSQ.setSub_appid(appInfo.getAppId()); - payOrderSQ.setMch_id(payAccount.getMchId()); - payOrderSQ.setSub_mch_id(payAccount.getSubMchId()); - payOrderSQ.setNonce_str(noncestr); - if (StringUtils.isNotBlank(record.getTransactionId())) { - payOrderSQ.setTransaction_id(record.getTransactionId()); - } else { - payOrderSQ.setOut_trade_no(record.getPayOrderNo()); - } - payOrderSQ.setSign_type("HMAC-SHA256"); - - try { - Map map = BeanUtils.toStringMap(payOrderSQ); - payOrderSQ.setSign(WxPayment.createSignHMAC(map, payAccount.getApiKey())); - map = BeanUtils.toStringMap(payOrderSQ); - - String response = WxPay.orderQuery(map); - return response; - } catch (RuntimeException e) { - throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); - } catch (Exception e) { - throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); - } - } - } - /** * 微信订单查询 */ @@ -750,7 +722,8 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { WxAppinfo appInfo = wxAppinfoService.getCAppInfo(record); - String response = wechatPayOrderQuery(appInfo, record); + WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); + String response = WxPayOrderServiceHelper.wechatPayOrderQuery(appInfo, record,payAccount); logger.info("pay order query, " + record.toString() + ", response: " + response); Map returnMap = WxPayment.xmlToMap(response); @@ -1648,7 +1621,8 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { // 回调未返回,主动检查支付订单状态 try { record.setPayOrderNo(String.valueOf(record.getId())); - String response = wechatPayOrderQuery(appInfo, record); + WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); + String response = WxPayOrderServiceHelper.wechatPayOrderQuery(appInfo, record,payAccount); logger.info("pay order query, " + record.toString() + ", response: " + response); Map returnMap = WxPayment.xmlToMap(response);