From c7f6f17f15bc181ac70d75dcc431e772640e14d9 Mon Sep 17 00:00:00 2001 From: lin <642018748@qq.com> Date: Sun, 21 Aug 2022 00:06:48 +0800 Subject: [PATCH] fix pay v3 --- .../controller/callback/WxPayController.java | 21 +- .../main/java/com/iformall/pay/WxPayV3.java | 14 +- .../impl/WxRefundOrderServiceImpl.java | 6 +- .../appPay/WxMiniAppPayV3AdapterService.java | 8 +- .../refund/RefundPayAdapterService.java | 2 +- .../refund/douyin/TtRefundAdapterService.java | 2 +- .../refund/wx/v2/WxRefundAdapterService.java | 2 +- .../wx/v3/WxRefundV3AdapterService.java | 481 ++++++------------ .../refund/wx/v3/entity/V3PayRefundReq.java | 2 +- 9 files changed, 179 insertions(+), 359 deletions(-) diff --git a/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java b/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java index 2e1ff6e87..0c2e58352 100644 --- a/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java +++ b/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java @@ -197,13 +197,14 @@ public class WxPayController extends BaseController { xml = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8")); logger.info(xml); paramMap = WxPayment.xmlToMap(xml); + paramMap.put("tenantId", tenantId); String jsonMsg = JSON.toJSONString(paramMap); FmInsideNotifyRefundSuccessMsg refundSuccessMsg = new FmInsideNotifyRefundSuccessMsg(); refundSuccessMsg.setMsgType(EnumMsgRecordType.INSIDE_NOTIFY_REFUND_SUCCESS.getCode()); refundSuccessMsg.setDelayTimeLevel(3); refundSuccessMsg.setPayWay(EnumPayWay.PAY_WAY_WECHAT.getCode()); - refundSuccessMsg.setPayVersion(EnumPayVersion.WX_PAY_V2.getCode()); + refundSuccessMsg.setPayVersion(EnumPayVersion.WX_PAY_V3.getCode()); refundSuccessMsg.setJsonMsg(jsonMsg); // response = wxRefundOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP); @@ -214,21 +215,21 @@ public class WxPayController extends BaseController { } catch (BizMessageException e) { logger.error("refund wxpay, notify error, req: " + xml + ", e:" + e.getLocalizedMessage()); SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", e.getMessage()); - return XmlUtil.getRequestXml(resultMap); + resultMap.put("code", "FAIL"); + resultMap.put("message", e.getMessage()); + return JSON.toJSONString(resultMap); } catch (MallinkException e) { logger.error("refund wxpay, notify error, req: " + xml + ", e:" +e.getLocalizedMessage()); SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", e.getMessage()); - return XmlUtil.getRequestXml(resultMap); + resultMap.put("code", "FAIL"); + resultMap.put("message", e.getMessage()); + return JSON.toJSONString(resultMap); } catch (Exception e) { logger.error("refund wxpay, order create error, req: " + xml + ", e: " + e.getMessage()); SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", e.getMessage()); - return XmlUtil.getRequestXml(resultMap); + resultMap.put("code", "FAIL"); + resultMap.put("message", e.getMessage()); + return JSON.toJSONString(resultMap); } } diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java b/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java index f542dafe7..e1c701a6f 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java @@ -56,7 +56,10 @@ public class WxPayV3 { //小程序下单-分账-查询 private static final String SHARE_QUERY_URL = "https://api.mch.weixin.qq.com/v3/profitsharing/orders/%s"; //小程序下单-普通支付-退款 - private static final String PAY_COMMON_REFUND = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"; + private static final String PAY_COMMON_REFUND_URL = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"; + //小程序下单-普通支付-退款查询 + private static final String PAY_COMMON_REFUND_QUERY_URL = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/%s"; + private WxPayV3() { @@ -197,8 +200,15 @@ public class WxPayV3 { * @throws WxPayException */ public static String payCommonRefund(WxPayService payService,V3PayRefundReq req) throws WxPayException { - return payService.postV3WithWechatpaySerial(PAY_COMMON_REFUND, JSON.toJSONString(req)); + return payService.postV3WithWechatpaySerial(PAY_COMMON_REFUND_URL, JSON.toJSONString(req)); } + /** + * 普通支付-退款查询 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_10.shtml + * @throws WxPayException + */ + public static String payCommonRefundQuery(WxPayService payService,String outRefundNo) throws WxPayException { + return payService.postV3WithWechatpaySerial(String.format(PAY_COMMON_REFUND_QUERY_URL, outRefundNo), null); + } } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java index e1df8b1ef..debaede09 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java @@ -350,7 +350,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { throw new MallinkException(ErrorCode.DB_FAIL); } - RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, payType); + RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder,updWxOrder.getId(), payType); if (refundResult.isSuccess()) { record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); wxRefundOrderMapper.updateById(record); @@ -554,7 +554,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { if (null == payAccount) { throw new MallinkException(ErrorCode.PAY_ORDER_QUERY_ERROR.getCode(), "payAccount为空[payId:"+appInfo.getPayId()+"]"); } - RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, payType); + RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, wxOrder.getId(),payType); if (refundResult.isSuccess()) { record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); wxRefundOrderMapper.updateById(record); @@ -776,7 +776,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { logger.error("退款订单已存在, 无法再提交退款申请"); throw new MallinkException(ErrorCode.REFUND_ORDER_EXIST.getCode(), "退款订单已存在, 无法再提交退款申请"); } - RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, null); + RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder,orderId, null); if (refundResult.isSuccess()) { record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); wxRefundOrderMapper.updateById(record); diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java index a667294c3..5a27a6383 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java @@ -83,7 +83,7 @@ public class WxMiniAppPayV3AdapterService extends BaseWxPayV3AdapterService impl throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前支付模式非法"); } req.setDescription(appInfo.getName()+"-"+productName); - req.setOut_trade_no(String.valueOf(composeOrder.getMainOrderId())); + req.setOut_trade_no(record.getPayOrderNo()); req.setNotify_url(payAccount.getPayNotifyV3Url()); V3PaySettleReq settle = new V3PaySettleReq(); @@ -128,7 +128,7 @@ public class WxMiniAppPayV3AdapterService extends BaseWxPayV3AdapterService impl V3CombinePayCommonMiniAppReq req = new V3CombinePayCommonMiniAppReq(); req.setCombine_appid(appInfo.getAppId()); req.setCombine_mchid(payAccount.getMchId()); - req.setCombine_out_trade_no(String.valueOf(composeOrder.getMainOrderId())); + req.setCombine_out_trade_no(record.getPayOrderNo()); if (payAccount.getMchType() != EnumPayMchType.TOTAL.getCode() && payAccount.getMchType() != EnumPayMchType.DIRECT.getCode()) { throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前支付模式非法"); } @@ -238,7 +238,7 @@ public class WxMiniAppPayV3AdapterService extends BaseWxPayV3AdapterService impl if (!oldRecord.isMulity()) { req.setSp_mchid(payAccount.getMchId()); req.setSub_mchid(oldRecord.getSingleChildOrderShare().getMerchantUid()); - req.setOut_trade_no(String.valueOf(oldRecord.getId())); + req.setOut_trade_no(oldRecord.getPayOrderNo()); String response = WxPayV3.payCommonQuery(payService, req); if (StringUtils.isBlank(response)){ log.error("pay common v3 query response is null."+JSON.toJSONString(req)); @@ -275,7 +275,7 @@ public class WxMiniAppPayV3AdapterService extends BaseWxPayV3AdapterService impl SFTPayQueryReq req = new SFTPayQueryReq(); req.setSp_mchid(payAccount.getMchId()); req.setSub_mchid(record.getSingleChildOrderShare().getMerchantUid()); - req.setOut_trade_no(String.valueOf(record.getId())); + req.setOut_trade_no(record.getPayOrderNo()); WxPayV3SFT.payCommonClose(payService, req); return new PayAdapterResult(true, "close success", req, null); }else { diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java index 5c748f6f3..7bb406a50 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java @@ -22,7 +22,7 @@ public interface RefundPayAdapterService { * @param payType * @return */ - public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType); + public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType); /** * API查询退款 diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java index a8eaaa712..265e06759 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java @@ -47,7 +47,7 @@ public class TtRefundAdapterService implements RefundPayAdapterService{ WxOrderService wxOrderService; @Override - public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) { + public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) { try { TtPayService ttPayService = maUtil.getTtPayService(appInfo, payAccount); diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v2/WxRefundAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v2/WxRefundAdapterService.java index 1f87ec534..42de289d5 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v2/WxRefundAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v2/WxRefundAdapterService.java @@ -343,7 +343,7 @@ public class WxRefundAdapterService implements RefundPayAdapterService{ } @Override - public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) { + public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) { if (StringUtils.isBlank(payAccount.getApiKey())) { log.error("支付密钥为空"); throw new MallinkException(ErrorCode.API_KEY_NOT_FOUND.getCode(), "支付密钥为空,请联系商城管理员"); diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/WxRefundV3AdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/WxRefundV3AdapterService.java index f980482b6..dbf66b0dd 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/WxRefundV3AdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/WxRefundV3AdapterService.java @@ -1,5 +1,6 @@ package com.iformall.service.pay.service.refund.wx.v3; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.SortedMap; @@ -7,6 +8,7 @@ import java.util.TreeMap; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON; @@ -16,6 +18,7 @@ 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.WxOrder; import com.iformall.domain.po.WxPayAccount; import com.iformall.domain.po.WxPayOrder; import com.iformall.domain.po.WxRefundOrder; @@ -34,9 +37,14 @@ import com.iformall.pay.WxPayV3; import com.iformall.pay.WxPayment; import com.iformall.pay.WxRefundOrderP; import com.iformall.pay.WxRefundOrderSP; +import com.iformall.service.WxOrderService; +import com.iformall.service.WxPayAccountService; +import com.iformall.service.order.entity.WxComposeChildOrderShare; import com.iformall.service.pay.service.refund.RefundPayAdapterService; import com.iformall.service.pay.service.refund.entity.RefundAdapterResult; import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult; +import com.iformall.service.pay.service.refund.wx.v3.entity.V3PayRefundAmountReq; +import com.iformall.service.pay.service.refund.wx.v3.entity.V3PayRefundGoodsReq; import com.iformall.service.pay.service.refund.wx.v3.entity.V3PayRefundReq; import com.iformall.utils.BeanUtils; import com.iformall.utils.CipherUtil; @@ -54,206 +62,100 @@ public class WxRefundV3AdapterService implements RefundPayAdapterService{ @Autowired MaUtil maUtil; - private RefundAdapterResult getReusltFromp(String response,WxRefundOrder record,WxPayOrder payOrder) throws MallinkException{ - Map returnMap = WxPayment.xmlToMap(response); - String result_no = returnMap.get("result_code"); - String refund_id = returnMap.get("refund_id"); - // 设置 微信退款订单号 - record.setRefundId(refund_id); - record.setRefundVendor(payOrder.getPayVendor()); - if ("SUCCESS".equals(result_no)) { - log.info("微信退款订单申请成功: " + returnMap.toString()); - try { - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款订单申请成功",returnMap); - } catch (Exception e) { - log.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); - } - } else { - String errDesc = returnMap.get("err_code_des"); - if (errDesc.equalsIgnoreCase("订单已全额退款")) { - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款订单申请成功",returnMap); - } - log.error("微信退款订单申请失败: " + response); - String errMsg = ""; - JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); - if (errObj != null) { - errMsg = errObj.toJSONString(); - record.setFailReason(errMsg); - } else { - errMsg = returnMap.get("return_msg"); - record.setFailReason(errMsg); - } - if (errDesc.equalsIgnoreCase("超期订单不允许退款")) { - // 更新券状态 - throw new MallinkException(ErrorCode.REFUND_NOT_ALLOW); - } - return new RefundAdapterResult(false, EnumRefundStatus.REFUND_REQ_FAIL.getCode(), errMsg, returnMap); - } - } - - - private RefundAdapterResult getResultFromSp(String response,WxRefundOrder record,WxPayOrder payOrder) { - Map returnMap = WxPayment.xmlToMap(response); - String result_no = returnMap.get("result_code"); - String refund_id = returnMap.get("refund_id"); - // 设置 微信退款订单号 - record.setRefundId(refund_id); - record.setRefundVendor(payOrder.getPayVendor()); - if ("SUCCESS".equals(result_no)) { - log.info("微信退款订单申请成功: " + returnMap.toString()); - try { - return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", returnMap); - } catch (Exception e) { - log.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "订单状态更新失败"); - } - } else { - // 特殊处理 - String errDesc = returnMap.get("err_code_des"); - if (errDesc.equalsIgnoreCase("订单已全额退款")) { - return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", returnMap); - } - log.error("微信退款订单申请失败: " + response); - String errMsg = ""; - JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); - if (errObj != null) { - errMsg = errObj.toJSONString(); - record.setFailReason(errMsg); - } else { - errMsg = returnMap.get("err_code_des"); - record.setFailReason(errMsg); - } - if (errDesc.equalsIgnoreCase("超期订单不允许退款")) { - // 更新券状态 - throw new MallinkException(ErrorCode.REFUND_NOT_ALLOW); - } - return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),errMsg,returnMap); - } - } - private V3PayRefundReq getReq(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) { + @Lazy + @Autowired + WxOrderService wxOrderService; + + @Lazy + @Autowired + WxPayAccountService wxPayAccountService; + + private V3PayRefundReq getReq(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) { V3PayRefundReq req = new V3PayRefundReq(); if (payAccount.getMchType() == EnumPayMchType.DIRECT.getCode()) { - req.setSub_mchid(getMerchantUid(record,composeOrder.getSingleOrder())); + WxComposeChildOrderShare share = payOrder.getChildOrderShare(orderId); + req.setSub_mchid(share.getMerchantUid()); //总分 }else if (payAccount.getMchType() == EnumPayMchType.TOTAL.getCode()) { req.setSub_mchid(payAccount.getSubMchId()); }else { throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前支付模式非法"); } - req.setSub_mchid(sub_mchid); + req.setOut_trade_no(payOrder.getPayOrderNo()); + req.setOut_refund_no(String.valueOf(record.getId())); + req.setReason(payType.getMessage()); + req.setNotify_url(payAccount.getRefundNotifyV3Url()); + V3PayRefundAmountReq amount = new V3PayRefundAmountReq(); + amount.setRefund(record.getRefundFee()); + amount.setTotal(record.getTotalFee()); + req.setAmount(amount); + List goods = new ArrayList(); + WxOrder order = wxOrderService.getById(orderId, payAccount.getTenantId()); + V3PayRefundGoodsReq gr = new V3PayRefundGoodsReq(); + gr.setGoods_name("商品"+order.getProductId()); + gr.setMerchant_goods_id(order.getProductId().toString()); + gr.setRefund_amount(record.getRefundFee()); + gr.setRefund_quantity(order.getCouponNumber()); + goods.add(gr); + req.setGoods_detail(goods); + return req; + } + + private RefundAdapterResult getResultFromSp(String response,WxRefundOrder record,WxPayOrder payOrder) { + JSONObject result = JSON.parseObject(response); + // 设置 微信退款订单号 + record.setRefundId(result.getString("refund_id")); + record.setRefundVendor(payOrder.getPayVendor()); + return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单成功", result); } + @Override - public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) { + public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) { // 向微信提交退款申请 if (payAccount.getType() == EnumPayMode.MCH.getCode()) { - } else { - // 服务商模式 - WxPayService payService = maUtil.getWxPayService(appInfo, payAccount); - String response = null; - try { - response = WxPayV3.payCommonRefund(payService, getReq(payAccount, appInfo, record, payOrder, payType)); - } catch (Exception e) { - log.error("退款异常: " + e.getMessage()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); - } - log.info("微信退款订单:" + wxRefundOrderSP.toString() + ", response: " + response.toString()); - return getResultFromSp(response, record, payOrder); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "当前只支持服务商模式"); } + // 服务商模式 + WxPayService payService = maUtil.getWxPayService(appInfo, payAccount); + String response = null; + try { + //合单和普通一样 + if (!payOrder.isMulity()) { + response = WxPayV3.payCommonRefund(payService, getReq(payAccount, appInfo, record, payOrder,orderId, payType)); + }else { + response = WxPayV3.payCommonRefund(payService, getReq(payAccount, appInfo, record, payOrder,orderId, payType)); + } + } catch (Exception e) { + log.error("退款异常: " + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); + } + return getResultFromSp(response, record, payOrder); } @Override public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record) { - if (payAccount.getType() == EnumPayMode.MCH.getCode()) { - Map paramMap = WxPayment.buildWeappRefundQueryMap( - appInfo.getAppId(), payAccount.getMchId(), - record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()), - record.getRefundId(), payAccount.getApiKey()); - String response = WxPay.orderRefundQuery(paramMap); - log.info("微信退款订单:" + record.toString() + ", response: " + response.toString()); - Map returnMap = WxPayment.xmlToMap(response); - String return_code = returnMap.get("return_code"); - if("SUCCESS".equals(return_code)){ - String result_code = returnMap.get("result_code"); - if("SUCCESS".equals(result_code)){ - String refund_status_0 = returnMap.get("refund_status_0"); - if("SUCCESS".equals(refund_status_0)){ - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_SUCCESS.getCode(),"退款成功",returnMap); - }else if("REFUNDCLOSE".equals(refund_status_0)){ - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款关闭,指商户发起退款失败的情况",returnMap); - }else if("PROCESSING".equals(refund_status_0)){ - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款中",returnMap); - }else if("CHANGE".equals(refund_status_0)){ - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(), - "退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败。",returnMap); - }else{ - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 非法状态"); - } - }else{ - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("err_code_des")); - } - }else{ - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("return_msg")); - } - -// String result_no = returnMap.get("result_code"); -// if ("SUCCESS".equals(result_no)) { -// String refund_id = returnMap.get("refund_id"); -// return new RefundAdapterResult(true,0,"退款",returnMap); -// } else { -// String errMsg = ""; -// JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); -// if (errObj != null) { -// errMsg = errObj.toJSONString(); -// } else { -// errMsg = returnMap.get("return_msg"); -// } -// return new RefundAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),errMsg,returnMap); -// } - } else { - Map paramMap = WxPayment.buildSWeappRefundQueryMap( - appInfo.getParentAppId(), appInfo.getAppId(), payAccount.getMchId(), payAccount.getSubMchId(), - record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()), record.getRefundId(), payAccount.getApiKey()); - String response = WxPay.orderRefundQuery(paramMap); - log.info("微信退款订单:" + record.toString() + ", response: " + response.toString()); - Map returnMap = WxPayment.xmlToMap(response); - String return_code = returnMap.get("return_code"); - if("SUCCESS".equals(return_code)){ - String result_code = returnMap.get("result_code"); - if("SUCCESS".equals(result_code)){ - String refund_status_0 = returnMap.get("refund_status_0"); - if("SUCCESS".equals(refund_status_0)){ - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_SUCCESS.getCode(),"退款成功",returnMap); - }else if("REFUNDCLOSE".equals(refund_status_0)){ - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款关闭,指商户发起退款失败的情况",returnMap); - }else if("PROCESSING".equals(refund_status_0)){ - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款中",returnMap); - }else if("CHANGE".equals(refund_status_0)){ - return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款异常",returnMap); - }else{ - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 非法状态"); - } - }else{ - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("err_code_des")); - } + // 服务商模式 + WxPayService payService = maUtil.getWxPayService(appInfo, payAccount); + String response = null; + try { + response = WxPayV3.payCommonRefundQuery(payService, String.valueOf(record.getId())); + JSONObject result = JSON.parseObject(response); + String refund_status_0 = result.getString("status"); + if("SUCCESS".equals(refund_status_0)){ + return new RefundAdapterResult(true,EnumRefundStatus.REFUND_SUCCESS.getCode(),"退款成功",result); + }else if("CLOSED".equals(refund_status_0)){ + return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款关闭,指商户发起退款失败的情况",result); + }else if("PROCESSING".equals(refund_status_0)){ + return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款中",result); + }else if("ABNORMAL".equals(refund_status_0)){ + return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(), + "退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败。",result); }else{ - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("return_msg")); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 非法状态"); } - -// String result_no = returnMap.get("result_code"); -// if ("SUCCESS".equals(result_no)) { -// String refund_id = returnMap.get("refund_id"); -// return new RefundAdapterResult(true,0,"退款",returnMap); -// } else { -// String errMsg = ""; -// JSONObject errObj = errorRefundQueryMap.getJSONObject(result_no); -// if (errObj != null) { -// errMsg = errObj.toJSONString(); -// } else { -// errMsg = returnMap.get("return_msg"); -// } -// return new RefundAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),errMsg,returnMap); -// } + } catch (Exception e) { + log.error("退款异常: " + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); } } @@ -269,171 +171,78 @@ public class WxRefundV3AdapterService implements RefundPayAdapterService{ private RefundNotifyAdapterResult notifyErrorResult(String msg) { SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "FAIL"); - resultMap.put("return_msg", msg); - return new RefundNotifyAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),msg,XmlUtil.getRequestXml(resultMap)); + resultMap.put("code", "FAIL"); + resultMap.put("message", msg); + return new RefundNotifyAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),msg,JSON.toJSONString(resultMap)); } private RefundNotifyAdapterResult notifySuccessResult(String transactionId,String refundId,WxRefundOrder refundOrder) { SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "SUCCESS"); - resultMap.put("return_msg", "OK"); - return new RefundNotifyAdapterResult(transactionId, refundId,refundOrder,XmlUtil.getRequestXml(resultMap)); + resultMap.put("code", "SUCCESS"); + resultMap.put("message", "OK"); + return new RefundNotifyAdapterResult(transactionId, refundId,refundOrder,JSON.toJSONString(resultMap)); } @Override public RefundNotifyAdapterResult notify(Map paramMap, EnumPayWay payWay) { - // how to get wechatAppId, wechatMchId, partnerKey - String appId = paramMap.get("appid"); - String subAppId = paramMap.get("sub_appid"); - String mchId = paramMap.get("mch_id"); - String subMchId = paramMap.get("sub_mch_id"); - if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) { - // 普通商户号 - WxAppinfo appinfo = wxAppinfoMapper.findByAppId(appId); - if (appinfo == null) { - log.error("未找到appid信息:" + appId); - throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); - } - WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId()); - if (payAccount == null) { - log.error("未找到mch_id信息:" + mchId); - throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); - } - if (!mchId.equalsIgnoreCase(payAccount.getMchId())) { - log.error("mch_id不对应:" + mchId + ",account:" + payAccount.getMchId()); - throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL); - } - String partnerKey = payAccount.getApiKey(); - try { - if (payWay.getType() == EnumPayWay.EnumPayWayType.WX_MINIPAY) { - if (!"SUCCESS".equals(paramMap.get("return_code"))) { - log.warn("notify refund, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("订单状态码非SUCCESS"); - } - - // 解密req_info - String req_info = CipherUtil.decryptReqInfo(paramMap.get("req_info"), partnerKey); - Map reqMap = WxPayment.xmlToMap(req_info); - - String payOrderNo = reqMap.get("out_trade_no"); - Long payOrderId = Long.valueOf(payOrderNo); - WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,payAccount.getTenantId()); - if (payOrder == null) { - log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("支付订单不存在"); - } - // 验证支付金额 - if (!reqMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { - log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("支付订单总金额不一致"); - } - String refundIdStr = reqMap.get("out_refund_no"); - Long refundOrderId = Long.valueOf(refundIdStr); - WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId); - if (refundOrder == null) { - log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("退款订单不存在"); - } - // 验证支付金额 - if (!reqMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) { - log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("订单总金额不一致"); - } - // 验证退款金额 - if (!reqMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) { - log.warn("notify refund, wxpay check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("退款总金额不一致"); - } - - // 处理支付成功 - //handleRefundSuccess(refundOrder, reqMap.get("transaction_id"), reqMap.get("refund_id")); - log.info("notify refund, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), refundOrder); - } - } catch (RuntimeException e) { - log.warn("notify refund paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage()); - } catch (Exception e) { - log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage()); - } - } else { - // 服务号回调 - WxAppinfo appinfo = wxAppinfoMapper.findByAppId(subAppId); - if (appinfo == null) { - log.error("未找到appid信息:" + appId); - throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); - } - WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId()); - if (payAccount == null) { - log.error("未找到mch_id信息:" + mchId); - throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); - } - if (!mchId.equalsIgnoreCase(payAccount.getMchId())) { - log.error("mch_id不对应:" + mchId + ",account:" + payAccount.getMchId()); - throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL); - } - String partnerKey = payAccount.getApiKey(); - try { - if (payWay.getType() == EnumPayWay.EnumPayWayType.WX_MINIPAY) { - if (!"SUCCESS".equals(paramMap.get("return_code"))) { - log.warn("notify order, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("订单状态码非SUCCESS"); - } - - // 解密req_info - String req_info = CipherUtil.decryptReqInfo(paramMap.get("req_info"), partnerKey); - log.info(req_info); - Map reqMap = WxPayment.xmlToMap(req_info); - - String payOrderNo = reqMap.get("out_trade_no"); - if (payOrderNo == null) { - return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), null); - } - Long payOrderId = Long.valueOf(payOrderNo); - WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,payAccount.getTenantId()); - if (payOrder == null) { - log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("支付订单不存在"); - } - // 验证支付金额 - if (!reqMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { - log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("支付订单总金额不一致"); - } - String refundIdStr = reqMap.get("out_refund_no"); - Long refundOrderId = Long.valueOf(refundIdStr); - WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId); - if (refundOrder == null) { - log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("退款订单不存在"); - } - // 验证支付金额 - if (!reqMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) { - log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("订单总金额不一致"); - } - // 验证退款金额 - if (!reqMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) { - log.warn("notify refund, wxpay check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); - return notifyErrorResult("退款总金额不一致"); - } - - log.info("notify refund, wxpay checksign success, paramMap:{}, paramMap: " + reqMap.toString() + ", payWay:" + payWay.toString()); - return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), refundOrder); - } - } catch (RuntimeException e) { - log.warn("notify refund, wepay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); - } catch (Exception e) { - log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage()); - } + String tenantId = paramMap.get("tenantId"); + String resource = paramMap.get("resource"); + JSONObject reObj = JSON.parseObject(resource); + WxPayService wxPayService = wxPayAccountService.getWxPayService(tenantId); + try { + String decryptContent = WxPayV3.decrypt(wxPayService, reObj.getString("ciphertext"), reObj.getString("nonce"), reObj.getString("associated_data")); + JSONObject decryptObj = JSON.parseObject(decryptContent); + String spMchId = decryptObj.getString("sp_mchid"); + String subMchId = decryptObj.getString("sub_mchid"); + String transactionId = decryptObj.getString("transaction_id"); + String outTradeNo = decryptObj.getString("out_trade_no"); + String refundId = decryptObj.getString("refund_id"); + String outRefundNo = decryptObj.getString("out_refund_no"); + String refundStatus = decryptObj.getString("refund_status"); + String successTime = decryptObj.getString("success_time"); + String userReceivedAccount = decryptObj.getString("user_received_account"); + JSONObject rObj = decryptObj.getJSONObject("amount"); + int total = rObj.getIntValue("total"); + int refund = rObj.getIntValue("refund"); + int payerTotal = rObj.getIntValue("payer_total"); + int payerRefund = rObj.getIntValue("payer_refund"); + + Long payOrderId = Long.valueOf(outTradeNo); + WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,tenantId); + if (payOrder == null) { + log.warn("notify refund, wxpay v3 check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); + return notifyErrorResult("支付订单不存在"); + } + // 验证支付金额 + if (payerTotal != payOrder.getPayAmount().intValue()) { + log.warn("notify refund, wxpay v3 check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); + return notifyErrorResult("支付订单总金额不一致"); + } + Long refundOrderId = Long.valueOf(outRefundNo); + WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId); + if (refundOrder == null) { + log.warn("notify refund, wxpay v3 check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); + return notifyErrorResult("退款订单不存在"); + } + // 验证支付金额 + if (payerTotal != refundOrder.getTotalFee().intValue()) { + log.warn("notify refund, wxpay v3 check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); + return notifyErrorResult("订单总金额不一致"); + } + // 验证退款金额 + if (payerRefund != refundOrder.getRefundFee().intValue()) { + log.warn("notify refund, wxpay v3 check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); + return notifyErrorResult("退款总金额不一致"); + } + return notifySuccessResult(transactionId, refundId, refundOrder); + } catch (RuntimeException e) { + log.warn("notify refund paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage()); + } catch (Exception e) { + log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage()); } - - return notifyErrorResult("FAILED"); } } diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/entity/V3PayRefundReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/entity/V3PayRefundReq.java index cea352411..99cac55b3 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/entity/V3PayRefundReq.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/entity/V3PayRefundReq.java @@ -8,7 +8,7 @@ import lombok.Data; public class V3PayRefundReq { private String sub_mchid;//微信支付分配的子商户号,即分账的出资商户号。 - private String out_trade_no;//微信支付订单号 + private String out_trade_no;//原支付交易对应的商户订单号 private String out_refund_no;//商户退款单号 private String reason;//退款原因 private String notify_url;//退款结果回调url