diff --git a/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/marriagebount/constant/MarriageBountyOrderPaymentStatusEnum.java b/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/marriagebount/constant/MarriageBountyOrderPaymentStatusEnum.java new file mode 100644 index 0000000..9354364 --- /dev/null +++ b/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/marriagebount/constant/MarriageBountyOrderPaymentStatusEnum.java @@ -0,0 +1,38 @@ +package com.qniao.dam.domian.aggregate.marriagebount.constant; + +import com.baomidou.mybatisplus.annotation.EnumValue; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.Getter; + +@Getter +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum MarriageBountyOrderPaymentStatusEnum { + + PAID(1, "已支付"), + + BEING_REFUNDED(2, "退款中"), + + REFUNDED(3, "已退款"); + + @EnumValue + @JsonValue + private final Integer value; + private final String desc; + + MarriageBountyOrderPaymentStatusEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @JsonCreator + public static MarriageBountyOrderPaymentStatusEnum get(Object code) { + for (MarriageBountyOrderPaymentStatusEnum e : MarriageBountyOrderPaymentStatusEnum.values()) { + if (e.getValue().equals(code)) { + return e; + } + } + return null; + } +} \ No newline at end of file diff --git a/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/paymentorderrefund/constant/PaymentOrderRefundStatusEnum.java b/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/paymentorderrefund/constant/PaymentOrderRefundStatusEnum.java new file mode 100644 index 0000000..9c8af8c --- /dev/null +++ b/dating-agency-mall-constant/src/main/java/com/qniao/dam/domian/aggregate/paymentorderrefund/constant/PaymentOrderRefundStatusEnum.java @@ -0,0 +1,41 @@ +package com.qniao.dam.domian.aggregate.paymentorderrefund.constant; + +import com.baomidou.mybatisplus.annotation.EnumValue; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.Getter; + +@Getter +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum PaymentOrderRefundStatusEnum { + + SUCCESS(1, "退款成功"), + + CLOSED(2, "退款关闭"), + + PROCESSING(3, "退款处理中"), + + ABNORMAL(4, "退款异常"); + + @EnumValue + @JsonValue + private final Integer value; + private final String desc; + + PaymentOrderRefundStatusEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @JsonCreator + public static PaymentOrderRefundStatusEnum get(Object code) { + for (PaymentOrderRefundStatusEnum e : PaymentOrderRefundStatusEnum.values()) { + if (e.getValue().equals(code)) { + return e; + } + } + return null; + + } +} \ No newline at end of file diff --git a/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/marriagebounty/entity/MarriageBountyOrder.java b/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/marriagebounty/entity/MarriageBountyOrder.java index 4459250..4c605af 100644 --- a/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/marriagebounty/entity/MarriageBountyOrder.java +++ b/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/marriagebounty/entity/MarriageBountyOrder.java @@ -3,6 +3,7 @@ package com.qniao.dam.domain.aggregate.marriagebounty.entity; import com.baomidou.mybatisplus.annotation.TableName; import com.qniao.dam.domain.aggregate.marriagebounty.valueobj.MarriageBountyOrderProductRecord; import com.qniao.dam.domain.aggregate.marriagebounty.valueobj.MarriageBountyOrderRel; +import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderPaymentStatusEnum; import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderStatusEnum; import com.qniao.domain.Entity; import io.swagger.annotations.ApiModelProperty; @@ -26,6 +27,9 @@ public class MarriageBountyOrder extends Entity { @ApiModelProperty("状态") private MarriageBountyOrderStatusEnum status; + @ApiModelProperty("状态") + private MarriageBountyOrderPaymentStatusEnum paymentStatus; + @ApiModelProperty("悬赏招亲订单标识关系") private transient List orderRelList; diff --git a/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/entity/PaymentOrderRefund.java b/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/entity/PaymentOrderRefund.java index c836f1c..3150b61 100644 --- a/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/entity/PaymentOrderRefund.java +++ b/dating-agency-mall-entity/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/entity/PaymentOrderRefund.java @@ -1,6 +1,8 @@ package com.qniao.dam.domain.aggregate.paymentorderrefund.entity; import com.baomidou.mybatisplus.annotation.TableName; +import com.qniao.dam.domian.aggregate.paymentorder.constant.PaymentMethodEnum; +import com.qniao.dam.domian.aggregate.paymentorderrefund.constant.PaymentOrderRefundStatusEnum; import com.qniao.domain.Entity; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -20,6 +22,12 @@ public class PaymentOrderRefund extends Entity { @ApiModelProperty("支付单号") private Long paymentOrderId; + @ApiModelProperty("付款方式") + private PaymentMethodEnum paymentMethod; + + @ApiModelProperty("订单金额") + private BigDecimal orderAmount; + @ApiModelProperty("退款金额") private BigDecimal refundFee; @@ -33,5 +41,5 @@ public class PaymentOrderRefund extends Entity { private LocalDateTime refundTime; @ApiModelProperty("状态") - private Integer status; + private PaymentOrderRefundStatusEnum status; } diff --git a/dating-agency-mall-event/src/main/java/com/qniao/dam/domian/aggregate/paymentorderrefund/event/PaymentOrderRefundRefundedEvent.java b/dating-agency-mall-event/src/main/java/com/qniao/dam/domian/aggregate/paymentorderrefund/event/PaymentOrderRefundRefundedEvent.java new file mode 100644 index 0000000..701eacd --- /dev/null +++ b/dating-agency-mall-event/src/main/java/com/qniao/dam/domian/aggregate/paymentorderrefund/event/PaymentOrderRefundRefundedEvent.java @@ -0,0 +1,48 @@ +package com.qniao.dam.domian.aggregate.paymentorderrefund.event; + +import com.qniao.dam.domian.aggregate.paymentorder.constant.PaymentMethodEnum; +import com.qniao.dam.domian.aggregate.paymentorderrefund.constant.PaymentOrderRefundStatusEnum; +import com.qniao.domain.BaseDomainEvent; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PaymentOrderRefundRefundedEvent extends BaseDomainEvent { + + @ApiModelProperty("唯一标识") + private Long id; + + @ApiModelProperty("交易订单id") + private Long tradeOrderId; + + @ApiModelProperty("支付单号") + private Long paymentOrderId; + + @ApiModelProperty("付款方式") + private PaymentMethodEnum paymentMethod; + + @ApiModelProperty("订单金额") + private BigDecimal orderAmount; + + @ApiModelProperty("退款金额") + private BigDecimal refundFee; + + @ApiModelProperty("微信支付订单号") + private String transactionId; + + @ApiModelProperty("微信退款单号") + private String refundId; + + @ApiModelProperty("退款成功时间") + private LocalDateTime refundTime; + + @ApiModelProperty("状态") + private PaymentOrderRefundStatusEnum status; +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/handler/paymentorderrefund/PaymentOrderRefundEventHandler.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/handler/paymentorderrefund/PaymentOrderRefundEventHandler.java new file mode 100644 index 0000000..a433c57 --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/handler/paymentorderrefund/PaymentOrderRefundEventHandler.java @@ -0,0 +1,51 @@ +package com.qniao.dam.application.handler.paymentorderrefund; + +import com.qniao.dam.domain.aggregate.marriagebounty.MarriageBountyOrderAggregate; +import com.qniao.dam.domain.aggregate.marriagebounty.entity.MarriageBountyOrder; +import com.qniao.dam.domain.aggregate.marriagebounty.valueobj.MarriageBountyOrderRel; +import com.qniao.dam.domian.aggregate.paymentorderrefund.constant.PaymentOrderRefundStatusEnum; +import com.qniao.dam.domian.aggregate.paymentorderrefund.event.PaymentOrderRefundRefundedEvent; +import com.qniao.dam.query.marriagebounty.MarriageBountyOrderQueryService; +import com.qniao.dam.query.paymentorderrefund.PaymentOrderRefundQueryService; +import com.qniao.domain.BaseApplicationService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class PaymentOrderRefundEventHandler extends BaseApplicationService { + + @Resource + private MarriageBountyOrderQueryService marriageBountyOrderQueryService; + @Resource + private PaymentOrderRefundQueryService paymentOrderRefundQueryService; + @Resource + private MarriageBountyOrderAggregate marriageBountyOrderAggregate; + + /** + * 付款单已退款事件 + */ + private void handle(PaymentOrderRefundRefundedEvent event) { + try { + if (PaymentOrderRefundStatusEnum.SUCCESS.equals(event.getStatus())) { + MarriageBountyOrder marriageBountyOrder = marriageBountyOrderQueryService.queryByOrderRel(event.getTradeOrderId()); + if (Objects.nonNull(marriageBountyOrder)) { + List tradeOrderIdList = marriageBountyOrder.getOrderRelList().stream().map(MarriageBountyOrderRel::getOrderId).collect(Collectors.toList()); + if (paymentOrderRefundQueryService.checkRefunded(tradeOrderIdList)) { + MarriageBountyOrder refundMarriageBountyOrder = new MarriageBountyOrder(); + refundMarriageBountyOrder.setId(marriageBountyOrder.getId()); + marriageBountyOrderAggregate.refund(refundMarriageBountyOrder); + //todo 主动发起退款 + } + } + } + } catch (Exception e) { + log.error("悬赏订单已退款事件处理异常", e); + } + } +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/marriagebounty/MarriageBountyOrderApplicationService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/marriagebounty/MarriageBountyOrderApplicationService.java index c518eaa..f99196e 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/marriagebounty/MarriageBountyOrderApplicationService.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/marriagebounty/MarriageBountyOrderApplicationService.java @@ -1,6 +1,7 @@ package com.qniao.dam.application.service.marriagebounty; import com.qniao.dam.api.query.marriagebounty.user.response.UserGetMarriageBountyOrderPreRefundInfoVo; +import com.qniao.dam.application.service.paymentorderrefund.PaymentOrderRefundApplicationService; import com.qniao.dam.domain.aggregate.marriagebounty.MarriageBountyOrderAggregate; import com.qniao.dam.domain.aggregate.marriagebounty.entity.MarriageBountyOrder; import com.qniao.dam.domain.aggregate.marriagebounty.entity.MarriageBountyOrderReward; @@ -15,6 +16,7 @@ import com.qniao.dam.domain.aggregate.paymentchannelorder.entity.PaymentChannelO import com.qniao.dam.domain.aggregate.paymentorder.entity.PaymentOrder; import com.qniao.dam.domain.aggregate.paymentorderrefund.entity.PaymentOrderRefund; import com.qniao.dam.domain.aggregate.productspec.entity.ProductSpec; +import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderPaymentStatusEnum; import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderStatusEnum; import com.qniao.dam.domian.aggregate.paymentorder.constant.PaymentOrderStatusEnum; import com.qniao.dam.domian.aggregate.product.constant.ProductSubCategoryEnum; @@ -49,10 +51,13 @@ public class MarriageBountyOrderApplicationService extends BaseApplicationServic private PaymentOrderQueryService paymentOrderQueryService; @Resource private PaymentChannelOrderQueryService paymentChannelOrderQueryService; + @Resource + private PaymentOrderRefundApplicationService paymentOrderRefundApplicationService; public void save(Long orderId) { Order order = orderRepository.load(orderId); - MarriageBountyOrder marriageBountyOrder = marriageBountyOrderQueryService.queryBy(order.getUserId(), order.getMiId(), MarriageBountyOrderStatusEnum.MATCHMAKING); + MarriageBountyOrder marriageBountyOrder = marriageBountyOrderQueryService.queryBy(order.getUserId(), order.getMiId(), + MarriageBountyOrderStatusEnum.MATCHMAKING, MarriageBountyOrderPaymentStatusEnum.PAID); if (Objects.isNull(marriageBountyOrder)) { //新的悬赏招亲 marriageBountyOrder = MarriageBountyOrder.build(order.getUserId(), order.getMiId()); @@ -114,10 +119,12 @@ public class MarriageBountyOrderApplicationService extends BaseApplicationServic MarriageBountyOrder marriageBountyOrder = marriageBountyOrderRepository.load(preRefundInfoVo.getMarriageBountyOrderId()); List orderList = marriageBountyOrder.getOrderRelList().stream().map(MarriageBountyOrderRel::getOrderId).collect(Collectors.toList()); List paymentOrderList = paymentOrderQueryService.listByOrderId(orderList, PaymentOrderStatusEnum.PAID); + List paymentOrderRefundList = new ArrayList<>(); for (PaymentOrder paymentOrder : paymentOrderList) { PaymentOrderRefund paymentOrderRefund = new PaymentOrderRefund(); BigDecimal refundFee = BigDecimal.ZERO; Order order = orderRepository.load(paymentOrder.getOrderId()); + PaymentChannelOrder paymentChannelOrder = paymentChannelOrderQueryService.queryByTxnOrderId(paymentOrder.getId()); for (OrderItem orderItem : order.getOrderItemList()) { if (ProductSubCategoryEnum.MARRIAGE_BOUNTY_MEETING_FEE.equals(orderItem.getSubCategory())) { refundFee = refundFee.add(orderItem.getUnitSettlementPrice().multiply(BigDecimal.valueOf(preRefundInfoVo.getRefundableMeetingQuantity()))); @@ -125,9 +132,19 @@ public class MarriageBountyOrderApplicationService extends BaseApplicationServic refundFee = refundFee.add(orderItem.getUnitSettlementPrice()); } } + paymentOrderRefund.setTradeOrderId(paymentOrder.getOrderId()); + paymentOrderRefund.setPaymentOrderId(paymentOrder.getId()); + paymentOrderRefund.setPaymentMethod(paymentOrder.getPaymentMethod()); + paymentOrderRefund.setTransactionId(paymentChannelOrder.getExtOrderNo()); + paymentOrderRefund.setOrderAmount(paymentChannelOrder.getAmount()); paymentOrderRefund.setRefundFee(refundFee); - //todo + paymentOrderRefundList.add(paymentOrderRefund); } + MarriageBountyOrder applyRefundMarriageBountyOrder = new MarriageBountyOrder(); + applyRefundMarriageBountyOrder.setMiId(marriageBountyOrder.getId()); + marriageBountyOrderAggregate.applyRefund(applyRefundMarriageBountyOrder); + //发起微信退款 + paymentOrderRefundApplicationService.refund(paymentOrderRefundList); } } } diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/notify/NotifyApplicationService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/notify/NotifyApplicationService.java index e60ce1a..2839564 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/notify/NotifyApplicationService.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/notify/NotifyApplicationService.java @@ -2,6 +2,7 @@ package com.qniao.dam.application.service.notify; import com.qniao.dam.api.command.notify.user.response.WeChatNotification; import com.qniao.dam.api.command.notify.user.response.WeChatNotificationVo; +import com.qniao.dam.application.service.paymentchannelorder.processor.wechat.WeChatPayProcessor; import com.qniao.dam.application.service.paymentchannelorder.processor.wechat.utils.WXPayV3Util; import com.qniao.dam.domain.aggregate.paymentchannelorder.PaymentChannelOrderAggregate; import com.qniao.dam.domain.aggregate.paymentchannelorder.entity.PaymentChannelOrder; @@ -22,8 +23,6 @@ import java.time.format.DateTimeFormatter; @Slf4j public class NotifyApplicationService extends BaseApplicationService { public static final String RETURN_VALUE_SUCCESS = "SUCCESS"; - public DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; - @Resource private PaymentChannelOrderDao paymentChannelOrderDao; @@ -42,7 +41,7 @@ public class NotifyApplicationService extends BaseApplicationService { PaymentChannelOrder paymentChannelOrder = paymentChannelOrderDao.selectById(notification.getOutTradeNo()); Assert.notNull(paymentChannelOrder, "支付订单不存在"); // 更新订单信息 - paymentChannelOrder.setPaidTime(LocalDateTime.parse(notification.getSuccessTime(), formatter)); + paymentChannelOrder.setPaidTime(LocalDateTime.parse(notification.getSuccessTime(), WeChatPayProcessor.formatter)); paymentChannelOrder.setExtOrderNo(notification.getTransactionId()); BaseDomainEvent event = paymentChannelOrderAggregate.paid(paymentChannelOrder); this.sendEvent(event); diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/order/OrderApplicationService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/order/OrderApplicationService.java index c59021b..4806581 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/order/OrderApplicationService.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/order/OrderApplicationService.java @@ -16,6 +16,7 @@ import com.qniao.dam.domain.aggregate.product.repository.ProductRepository; import com.qniao.dam.domain.aggregate.productspec.entity.ProductSpec; import com.qniao.dam.domain.aggregate.productspec.repository.ProductSpecRepository; import com.qniao.dam.domain.service.order.SubmitOrderDomainService; +import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderPaymentStatusEnum; import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderStatusEnum; import com.qniao.dam.domian.aggregate.order.constant.OrderBelongingEnum; import com.qniao.dam.domian.aggregate.order.constant.OrderTypeEnum; @@ -193,7 +194,7 @@ public class OrderApplicationService { } private void fillMarriageBountyOrderInfo(Order order, List productList) { - MarriageBountyOrder marriageBountyOrder = marriageBountyOrderQueryService.queryBy(order.getUserId(), order.getMiId(), MarriageBountyOrderStatusEnum.MATCHMAKING); + MarriageBountyOrder marriageBountyOrder = marriageBountyOrderQueryService.queryBy(order.getUserId(), order.getMiId(), MarriageBountyOrderStatusEnum.MATCHMAKING, MarriageBountyOrderPaymentStatusEnum.PAID); order.setOrderBelonging(OrderBelongingEnum.CUSTOMER); MarriageInformation marriageInformation = marriageInformationDao.selectById(order.getMiId()); order.setOrderBelongName(marriageInformation.getNickName()); diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/IChannelPayService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/IChannelPayService.java index bdd9e80..df56b36 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/IChannelPayService.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/IChannelPayService.java @@ -3,6 +3,7 @@ package com.qniao.dam.application.service.paymentchannelorder.processor; import com.qniao.dam.api.command.paymentchannelorder.user.request.ThirdPartyField; import com.qniao.dam.application.service.paymentchannelorder.processor.wechat.WeChatPayProcessor; import com.qniao.dam.domain.aggregate.paymentchannelorder.entity.PaymentChannelOrder; +import com.qniao.dam.domain.aggregate.paymentorderrefund.entity.PaymentOrderRefund; import com.qniao.dam.domian.aggregate.paymentorder.constant.PaymentMethodEnum; import com.qniao.dau.application.response.WeChatAppletUserSessionVo; import com.qniao.framework.exception.BizException; @@ -24,4 +25,6 @@ public abstract class IChannelPayService { } public abstract Map prepay(PaymentChannelOrder paymentChannelOrder, String platformAppId, String openId); + + public abstract void refund(PaymentOrderRefund paymentOrderRefund); } diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/wechat/WeChatPayProcessor.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/wechat/WeChatPayProcessor.java index 039e769..ebd3749 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/wechat/WeChatPayProcessor.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/wechat/WeChatPayProcessor.java @@ -7,6 +7,8 @@ import com.qniao.dam.api.command.paymentchannelorder.user.request.ThirdPartyFiel import com.qniao.dam.application.service.paymentchannelorder.processor.IChannelPayService; import com.qniao.dam.application.service.paymentchannelorder.processor.wechat.utils.WXPayV3Util; import com.qniao.dam.domain.aggregate.paymentchannelorder.entity.PaymentChannelOrder; +import com.qniao.dam.domain.aggregate.paymentorderrefund.entity.PaymentOrderRefund; +import com.qniao.dam.domian.aggregate.paymentorderrefund.constant.PaymentOrderRefundStatusEnum; import com.qniao.dau.application.UecServerApplicationService; import com.qniao.dau.application.request.GetWechatSessionDto; import com.qniao.dau.application.response.WeChatAppletUserSessionVo; @@ -17,6 +19,8 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,11 +35,9 @@ public class WeChatPayProcessor extends IChannelPayService { private String mchId; @Value("${weixin.notifyurl}") private String notifyUrl; - - @Resource - private UecServerApplicationService uecServerApplicationService; @Resource private WXPayV3Util wxPayV3Util; + public static DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; @Override public Map prepay(PaymentChannelOrder paymentChannelOrder, @@ -87,8 +89,49 @@ public class WeChatPayProcessor extends IChannelPayService { log.info("returnMap________" + returnMap); return returnMap; } catch (Exception e) { - log.error("pay fail AppV3PayStrategyImpl {}", e.getMessage(), e); + log.error("发起微信预支付失败:{}", e.getMessage()); throw new BizException("发起微信预支付失败"); } } + + @Override + public void refund(PaymentOrderRefund paymentOrderRefund) { + try { + Map reqParams = new HashMap<>(); + reqParams.put("out_trade_no", paymentOrderRefund.getPaymentOrderId().toString()); + reqParams.put("amount", new HashMap() { + { + put("refund", paymentOrderRefund.getRefundFee().multiply(BigDecimal.valueOf(100)).intValue()); + put("total", paymentOrderRefund.getOrderAmount().multiply(BigDecimal.valueOf(100)).intValue()); + put("currency", "CNY"); + } + }); + JSONObject result = wxPayV3Util.doPostWeiXinV3(WXPayV3Util.api_v3_refund_url, JSONUtil.toJsonStr(reqParams)); + if (ObjectUtil.isNull(result.get("refund_id"))) { + throw new BizException("微信退款申请失败,请检查配置"); + } + paymentOrderRefund.setRefundId(result.getString("refund_id")); + String refundTime = result.getString("success_time"); + paymentOrderRefund.setRefundTime(LocalDateTime.parse(refundTime, WeChatPayProcessor.formatter)); + paymentOrderRefund.setStatus(transformRefundStatus(result.getString("status"))); + } catch (Exception e) { + log.error("发起微信退款申请失败:{}", e.getMessage()); + throw new BizException("发起微信退款申请失败"); + } + } + + private PaymentOrderRefundStatusEnum transformRefundStatus(String status) { + switch (status) { + case "SUCCESS": + return PaymentOrderRefundStatusEnum.SUCCESS; + case "CLOSED": + return PaymentOrderRefundStatusEnum.CLOSED; + case "PROCESSING": + return PaymentOrderRefundStatusEnum.PROCESSING; + case "ABNORMAL": + return PaymentOrderRefundStatusEnum.ABNORMAL; + default: + return null; + } + } } diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentorderrefund/PaymentOrderRefundApplicationService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentorderrefund/PaymentOrderRefundApplicationService.java new file mode 100644 index 0000000..19f6b28 --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentorderrefund/PaymentOrderRefundApplicationService.java @@ -0,0 +1,32 @@ +package com.qniao.dam.application.service.paymentorderrefund; + +import cn.hutool.core.collection.CollUtil; +import com.qniao.dam.application.service.paymentchannelorder.processor.IChannelPayService; +import com.qniao.dam.domain.aggregate.paymentorderrefund.PaymentOrderRefundAggregate; +import com.qniao.dam.domain.aggregate.paymentorderrefund.entity.PaymentOrderRefund; +import com.qniao.domain.BaseApplicationService; +import com.qniao.domain.BaseDomainEvent; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +@Service +public class PaymentOrderRefundApplicationService extends BaseApplicationService { + + @Resource + private PaymentOrderRefundAggregate paymentOrderRefundAggregate; + + public void refund(List paymentOrderRefundList) { + List eventList = new ArrayList<>(); + if (CollUtil.isNotEmpty(paymentOrderRefundList)) { + for (PaymentOrderRefund paymentOrderRefund : paymentOrderRefundList) { + IChannelPayService channelPayService = IChannelPayService.getService(paymentOrderRefund.getPaymentMethod()); + channelPayService.refund(paymentOrderRefund); + eventList.add(paymentOrderRefundAggregate.refund(paymentOrderRefund)); + } + } + this.sendEvent(eventList); + } +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/marriagebounty/MarriageBountyOrderAggregate.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/marriagebounty/MarriageBountyOrderAggregate.java index 22a1498..302fa5e 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/marriagebounty/MarriageBountyOrderAggregate.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/marriagebounty/MarriageBountyOrderAggregate.java @@ -2,6 +2,7 @@ package com.qniao.dam.domain.aggregate.marriagebounty; import com.qniao.dam.domain.aggregate.marriagebounty.entity.MarriageBountyOrder; import com.qniao.dam.domain.aggregate.marriagebounty.repository.MarriageBountyOrderRepository; +import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderPaymentStatusEnum; import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderStatusEnum; import com.qniao.dam.domian.aggregate.marriagebounty.event.MarriageBountyOrderCreatedEvent; import com.qniao.domain.BaseDomainEvent; @@ -18,6 +19,7 @@ public class MarriageBountyOrderAggregate { public BaseDomainEvent create(MarriageBountyOrder marriageBountyOrder) { marriageBountyOrder.setStatus(MarriageBountyOrderStatusEnum.MATCHMAKING); + marriageBountyOrder.setPaymentStatus(MarriageBountyOrderPaymentStatusEnum.PAID); marriageBountyOrderRepository.save(marriageBountyOrder); return TypeConvertUtils.convert(marriageBountyOrder, MarriageBountyOrderCreatedEvent.class); } @@ -25,4 +27,14 @@ public class MarriageBountyOrderAggregate { public void update(MarriageBountyOrder marriageBountyOrder) { marriageBountyOrderRepository.save(marriageBountyOrder); } + + public void applyRefund(MarriageBountyOrder marriageBountyOrder) { + marriageBountyOrder.setPaymentStatus(MarriageBountyOrderPaymentStatusEnum.BEING_REFUNDED); + marriageBountyOrderRepository.save(marriageBountyOrder); + } + + public void refund(MarriageBountyOrder marriageBountyOrder) { + marriageBountyOrder.setPaymentStatus(MarriageBountyOrderPaymentStatusEnum.REFUNDED); + marriageBountyOrderRepository.save(marriageBountyOrder); + } } diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/PaymentOrderRefundAggregate.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/PaymentOrderRefundAggregate.java new file mode 100644 index 0000000..cc7aeeb --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/PaymentOrderRefundAggregate.java @@ -0,0 +1,22 @@ +package com.qniao.dam.domain.aggregate.paymentorderrefund; + +import com.qniao.dam.domain.aggregate.paymentorderrefund.entity.PaymentOrderRefund; +import com.qniao.dam.domain.aggregate.paymentorderrefund.impl.PaymentOrderRefundRepository; +import com.qniao.dam.domian.aggregate.paymentorderrefund.event.PaymentOrderRefundRefundedEvent; +import com.qniao.domain.BaseDomainEvent; +import com.qniao.framework.utils.TypeConvertUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +public class PaymentOrderRefundAggregate { + + @Resource + private PaymentOrderRefundRepository paymentOrderRefundRepository; + + public BaseDomainEvent refund(PaymentOrderRefund paymentOrderRefund) { + paymentOrderRefundRepository.save(paymentOrderRefund); + return TypeConvertUtils.convert(paymentOrderRefund, PaymentOrderRefundRefundedEvent.class); + } +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/impl/PaymentOrderRefundRepository.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/impl/PaymentOrderRefundRepository.java new file mode 100644 index 0000000..c474adc --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentorderrefund/impl/PaymentOrderRefundRepository.java @@ -0,0 +1,7 @@ +package com.qniao.dam.domain.aggregate.paymentorderrefund.impl; + +import com.qniao.dam.domain.aggregate.paymentorderrefund.entity.PaymentOrderRefund; +import com.qniao.domain.Repository; + +public interface PaymentOrderRefundRepository extends Repository { +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/infrastructure/persistent/dao/domain/PaymentOrderRefundDao.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/infrastructure/persistent/dao/domain/PaymentOrderRefundDao.java new file mode 100644 index 0000000..06f10cd --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/infrastructure/persistent/dao/domain/PaymentOrderRefundDao.java @@ -0,0 +1,7 @@ +package com.qniao.dam.infrastructure.persistent.dao.domain; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.qniao.dam.domain.aggregate.paymentorderrefund.entity.PaymentOrderRefund; + +public interface PaymentOrderRefundDao extends BaseMapper { +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/infrastructure/persistent/repository/impl/PaymentOrderRefundRepositoryImpl.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/infrastructure/persistent/repository/impl/PaymentOrderRefundRepositoryImpl.java new file mode 100644 index 0000000..d405a31 --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/infrastructure/persistent/repository/impl/PaymentOrderRefundRepositoryImpl.java @@ -0,0 +1,31 @@ +package com.qniao.dam.infrastructure.persistent.repository.impl; + +import com.qniao.dam.domain.aggregate.paymentorderrefund.entity.PaymentOrderRefund; +import com.qniao.dam.domain.aggregate.paymentorderrefund.impl.PaymentOrderRefundRepository; +import com.qniao.dam.infrastructure.persistent.dao.domain.PaymentOrderRefundDao; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Objects; + +@Service +public class PaymentOrderRefundRepositoryImpl implements PaymentOrderRefundRepository { + + @Resource + private PaymentOrderRefundDao paymentOrderRefundDao; + + @Override + public PaymentOrderRefund load(Long id) { + return paymentOrderRefundDao.selectById(id); + } + + @Override + public Long save(PaymentOrderRefund entity) { + if (Objects.isNull(entity.getId()) || Objects.isNull(paymentOrderRefundDao.selectById(entity.getId()))) { + paymentOrderRefundDao.insert(entity); + } else { + paymentOrderRefundDao.updateById(entity); + } + return entity.getId(); + } +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/marriagebounty/MarriageBountyOrderQueryService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/marriagebounty/MarriageBountyOrderQueryService.java index f6f24c2..70ab0a0 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/marriagebounty/MarriageBountyOrderQueryService.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/marriagebounty/MarriageBountyOrderQueryService.java @@ -2,10 +2,13 @@ package com.qniao.dam.query.marriagebounty; import com.qniao.dam.api.query.marriagebounty.user.response.UserGetMarriageBountyOrderPreRefundInfoVo; import com.qniao.dam.domain.aggregate.marriagebounty.entity.MarriageBountyOrder; +import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderPaymentStatusEnum; import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderStatusEnum; public interface MarriageBountyOrderQueryService { - MarriageBountyOrder queryBy(Long userId, Long miId, MarriageBountyOrderStatusEnum status); + MarriageBountyOrder queryBy(Long userId, Long miId, MarriageBountyOrderStatusEnum status, MarriageBountyOrderPaymentStatusEnum paymentStatus); UserGetMarriageBountyOrderPreRefundInfoVo getMarriageBountyOrderPreRefundInfo(Long userId, Long miId); + + MarriageBountyOrder queryByOrderRel(Long orderRelId); } diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/marriagebounty/impl/MarriageBountyOrderQueryServiceImpl.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/marriagebounty/impl/MarriageBountyOrderQueryServiceImpl.java index bb1813e..5ea45c8 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/marriagebounty/impl/MarriageBountyOrderQueryServiceImpl.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/marriagebounty/impl/MarriageBountyOrderQueryServiceImpl.java @@ -4,9 +4,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.qniao.dam.api.query.marriagebounty.user.response.UserGetMarriageBountyOrderPreRefundInfoVo; import com.qniao.dam.domain.aggregate.marriagebounty.entity.MarriageBountyOrder; import com.qniao.dam.domain.aggregate.marriagebounty.entity.MarriageBountyOrderReward; +import com.qniao.dam.domain.aggregate.marriagebounty.repository.MarriageBountyOrderRepository; +import com.qniao.dam.domain.aggregate.marriagebounty.valueobj.MarriageBountyOrderRel; +import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderPaymentStatusEnum; import com.qniao.dam.domian.aggregate.marriagebount.constant.MarriageBountyOrderStatusEnum; import com.qniao.dam.domian.aggregate.product.constant.ProductSubCategoryEnum; import com.qniao.dam.infrastructure.persistent.dao.domain.MarriageBountyOrderDao; +import com.qniao.dam.infrastructure.persistent.dao.domain.MarriageBountyOrderRelDao; import com.qniao.dam.infrastructure.persistent.dao.domain.MarriageBountyOrderRewardDao; import com.qniao.dam.query.marriagebounty.MarriageBountyOrderQueryService; import org.springframework.stereotype.Service; @@ -21,14 +25,19 @@ public class MarriageBountyOrderQueryServiceImpl implements MarriageBountyOrderQ @Resource private MarriageBountyOrderDao marriageBountyOrderDao; @Resource + private MarriageBountyOrderRepository marriageBountyOrderRepository; + @Resource + private MarriageBountyOrderRelDao marriageBountyOrderRelDao; + @Resource private MarriageBountyOrderRewardDao marriageBountyOrderRewardDao; @Override - public MarriageBountyOrder queryBy(Long userId, Long miId, MarriageBountyOrderStatusEnum status) { + public MarriageBountyOrder queryBy(Long userId, Long miId, MarriageBountyOrderStatusEnum status, MarriageBountyOrderPaymentStatusEnum paymentStatus) { MarriageBountyOrder marriageBountyOrder = marriageBountyOrderDao.selectOne(new LambdaQueryWrapper() .eq(MarriageBountyOrder::getUserId, userId) .eq(MarriageBountyOrder::getMiId, miId) .eq(MarriageBountyOrder::getStatus, status) + .eq(MarriageBountyOrder::getPaymentStatus, paymentStatus) .orderByDesc(MarriageBountyOrder::getCreateTime) .last("limit 1")); if (Objects.nonNull(marriageBountyOrder)) { @@ -41,7 +50,7 @@ public class MarriageBountyOrderQueryServiceImpl implements MarriageBountyOrderQ @Override public UserGetMarriageBountyOrderPreRefundInfoVo getMarriageBountyOrderPreRefundInfo(Long userId, Long miId) { UserGetMarriageBountyOrderPreRefundInfoVo refundInfoVo = new UserGetMarriageBountyOrderPreRefundInfoVo(); - MarriageBountyOrder marriageBountyOrder = queryBy(userId, miId, MarriageBountyOrderStatusEnum.MATCHMAKING); + MarriageBountyOrder marriageBountyOrder = queryBy(userId, miId, MarriageBountyOrderStatusEnum.MATCHMAKING, MarriageBountyOrderPaymentStatusEnum.PAID); if (Objects.nonNull(marriageBountyOrder)) { refundInfoVo.setMarriageBountyOrderId(marriageBountyOrder.getId()); BigDecimal refundableMeetingFee = BigDecimal.ZERO; @@ -64,4 +73,16 @@ public class MarriageBountyOrderQueryServiceImpl implements MarriageBountyOrderQ } return refundInfoVo; } + + @Override + public MarriageBountyOrder queryByOrderRel(Long orderRelId) { + MarriageBountyOrder marriageBountyOrder = null; + MarriageBountyOrderRel orderRel = marriageBountyOrderRelDao.selectOne(new LambdaQueryWrapper() + .eq(MarriageBountyOrderRel::getOrderId, orderRelId) + .last("limit 1")); + if (Objects.nonNull(orderRel)) { + marriageBountyOrder = marriageBountyOrderRepository.load(orderRel.getMarriageBountyOrderId()); + } + return marriageBountyOrder; + } } diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentchannelorder/PaymentChannelOrderQueryService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentchannelorder/PaymentChannelOrderQueryService.java index ca38474..fa4fbc1 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentchannelorder/PaymentChannelOrderQueryService.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentchannelorder/PaymentChannelOrderQueryService.java @@ -1,4 +1,7 @@ package com.qniao.dam.query.paymentchannelorder; +import com.qniao.dam.domain.aggregate.paymentchannelorder.entity.PaymentChannelOrder; + public interface PaymentChannelOrderQueryService { + PaymentChannelOrder queryByTxnOrderId(Long txnOrderId); } diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentchannelorder/impl/PaymentChannelOrderQueryServiceImpl.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentchannelorder/impl/PaymentChannelOrderQueryServiceImpl.java index ab5e6ba..6a4cc48 100644 --- a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentchannelorder/impl/PaymentChannelOrderQueryServiceImpl.java +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentchannelorder/impl/PaymentChannelOrderQueryServiceImpl.java @@ -1,8 +1,23 @@ package com.qniao.dam.query.paymentchannelorder.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.qniao.dam.domain.aggregate.paymentchannelorder.entity.PaymentChannelOrder; +import com.qniao.dam.infrastructure.persistent.dao.domain.PaymentChannelOrderDao; import com.qniao.dam.query.paymentchannelorder.PaymentChannelOrderQueryService; import org.springframework.stereotype.Service; +import javax.annotation.Resource; + @Service public class PaymentChannelOrderQueryServiceImpl implements PaymentChannelOrderQueryService { + + @Resource + private PaymentChannelOrderDao paymentChannelOrderDao; + + @Override + public PaymentChannelOrder queryByTxnOrderId(Long txnOrderId) { + return paymentChannelOrderDao.selectOne(new LambdaQueryWrapper() + .eq(PaymentChannelOrder::getTxnOrderId, txnOrderId) + .last("limit 1")); + } } diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentorderrefund/PaymentOrderRefundQueryService.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentorderrefund/PaymentOrderRefundQueryService.java new file mode 100644 index 0000000..7645af2 --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentorderrefund/PaymentOrderRefundQueryService.java @@ -0,0 +1,7 @@ +package com.qniao.dam.query.paymentorderrefund; + +import java.util.List; + +public interface PaymentOrderRefundQueryService { + boolean checkRefunded(List tradeOrderIdList); +} diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentorderrefund/impl/PaymentOrderRefundQueryServiceImpl.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentorderrefund/impl/PaymentOrderRefundQueryServiceImpl.java new file mode 100644 index 0000000..60c1053 --- /dev/null +++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/query/paymentorderrefund/impl/PaymentOrderRefundQueryServiceImpl.java @@ -0,0 +1,36 @@ +package com.qniao.dam.query.paymentorderrefund.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.qniao.dam.domain.aggregate.paymentorderrefund.entity.PaymentOrderRefund; +import com.qniao.dam.domian.aggregate.paymentorderrefund.constant.PaymentOrderRefundStatusEnum; +import com.qniao.dam.infrastructure.persistent.dao.domain.PaymentOrderRefundDao; +import com.qniao.dam.query.paymentorderrefund.PaymentOrderRefundQueryService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +@Service +public class PaymentOrderRefundQueryServiceImpl implements PaymentOrderRefundQueryService { + + @Resource + private PaymentOrderRefundDao paymentOrderRefundDao; + + @Override + public boolean checkRefunded(List tradeOrderIdList) { + boolean status = true; + if (CollUtil.isNotEmpty(tradeOrderIdList)) { + for (Long tradeOrderId : tradeOrderIdList) { + if (paymentOrderRefundDao.selectCount(new LambdaQueryWrapper() + .eq(PaymentOrderRefund::getTradeOrderId, tradeOrderId) + .eq(PaymentOrderRefund::getStatus, PaymentOrderRefundStatusEnum.SUCCESS)) == 0) { + status = false; + break; + } + } + } + return status; + } + +}