修改退款申请封装

This commit is contained in:
gong
2026-01-15 13:32:55 +08:00
parent ee25493570
commit 98dfda0bca
20 changed files with 361 additions and 136 deletions

View File

@@ -18,6 +18,7 @@ import com.czg.order.entity.OrderInfo;
import com.czg.order.entity.OrderPayment;
import com.czg.order.service.OrderInfoCustomService;
import com.czg.order.service.OrderPaymentService;
import com.czg.pay.PayNotifyRespDTO;
import com.czg.service.market.service.impl.AppWxServiceImpl;
import com.czg.third.wechat.WechatReqUtils;
import com.czg.utils.AssertUtil;
@@ -75,6 +76,8 @@ public class NotifyController {
log.info("【微信支付回调】解密数据 {}", decrypted);
WechatPayNotifyDataDto dataDto = JSONObject.parseObject(decrypted, WechatPayNotifyDataDto.class);
PayNotifyRespDTO respDTO = dataDto.convertToPayNotifyRespDTO();
orderInfoCustomService.payCallBackOrder(respDTO.getMchOrderNo(), respDTO, 0);
return "success";
} else if (PayCst.Platform.ALIPAY.equalsIgnoreCase(platform)) {
// 支付宝
@@ -106,10 +109,10 @@ public class NotifyController {
@RequestMapping("/payCallBack")
public String notifyCallBack(@RequestBody PolyBaseResp respParams) {
JSONObject czg = PolyPayUtils.getCzg(respParams);
AssertUtil.isNull(czg, "支付回调数据为空");
log.info("支付回调数据为:{}", czg);
orderInfoCustomService.payCallBackOrder(czg.getString("mchOrderNo"), czg, 0);
PayNotifyRespDTO respDTO = PolyPayUtils.getNotifyResp(respParams);
AssertUtil.isNull(respDTO, "支付回调数据为空");
log.info("支付回调数据为:{}", respDTO);
orderInfoCustomService.payCallBackOrder(respDTO.getMchOrderNo(), respDTO, 0);
return SUCCESS;
}

View File

@@ -151,10 +151,11 @@ public class OrderPayment implements Serializable {
}
public static OrderPayment refund(@NonNull Long shopId, @NonNull Long sourceId, @NotBlank String sourceType,
@NotBlank String orderNo, @NonNull BigDecimal amount, Long relatedId) {
@NotBlank String orderNo, @NonNull BigDecimal amount, Long relatedId, String platformType) {
OrderPayment orderPayment = getInstance(shopId, sourceId, sourceType, orderNo, amount, null, relatedId);
orderPayment.setPayType(PayTypeConstants.PayType.REFUND);
orderPayment.setPayStatus(PayTypeConstants.PayStatus.INIT);
orderPayment.setPlatformType(platformType);
return orderPayment;
}

View File

@@ -12,9 +12,9 @@ import com.czg.order.enums.PayEnums;
import com.czg.order.vo.HistoryOrderPrintVo;
import com.czg.order.vo.HistoryOrderVo;
import com.czg.order.vo.OrderInfoVo;
import com.czg.pay.PayNotifyRespDTO;
import com.czg.resp.CzgResult;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import jakarta.validation.constraints.NotBlank;
import org.jetbrains.annotations.NotNull;
@@ -44,7 +44,7 @@ public interface OrderInfoCustomService {
CzgResult<Object> mergeOrder(MergeOrderDTO param);
void payCallBackOrder(@NotBlank String orderNo, @NotNull JSONObject resultJson, int retryCount);
void payCallBackOrder(@NotBlank String orderNo, @NotNull PayNotifyRespDTO notifyRespDTO, int retryCount);
void refundCallBackOrder(@NotBlank String orderNo, @NotNull JSONObject resultJson);

View File

@@ -50,16 +50,22 @@ public class CzgRefundReq {
*/
private String notifyUrl;
/**
* 支付平台
*/
private String platform;
/**
* payOrderId和mchOrderNo 二选一 必填
*/
public CzgRefundReq(@NonNull String mchRefundNo, @NonNull String refundReason, @NonNull Long refundAmount,
@NonNull Long orderTotalAmount, String mchOrderNo, String extParam) {
@NonNull Long orderTotalAmount, String mchOrderNo, String extParam, String platform) {
this.mchRefundNo = mchRefundNo;
this.refundReason = refundReason;
this.refundAmount = refundAmount;
this.orderTotalAmount = orderTotalAmount;
this.mchOrderNo = mchOrderNo;
this.extParam = extParam;
this.platform = platform;
}
}

View File

@@ -0,0 +1,67 @@
package com.czg.pay;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 统一支付回调响应数据
* @author yjjie
* @date 2026/1/15 09:16
*/
@Data
@Accessors(chain = true)
public class PayNotifyRespDTO {
/**
* 商户订单号
*/
private String mchOrderNo;
/**
* 三方订单号
*/
private String thirdOrderNo;
/**
* 订单状态
* INIT - 订单初始化;
* TRADE_AWAIT - 待支付;
* TRADE_SUCCESS - 支付成功;
* TRADE_FAIL -支付失败;
* TRADE_CANCEL -交易取消;
* TRADE_REFUND -已退款;
* REFUND_ING - 退款中;
* TRADE_CLOSE -订单关闭
*/
private String status;
/**
* 支付平台
*/
private String platform;
/**
* 订单金额 分
*/
private Long amount;
/**
* 扩展数据
*/
private String extData;
/**
* 支付成功时间
*/
private String paySuccessTime;
/**
* 错误信息
*/
private String errorMsg;
/**
* 回调原始数据
*/
private String originalData;
}

View File

@@ -0,0 +1,59 @@
package com.czg.pay;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 退款相应数据
* @author yjjie
* @date 2026/1/15 11:00
*/
@Data
@Accessors(chain = true)
public class RefundRespDTO {
/**
* 退款状态
* INIT初始化
* ING退款中
* SUCCESS退款成功
* FAIL退款失败
* CLOSE退款关闭
*/
private String status;
/**
* 退款金额
*/
private Long refundAmount;
/**
* 退款时间
*/
private String refundTime;
/**
* 三方退款订单号
*/
private String thirdRefundNo;
/**
* 商户退款订单号
*/
private String merchantRefundNo;
/**
* 退款失败原因
*/
private String errMessage;
/**
* 退款相应原始数据
*/
private String originalData;
/**
* 退款平台
*/
private String platform;
}

View File

@@ -59,4 +59,8 @@ public class CzgResult<T> implements Serializable {
public static <T> CzgResult<T> failure(CzgRespCode respCode) {
return new CzgResult<>(respCode.getCode(), respCode.getMsg(), null);
}
public boolean isSuccess() {
return code == 200;
}
}

View File

@@ -1,10 +1,11 @@
package com.czg;
import com.czg.constants.SystemConstants;
import com.czg.dto.req.RefundParamsDto;
import com.czg.exception.CzgException;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.NativeMerchantDTO;
import com.czg.pay.RefundRespDTO;
import com.czg.third.alipay.AlipayIsvPayManager;
import com.czg.third.wechat.WechatPayManager;
@@ -64,11 +65,11 @@ public class PayManager {
/**
* 退款
*/
public static Map<String, Object> refund(String platform, RefundParamsDto paramsDto) {
if (SystemConstants.PayType.WECHAT.equals(platform)) {
return WechatPayManager.refundOrder(null, paramsDto);
} else if (SystemConstants.PayType.ALIPAY.equals(platform)) {
return AlipayIsvPayManager.refundOrder(null, paramsDto);
public static RefundRespDTO refund(CzgRefundReq paramsDto, String notifyUrl, NativeMerchantDTO merchantDTO) {
if (PayCst.Platform.WECHAT.equals(paramsDto.getPlatform())) {
return WechatPayManager.refundOrder(null, paramsDto, notifyUrl, merchantDTO);
} else if (PayCst.Platform.ALIPAY.equals(paramsDto.getPlatform())) {
return AlipayIsvPayManager.refundOrder(null, paramsDto, notifyUrl, merchantDTO);
} else {
throw new CzgException("不支持的支付平台");
}

View File

@@ -1,6 +1,8 @@
package com.czg.dto.req;
import com.alibaba.fastjson2.annotation.JSONField;
import com.czg.PayCst;
import com.czg.pay.PayNotifyRespDTO;
import lombok.Data;
/**
@@ -115,4 +117,35 @@ public class WechatPayNotifyDataDto {
public Long getPayAmount() {
return Long.valueOf(amount.getTotal());
}
public PayNotifyRespDTO convertToPayNotifyRespDTO() {
PayNotifyRespDTO respDTO = new PayNotifyRespDTO()
.setMchOrderNo(outTradeNo)
.setThirdOrderNo(transactionId)
.setAmount(getPayAmount())
.setPlatform(PayCst.Platform.WECHAT)
.setExtData(attach)
.setPaySuccessTime(successTime)
.setErrorMsg(tradeStateDesc);
switch (tradeState) {
case "SUCCESS":
respDTO.setStatus("TRADE_SUCCESS");
break;
case "CLOSED":
respDTO.setStatus("TRADE_CLOSE");
break;
case "USERPAYING":
respDTO.setStatus("TRADE_AWAIT");
break;
case "NOTPAY":
respDTO.setStatus("TRADE_CANCEL");
break;
default:
respDTO.setStatus("TRADE_FAIL");
break;
}
return respDTO;
}
}

View File

@@ -9,10 +9,11 @@ import com.alipay.v3.model.AlipayTradePayModel;
import com.alipay.v3.model.ExtendParams;
import com.alipay.v3.util.model.CustomizedParams;
import com.czg.PayCst;
import com.czg.dto.req.RefundParamsDto;
import com.czg.exception.CzgException;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.NativeMerchantDTO;
import com.czg.pay.RefundRespDTO;
import com.czg.third.alipay.dto.config.AlipayConfigDto;
import lombok.extern.slf4j.Slf4j;
@@ -107,8 +108,8 @@ public class AlipayIsvPayManager {
return new HashMap<>();
}
public static Map<String, Object> refundOrder(AlipayConfigDto configDto, RefundParamsDto paramsDto) {
return new HashMap<>();
public static RefundRespDTO refundOrder(AlipayConfigDto configDto, CzgRefundReq paramsDto, String notifyUrl, NativeMerchantDTO merchantDTO) {
return new RefundRespDTO();
}
/**

View File

@@ -5,10 +5,11 @@ import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.PayCst;
import com.czg.dto.req.RefundParamsDto;
import com.czg.exception.CzgException;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.NativeMerchantDTO;
import com.czg.pay.RefundRespDTO;
import com.czg.third.wechat.dto.config.WechatPayConfigDto;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.cipher.Signer;
@@ -257,64 +258,63 @@ public class WechatPayManager {
* PROCESSING: 退款处理中
* ABNORMAL: 退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往服务商平台-交易中心,手动处理此笔退款
*/
public static Map<String, Object> refundOrder(WechatPayConfigDto configDto, RefundParamsDto paramsDto) {
public static RefundRespDTO refundOrder(WechatPayConfigDto configDto, CzgRefundReq paramsDto, String notifyUrl, NativeMerchantDTO merchantDTO) {
try {
if (configDto == null) {
configDto = WechatPayConfigDto.getDefaultConfig();
}
JSONObject refundParam = new JSONObject();
refundParam.put("sub_mchid", paramsDto.getMerchantId());
refundParam.put("out_trade_no", paramsDto.getOrderNo());
refundParam.put("out_refund_no", paramsDto.getRefundOrderNo());
refundParam.put("sub_mchid", merchantDTO.getWechatMerchantId());
refundParam.put("out_trade_no", paramsDto.getMchOrderNo());
refundParam.put("out_refund_no", paramsDto.getMchRefundNo());
refundParam.put("reason", paramsDto.getRefundReason());
refundParam.put("notify_url", paramsDto.getRefundNotifyUrl() + "/" + PayCst.Platform.WECHAT);
refundParam.put("notify_url", notifyUrl + "/" + PayCst.Platform.WECHAT);
JSONObject amount = new JSONObject();
amount.put("total", paramsDto.getOrderAmount());
amount.put("total", paramsDto.getOrderTotalAmount());
amount.put("refund", paramsDto.getRefundAmount());
amount.put("currency", "CNY");
refundParam.put("amount", amount);
String resp = WechatReqUtils.postReq(configDto, "/v3/refund/domestic/refunds", refundParam.toJSONString());
log.info("微信退款,订单号:{} 响应:{}", paramsDto.getOrderNo(), resp);
log.info("微信退款,订单号:{} 响应:{}", paramsDto.getMchOrderNo(), resp);
JSONObject object = JSONObject.parseObject(resp);
JSONObject res = new JSONObject();
res.put("mchRefundNo", object.getString("out_refund_no"));
res.put("refundOrderId", object.getString("refund_id"));
res.put("oriPayOrderId", object.getString("out_trade_no"));
res.put("mercNo", paramsDto.getMerchantId());
res.put("refundReason", paramsDto.getRefundReason());
res.put("payType", PayCst.Platform.WECHAT);
res.put("refundTime", object.getString("success_time"));
switch (object.getString("status")) {
case "SUCCESS":
res.put("status", "SUCCESS");
break;
case "CLOSED":
res.put("status", "CLOSED");
break;
case "PROCESSING":
res.put("status", "ING");
break;
case "ABNORMAL":
res.put("status", "INIT");
break;
default:
res.put("status", "FAIL");
break;
}
RefundRespDTO respDTO = new RefundRespDTO()
.setMerchantRefundNo(object.getString("out_refund_no"))
.setThirdRefundNo(object.getString("refund_id"))
.setRefundTime(object.getString("success_time"))
.setOriginalData(resp)
.setPlatform(PayCst.Platform.WECHAT);
JSONObject resAmount = object.getJSONObject("amount");
if (resAmount != null) {
res.put("refundAmt", resAmount.getLong("refund"));
res.put("oriAmount", resAmount.getLong("total"));
respDTO.setRefundAmount(resAmount.getLong("refund"));
}
return res;
switch (object.getString("status")) {
case "SUCCESS":
respDTO.setStatus("SUCCESS");
break;
case "CLOSED":
respDTO.setStatus("CLOSED");
break;
case "PROCESSING":
respDTO.setStatus("ING");
break;
case "ABNORMAL":
respDTO.setStatus("INIT");
break;
default:
respDTO.setStatus("FAIL");
break;
}
return respDTO;
} catch (Exception e) {
log.error("微信退款异常: orderNo = {}, e = {}", paramsDto.getOrderNo(), e.getMessage());
log.error("微信退款异常: orderNo = {}, e = {}", paramsDto.getMchOrderNo(), e.getMessage());
throw new CzgException("微信退款异常");
}
}
@@ -369,13 +369,13 @@ public class WechatPayManager {
// Map<String, Object> sss1 = queryOrder(null, "sa101293120sss1", "1738216504");
// System.out.println(sss1);
refundOrder(null, new RefundParamsDto()
.setMerchantId("1738216504")
.setOrderNo("sa101293120sss1")
.setRefundOrderNo("sa101293120sss1")
.setOrderAmount(1L)
.setRefundAmount(1L)
.setRefundReason("测试")
.setRefundNotifyUrl("https://www.baidu.com"));
// refundOrder(null, new RefundParamsDto()
// .setMerchantId("1738216504")
// .setOrderNo("sa101293120sss1")
// .setRefundOrderNo("sa101293120sss1")
// .setOrderAmount(1L)
// .setRefundAmount(1L)
// .setRefundReason("测试")
// .setRefundNotifyUrl("https://www.baidu.com"));
}
}

View File

@@ -10,10 +10,12 @@ import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.czg.entity.PolyBaseReq;
import com.czg.entity.PolyBaseResp;
import com.czg.entity.notify.CzgPayNotifyDTO;
import com.czg.entity.resp.*;
import com.czg.enums.CzgPayEnum;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.PayNotifyRespDTO;
import com.czg.resp.CzgRespCode;
import com.czg.resp.CzgResult;
import com.czg.utils.AssertUtil;
@@ -158,6 +160,32 @@ public class PolyPayUtils {
}
/**
* 回调数据处理
*/
public static PayNotifyRespDTO getNotifyResp(PolyBaseResp respParams) {
AssertUtil.isNull(respParams, "聚合交易 回调数据为空");
log.info("聚合交易请求响应,{}", respParams);
if (!"000000".equals(respParams.getCode())) {
log.error("聚合回调响应失败,{}", respParams);
return null;
}
CzgPayNotifyDTO dto = JSONObject.parseObject(respParams.getBizData(), CzgPayNotifyDTO.class);
return new PayNotifyRespDTO()
.setMchOrderNo(dto.getMchOrderNo())
.setThirdOrderNo(dto.getPayOrderId())
.setAmount(dto.getAmount())
.setPlatform(dto.getPayType())
.setExtData(dto.getExtParam())
.setPaySuccessTime(dto.getPayTime())
.setErrorMsg("")
.setStatus(dto.getState())
.setOriginalData(respParams.getBizData());
}
/**
* 默认Post
*

View File

@@ -1,12 +1,12 @@
package com.czg.service.order.service;
import com.czg.entity.resp.CzgBaseResp;
import com.czg.entity.resp.CzgRefundResp;
import com.czg.enums.CzgPayEnum;
import com.czg.order.dto.LtPayOtherDTO;
import com.czg.order.entity.OrderPayment;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.RefundRespDTO;
import com.czg.resp.CzgResult;
import lombok.NonNull;
@@ -44,7 +44,7 @@ public interface PayService {
* 退款
* 目前订单 会员 使用
*/
CzgResult<CzgRefundResp> refund(@NonNull Long shopId, CzgRefundReq bizData);
CzgResult<RefundRespDTO> refund(@NonNull Long shopId, CzgRefundReq bizData);
/**
* 统一退款接口
* 目前 拼团商品 积分商品 套餐推广 使用
@@ -75,5 +75,5 @@ public interface PayService {
* @param mchRefundNo 商户退款订单号 二选一
* @param refundOrderId 平台退款订单号 二选一
*/
CzgResult<CzgRefundResp> queryRefund(Long shopId, String mchRefundNo, String refundOrderId);
CzgResult<RefundRespDTO> queryRefund(Long shopId, String mchRefundNo, String refundOrderId);
}

View File

@@ -6,7 +6,10 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.*;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
@@ -17,9 +20,8 @@ import com.czg.config.RabbitPublisher;
import com.czg.config.RedisCst;
import com.czg.constant.MarketConstants;
import com.czg.constant.TableValueConstant;
import com.czg.entity.notify.CzgPayNotifyDTO;
import com.czg.entity.notify.CzgRefundNotifyDTO;
import com.czg.constants.PayTypeConstants;
import com.czg.entity.notify.CzgRefundNotifyDTO;
import com.czg.enums.ShopTableStatusEnum;
import com.czg.enums.ShopUserFlowBizEnum;
import com.czg.exception.CzgException;
@@ -40,6 +42,7 @@ import com.czg.order.entity.OrderPayment;
import com.czg.order.enums.PayEnums;
import com.czg.order.service.*;
import com.czg.order.vo.*;
import com.czg.pay.PayNotifyRespDTO;
import com.czg.product.entity.Product;
import com.czg.product.service.ProductRpcService;
import com.czg.product.service.ProductService;
@@ -50,7 +53,6 @@ import com.czg.service.order.enums.OrderStatusEnums;
import com.czg.service.order.mapper.OrderInfoCustomMapper;
import com.czg.service.order.print.PrinterHandler;
import com.czg.utils.*;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
@@ -1028,13 +1030,12 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
@Override
@Transactional
public void payCallBackOrder(@NotBlank String orderNo, @NotNull JSONObject resultJson, int retryCount) {
CzgPayNotifyDTO czgCallBackDto = JSONObject.parseObject(resultJson.toString(), CzgPayNotifyDTO.class);
public void payCallBackOrder(@NotBlank String orderNo, @NotNull PayNotifyRespDTO notifyRespDTO, int retryCount) {
OrderPayment payment = paymentService.getOne(new QueryWrapper().eq(OrderPayment::getOrderNo, orderNo));
if (payment == null) {
if (retryCount < MAX_RETRIES) {
log.info("支付记录不存在,第 {} 次重试,将在 {} 秒后进行", retryCount + 1, DELAY);
executorService.schedule(() -> payCallBackOrder(orderNo, resultJson, retryCount + 1), DELAY, TimeUnit.SECONDS);
executorService.schedule(() -> payCallBackOrder(orderNo, notifyRespDTO, retryCount + 1), DELAY, TimeUnit.SECONDS);
} else {
log.error("订单支付回调失败, 达到最大重试次数, 支付记录不存在, orderNo: {}", orderNo);
}
@@ -1044,10 +1045,11 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
log.info("订单处理过payment id{}", payment.getId());
return;
}
payment.setTradeNumber(czgCallBackDto.getPayOrderId());
payment.setRespJson(resultJson.toString());
payment.setTradeNumber(notifyRespDTO.getThirdOrderNo());
payment.setRespJson(notifyRespDTO.getOriginalData());
payment.setPayStatus(PayTypeConstants.PayStatus.FAIL);
if ("TRADE_SUCCESS".equals(czgCallBackDto.getState())) {
payment.setPlatformType(notifyRespDTO.getPlatform());
if ("TRADE_SUCCESS".equals(notifyRespDTO.getStatus())) {
payment.setPayStatus(PayTypeConstants.PayStatus.SUCCESS);
if (PayTypeConstants.SourceType.ORDER.equals(payment.getSourceType())) {
OrderInfo orderInfo = orderInfoService.getById(payment.getSourceId());
@@ -1055,8 +1057,8 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
log.error("订单支付回调失败,订单不存在,支付记录Id,{}", payment.getId());
return;
}
upOrderInfo(orderInfo, new BigDecimal(czgCallBackDto.getAmount()).divide(new BigDecimal(100), 2, RoundingMode.DOWN),
DateUtil.parseLocalDateTime(czgCallBackDto.getPayTime()), payment.getId(), null);
upOrderInfo(orderInfo, new BigDecimal(notifyRespDTO.getAmount()).divide(new BigDecimal(100), 2, RoundingMode.DOWN),
DateUtil.parseLocalDateTime(notifyRespDTO.getPaySuccessTime()), payment.getId(), null);
if (orderInfo.getUserId() != null) {
// 分销员升级等级
distributionUserService.costUpgradeLevelBefore(orderInfo.getUserId(), orderInfo.getShopId());
@@ -1066,14 +1068,14 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
} else if (PayTypeConstants.SourceType.MEMBER_IN.equals(payment.getSourceType()) || PayTypeConstants.SourceType.FREE.equals(payment.getSourceType())) {
boolean isFree = PayTypeConstants.SourceType.FREE.equals(payment.getSourceType());
ShopUser shopUser = shopUserService.getById(payment.getSourceId());
OrderInfo orderInfo = null;
OrderInfo orderInfo;
if (shopUser == null) {
log.error("会员充值失败会员不存在会员id{}", payment.getSourceId());
} else {
ShopUserFlowBizEnum bizEnum;
if ("WECHAT".equals(czgCallBackDto.getPayType())) {
if ("WECHAT".equals(notifyRespDTO.getPlatform())) {
bizEnum = ShopUserFlowBizEnum.WECHAT_IN;
} else if ("ALIPAY".equals(czgCallBackDto.getPayType())) {
} else if ("ALIPAY".equals(notifyRespDTO.getPlatform())) {
bizEnum = ShopUserFlowBizEnum.ALIPAY_IN;
} else {
bizEnum = ShopUserFlowBizEnum.CASH_IN;
@@ -1089,7 +1091,7 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
.setType(1)
.setBizEnum(ShopUserFlowBizEnum.FREE_IN)
.setRelationId(orderInfo.getId())
.setMoney(BigDecimal.valueOf(czgCallBackDto.getAmount()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN));
.setMoney(BigDecimal.valueOf(notifyRespDTO.getAmount()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN));
shopUserService.updateMoney(shopUserMoneyEditDTO);
upOrderInfo(orderInfo, BigDecimal.ZERO,
LocalDateTime.now(), null, PayEnums.FREE_PAY);
@@ -1111,7 +1113,7 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
LocalDateTime.now(), null, PayEnums.VIP_PAY);
}
shopRechargeService.recharge(payment.getShopId(), payment.getSourceId(), payment.getRelatedId(),
BigDecimal.valueOf(czgCallBackDto.getAmount()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN),
BigDecimal.valueOf(notifyRespDTO.getAmount()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN),
payment.getId(), payment.getSourceType(), bizEnum, orderInfo == null);
}
}

View File

@@ -17,7 +17,6 @@ import com.czg.account.service.UserInfoService;
import com.czg.config.RabbitPublisher;
import com.czg.config.RedisCst;
import com.czg.constants.PayTypeConstants;
import com.czg.entity.resp.CzgRefundResp;
import com.czg.enums.CzgPayEnum;
import com.czg.enums.ShopUserFlowBizEnum;
import com.czg.exception.CzgException;
@@ -38,6 +37,7 @@ import com.czg.order.service.OrderInfoCustomService;
import com.czg.order.service.OrderPaymentService;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.RefundRespDTO;
import com.czg.resp.CzgResult;
import com.czg.service.RedisService;
import com.czg.service.order.dto.OrderPayParamDTO;
@@ -512,21 +512,21 @@ public class OrderPayServiceImpl implements OrderPayService {
OrderPayment payment = paymentService.getById(payOrderId);
AssertUtil.isNull(payment, "退款失败支付记录不存在");
Long refundId = payService.initPayment(OrderPayment.refund(shopId, orderId, PayTypeConstants.SourceType.ORDER,
refPayOrderNo, refundAmount, payment.getId()));
refPayOrderNo, refundAmount, payment.getId(), payment.getPlatformType()));
CzgResult<CzgRefundResp> refund = payService.refund(shopId, new CzgRefundReq(refPayOrderNo, refundReason, refundAmount.multiply(PayService.MONEY_RATE).longValue(),
payment.getAmount().multiply(PayService.MONEY_RATE).longValue(), payment.getOrderNo(), ""));
if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getState())) {
if (refund.getData() != null && refund.getData().getNote() != null) {
throw new CzgException(refund.getData().getNote());
CzgResult<RefundRespDTO> refund = payService.refund(shopId, new CzgRefundReq(refPayOrderNo, refundReason, refundAmount.multiply(PayService.MONEY_RATE).longValue(),
payment.getAmount().multiply(PayService.MONEY_RATE).longValue(), payment.getOrderNo(), "", payment.getPlatformType()));
if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getStatus())) {
if (refund.getData() != null && refund.getData().getErrMessage() != null) {
throw new CzgException(refund.getData().getErrMessage());
}
throw new CzgException(refund.getMsg());
} else {
paymentService.updateChain()
.eq(OrderPayment::getId, refundId)
.set(OrderPayment::getPayTime, refund.getData().getRefundTime())
.set(OrderPayment::getTradeNumber, refund.getData().getRefundOrderId())
.set(OrderPayment::getRespJson, JSONObject.toJSONString(refund.getData()))
.set(OrderPayment::getTradeNumber, refund.getData().getThirdRefundNo())
.set(OrderPayment::getRespJson, refund.getData().getOriginalData())
.update();
}
}

View File

@@ -6,21 +6,21 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.PayAdapter;
import com.czg.PayAdapterFactory;
import com.czg.constants.SystemConstants;
import com.czg.order.entity.ShopMerchant;
import com.czg.order.service.ShopMerchantService;
import com.czg.constant.PayChannelCst;
import com.czg.constants.ParamCodeCst;
import com.czg.constants.PayTypeConstants;
import com.czg.constants.SystemConstants;
import com.czg.entity.resp.CzgBaseResp;
import com.czg.entity.resp.CzgRefundResp;
import com.czg.enums.CzgPayEnum;
import com.czg.exception.CzgException;
import com.czg.order.dto.LtPayOtherDTO;
import com.czg.order.entity.OrderPayment;
import com.czg.order.entity.ShopMerchant;
import com.czg.order.service.OrderPaymentService;
import com.czg.order.service.ShopMerchantService;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.RefundRespDTO;
import com.czg.resp.CzgResult;
import com.czg.service.order.mapper.OrderPaymentMapper;
import com.czg.service.order.service.PayService;
@@ -85,7 +85,7 @@ public class PayServiceImpl implements PayService {
}
@Override
public CzgResult<CzgRefundResp> refund(@NonNull Long shopId, CzgRefundReq bizData) {
public CzgResult<RefundRespDTO> refund(@NonNull Long shopId, CzgRefundReq bizData) {
ShopMerchant shopMerchant = getMerchant(shopId);
PayAdapter adapter = PayAdapterFactory.getAdapter(shopMerchant.getChannel());
String payData = null;
@@ -104,17 +104,18 @@ public class PayServiceImpl implements PayService {
@NonNull String refundReason, @NonNull BigDecimal refundAmount) {
OrderPayment payment = paymentService.getById(payOrderId);
AssertUtil.isNull(payment, "退款失败,支付记录不存在");
Long refundId = initPayment(OrderPayment.refund(shopId, sourceId, payment.getSourceType(), refPayOrderNo, refundAmount, payment.getId()));
CzgResult<CzgRefundResp> refund = refund(shopId, new CzgRefundReq(refPayOrderNo, refundReason, refundAmount.multiply(MONEY_RATE).longValue(),
payment.getAmount().multiply(PayService.MONEY_RATE).longValue(), payment.getOrderNo(), ""));
Long refundId = initPayment(OrderPayment.refund(shopId, sourceId, payment.getSourceType(), refPayOrderNo, refundAmount, payment.getId(), payment.getPlatformType()));
CzgResult<RefundRespDTO> refund = refund(shopId, new CzgRefundReq(refPayOrderNo, refundReason, refundAmount.multiply(MONEY_RATE).longValue(),
payment.getAmount().multiply(PayService.MONEY_RATE).longValue(), payment.getOrderNo(), "", payment.getPlatformType()));
OrderPayment uOrderPayment = new OrderPayment();
uOrderPayment.setRespJson(JSONObject.toJSONString(refund.getData()));
if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getState())) {
if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getStatus())) {
uOrderPayment.setPayStatus(PayTypeConstants.PayStatus.FAIL);
} else {
uOrderPayment.setTradeNumber(refund.getData().getRefundOrderId());
uOrderPayment.setTradeNumber(refund.getData().getThirdRefundNo());
uOrderPayment.setPayStatus(PayTypeConstants.PayStatus.SUCCESS);
uOrderPayment.setPayTime(LocalDateTimeUtil.parse(refund.getData().getRefundTime(), "yyyy-MM-dd HH:mm:ss"));
uOrderPayment.setRespJson(refund.getData().getOriginalData());
}
paymentService.update(uOrderPayment, QueryWrapper.create().eq(OrderPayment::getId, refundId));
}
@@ -127,16 +128,17 @@ public class PayServiceImpl implements PayService {
AssertUtil.isNull(payment, "退款失败,支付记录不存在");
Long refundCompensate = initPayment(OrderPayment.refundCompensate(refundPayment.getShopId(), refundPayment.getSourceId(),
payment.getSourceType(), refPayOrderNo, refundPayment.getAmount(), refundPayment.getId()));
CzgResult<CzgRefundResp> refund = refund(payment.getShopId(), new CzgRefundReq(refPayOrderNo, "退款补偿", refundPayment.getAmount().multiply(MONEY_RATE).longValue(),
payment.getAmount().multiply(PayService.MONEY_RATE).longValue(), payment.getOrderNo(), ""));
CzgResult<RefundRespDTO> refund = refund(payment.getShopId(), new CzgRefundReq(refPayOrderNo, "退款补偿", refundPayment.getAmount().multiply(MONEY_RATE).longValue(),
payment.getAmount().multiply(PayService.MONEY_RATE).longValue(), payment.getOrderNo(), "", payment.getPlatformType()));
OrderPayment uOrderPayment = new OrderPayment();
uOrderPayment.setTradeNumber(refund.getData().getRefundOrderId());
uOrderPayment.setTradeNumber(refund.getData().getThirdRefundNo());
uOrderPayment.setRespJson(JSONObject.toJSONString(refund.getData()));
if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getState())) {
if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getStatus())) {
uOrderPayment.setPayStatus(PayTypeConstants.PayStatus.FAIL);
} else {
uOrderPayment.setPayStatus(PayTypeConstants.PayStatus.SUCCESS);
uOrderPayment.setPayTime(LocalDateTimeUtil.parse(refund.getData().getRefundTime(), "yyyy-MM-dd HH:mm:ss"));
uOrderPayment.setRespJson(refund.getData().getOriginalData());
}
paymentService.update(uOrderPayment, QueryWrapper.create().eq(OrderPayment::getId, refundPayment.getId()));
paymentService.update(uOrderPayment, QueryWrapper.create().eq(OrderPayment::getId, refundCompensate));
@@ -158,7 +160,7 @@ public class PayServiceImpl implements PayService {
@Override
@Transactional
public CzgResult<CzgRefundResp> queryRefund(@NonNull Long shopId, String mchRefundNo, String refundOrderId) {
public CzgResult<RefundRespDTO> queryRefund(@NonNull Long shopId, String mchRefundNo, String refundOrderId) {
ShopMerchant shopMerchant = getMerchant(shopId);
PayAdapter adapter = PayAdapterFactory.getAdapter(shopMerchant.getChannel());
String payData = null;

View File

@@ -2,12 +2,10 @@ package com.czg.service.order.service.impl;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO;
import com.czg.account.entity.*;
import com.czg.account.service.*;
import com.czg.constants.PayTypeConstants;
import com.czg.entity.resp.CzgRefundResp;
import com.czg.enums.CzgPayEnum;
import com.czg.enums.ShopUserFlowBizEnum;
import com.czg.exception.CzgException;
@@ -26,6 +24,7 @@ import com.czg.order.service.OrderInfoCustomService;
import com.czg.order.service.OrderPaymentService;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.RefundRespDTO;
import com.czg.resp.CzgResult;
import com.czg.service.order.dto.VipMemberPayParamDTO;
import com.czg.service.order.dto.VipPayParamDTO;
@@ -312,19 +311,19 @@ public class ShopUserServiceImpl implements ShopUserPayService {
}
String refPayOrderNo = "REFVIP" + IdUtil.getSnowflakeNextId();
refPaymentId = payService.initPayment(OrderPayment.refund(refPayParam.getShopId(), shopUser.getId(), PayTypeConstants.SourceType.MEMBER_IN,
refPayOrderNo, refPayParam.getRefAmount(), inFlow.getId()));
CzgResult<CzgRefundResp> refund = payService.refund(refPayParam.getShopId(), new CzgRefundReq(refPayOrderNo, refPayParam.getRemark(),
refPayOrderNo, refPayParam.getRefAmount(), inFlow.getId(), payment.getPlatformType()));
CzgResult<RefundRespDTO> refund = payService.refund(refPayParam.getShopId(), new CzgRefundReq(refPayOrderNo, refPayParam.getRemark(),
refPayParam.getRefAmount().multiply(PayService.MONEY_RATE).longValue(), payment.getAmount().multiply(PayService.MONEY_RATE).longValue(),
payment.getOrderNo(), ""));
if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getState())) {
payment.getOrderNo(), "", payment.getPlatformType()));
if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getStatus())) {
throw new CzgException(refund.getMsg());
} else {
paymentService.updateChain()
.eq(OrderPayment::getId, refPaymentId)
.set(OrderPayment::getPayTime, refund.getData().getRefundTime())
.set(OrderPayment::getTradeNumber, refund.getData().getRefundOrderId())
.set(OrderPayment::getTradeNumber, refund.getData().getThirdRefundNo())
.set(OrderPayment::getPayStatus, PayTypeConstants.PayStatus.SUCCESS)
.set(OrderPayment::getRespJson, JSONObject.toJSONString(refund.getData()))
.set(OrderPayment::getRespJson, refund.getData().getOriginalData())
.update();
}
}

View File

@@ -1,12 +1,8 @@
package com.czg;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.entity.resp.CzgBaseResp;
import com.czg.entity.resp.CzgRefundResp;
import com.czg.enums.CzgPayEnum;
import com.czg.pay.NativeMerchantDTO;
import com.czg.pay.PolyMerchantDTO;
import com.czg.pay.*;
import com.czg.resp.CzgResult;
import jakarta.validation.constraints.NotBlank;
import lombok.NonNull;
@@ -41,10 +37,10 @@ public interface PayAdapter {
CzgResult<Map<String, Object>> pay(@NonNull CzgPayEnum payType, @NotBlank String payData, @NotBlank String domain,
@NotBlank String notifyUrl, CzgPayBaseReq bizData);
CzgResult<CzgRefundResp> refund(@NotBlank String domain, @NotBlank String payData, String notifyUrl, CzgRefundReq bizData);
CzgResult<RefundRespDTO> refund(@NotBlank String domain, @NotBlank String payData, String notifyUrl, CzgRefundReq bizData);
CzgResult<CzgBaseResp> queryPayOrder(@NotBlank String domain, @NotBlank String payData, String payOrderId, String mchOrderNo);
CzgResult<CzgRefundResp> queryRefund(@NotBlank String domain, @NotBlank String payData, String mchRefundNo, String refundOrderId);
CzgResult<RefundRespDTO> queryRefund(@NotBlank String domain, @NotBlank String payData, String mchRefundNo, String refundOrderId);
}

View File

@@ -5,14 +5,13 @@ import com.czg.PayAdapter;
import com.czg.PayManager;
import com.czg.constant.PayChannelCst;
import com.czg.entity.resp.CzgBaseResp;
import com.czg.entity.resp.CzgRefundResp;
import com.czg.enums.CzgPayEnum;
import com.czg.exception.CzgException;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.NativeMerchantDTO;
import com.czg.pay.RefundRespDTO;
import com.czg.resp.CzgResult;
import jakarta.validation.constraints.NotBlank;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
@@ -36,17 +35,17 @@ public class NativePayAdapter implements PayAdapter {
@Override
public CzgResult<Map<String, Object>> pay(@NonNull CzgPayEnum payType, String payData, String domain, String notifyUrl, CzgPayBaseReq bizData) {
try {
NativeMerchantDTO polyMerchantDTO = JSONObject.parseObject(payData, NativeMerchantDTO.class);
NativeMerchantDTO merchantDTO = getMerchantDTO(payData);
return switch (payType) {
// case H5_PAY:
// return h5Pay(polyMerchantDTO, domain, notifyUrl, bizData);
case JS_PAY -> jsPay(polyMerchantDTO, notifyUrl, bizData);
case LT_PAY -> jsPay(polyMerchantDTO, notifyUrl, bizData);
// return h5Pay(merchantDTO, domain, notifyUrl, bizData);
case JS_PAY -> jsPay(merchantDTO, notifyUrl, bizData);
case LT_PAY -> jsPay(merchantDTO, notifyUrl, bizData);
// case SCAN_PAY:
// return scanPay(polyMerchantDTO, domain, notifyUrl, bizData);
// return scanPay(merchantDTO, domain, notifyUrl, bizData);
case MICRO_PAY ->
//扫码支付 扫描码
barPay(polyMerchantDTO, notifyUrl, bizData);
barPay(merchantDTO, notifyUrl, bizData);
default -> throw new CzgException("原生支付不支持该支付方式: " + bizData.getPayType());
};
} catch (Exception e) {
@@ -56,8 +55,9 @@ public class NativePayAdapter implements PayAdapter {
}
@Override
public CzgResult<CzgRefundResp> refund(String domain, String payData, String notifyUrl, CzgRefundReq bizData) {
return null;
public CzgResult<RefundRespDTO> refund(String domain, String payData, String notifyUrl, CzgRefundReq bizData) {
NativeMerchantDTO merchantDTO = getMerchantDTO(payData);
return CzgResult.success(PayManager.refund(bizData, notifyUrl, merchantDTO));
}
@Override
@@ -66,7 +66,7 @@ public class NativePayAdapter implements PayAdapter {
}
@Override
public CzgResult<CzgRefundResp> queryRefund(String domain, String payData, String mchRefundNo, String refundOrderId) {
public CzgResult<RefundRespDTO> queryRefund(String domain, String payData, String mchRefundNo, String refundOrderId) {
return null;
}
@@ -79,4 +79,8 @@ public class NativePayAdapter implements PayAdapter {
bizData.setNotifyUrl(notifyUrl);
return CzgResult.success(PayManager.barPay(bizData, merchantDTO));
}
private NativeMerchantDTO getMerchantDTO(String payData) {
return JSONObject.parseObject(payData, NativeMerchantDTO.class);
}
}

View File

@@ -12,6 +12,7 @@ import com.czg.exception.CzgException;
import com.czg.pay.CzgPayBaseReq;
import com.czg.pay.CzgRefundReq;
import com.czg.pay.PolyMerchantDTO;
import com.czg.pay.RefundRespDTO;
import com.czg.resp.CzgResult;
import com.czg.utils.AssertUtil;
import jakarta.validation.constraints.NotBlank;
@@ -51,10 +52,11 @@ public class PolyPayAdapter implements PayAdapter {
@Override
public CzgResult<CzgRefundResp> refund(@NotBlank String domain, @NotBlank String payData, String notifyUrl, CzgRefundReq bizData) {
public CzgResult<RefundRespDTO> refund(@NotBlank String domain, @NotBlank String payData, String notifyUrl, CzgRefundReq bizData) {
PolyMerchantDTO shopMerchant = JSONObject.parseObject(payData, PolyMerchantDTO.class);
bizData.setNotifyUrl(notifyUrl);
return PolyPayUtils.refundOrder(domain, shopMerchant.getAppId(), shopMerchant.getAppSecret(), bizData);
CzgResult<CzgRefundResp> result = PolyPayUtils.refundOrder(domain, shopMerchant.getAppId(), shopMerchant.getAppSecret(), bizData);
return convertRefundResp(result);
}
@Override
@@ -65,9 +67,10 @@ public class PolyPayAdapter implements PayAdapter {
}
@Override
public CzgResult<CzgRefundResp> queryRefund(@NotBlank String payData, @NotBlank String domain, String mchRefundNo, String refundOrderId) {
public CzgResult<RefundRespDTO> queryRefund(@NotBlank String payData, @NotBlank String domain, String mchRefundNo, String refundOrderId) {
PolyMerchantDTO shopMerchant = JSONObject.parseObject(payData, PolyMerchantDTO.class);
return PolyPayUtils.queryRefundOrder(domain, shopMerchant.getAppId(), shopMerchant.getAppSecret(), mchRefundNo, refundOrderId);
CzgResult<CzgRefundResp> result = PolyPayUtils.queryRefundOrder(domain, shopMerchant.getAppId(), shopMerchant.getAppSecret(), mchRefundNo, refundOrderId);
return convertRefundResp(result);
}
private CzgResult<Map<String, Object>> h5Pay(PolyMerchantDTO shopMerchant, String domain, String notifyUrl, CzgPayBaseReq bizData) {
@@ -98,4 +101,20 @@ public class PolyPayAdapter implements PayAdapter {
bizData.polyBase(shopMerchant.getStoreId(), notifyUrl);
return PolyPayUtils.microPay(domain, shopMerchant.getAppId(), shopMerchant.getAppSecret(), bizData);
}
private CzgResult<RefundRespDTO> convertRefundResp(CzgResult<CzgRefundResp> result) {
if (result.isSuccess()) {
RefundRespDTO respDTO = new RefundRespDTO()
.setStatus(result.getData().getState())
.setMerchantRefundNo(result.getData().getMchRefundNo())
.setThirdRefundNo(result.getData().getRefundOrderId())
.setPlatform(result.getData().getPayType())
.setRefundAmount(result.getData().getRefundAmt())
.setRefundTime(result.getData().getRefundTime())
.setOriginalData(result.getData().getExtParam());
return CzgResult.success(respDTO);
}
return CzgResult.failure(result.getMsg());
}
}