diff --git a/dating-agency-mall-event/pom.xml b/dating-agency-mall-event/pom.xml
index daaf667..5973371 100644
--- a/dating-agency-mall-event/pom.xml
+++ b/dating-agency-mall-event/pom.xml
@@ -17,4 +17,21 @@
UTF-8
+
+
+ com.qniao
+ ddd-event
+ 0.0.1-SNAPSHOT
+
+
+ com.qniao
+ dating-agency-uec-constant
+ 0.0.1-SNAPSHOT
+
+
+ com.qniao
+ dating-agency-mall-constant
+ 0.0.1-SNAPSHOT
+
+
\ No newline at end of file
diff --git a/dating-agency-mall-event/src/main/java/com/qniao/dam/domian/aggregate/paymentchannelorder/event/PaymentChannelOrderPaidEvent.java b/dating-agency-mall-event/src/main/java/com/qniao/dam/domian/aggregate/paymentchannelorder/event/PaymentChannelOrderPaidEvent.java
new file mode 100644
index 0000000..06a5afd
--- /dev/null
+++ b/dating-agency-mall-event/src/main/java/com/qniao/dam/domian/aggregate/paymentchannelorder/event/PaymentChannelOrderPaidEvent.java
@@ -0,0 +1,27 @@
+package com.qniao.dam.domian.aggregate.paymentchannelorder.event;
+
+import com.qniao.dam.domian.aggregate.paymentorder.constant.PaymentMethodEnum;
+import com.qniao.domain.BaseDomainEvent;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class PaymentChannelOrderPaidEvent extends BaseDomainEvent {
+
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private Long txnOrderId;
+
+ private PaymentMethodEnum paymentMethod;
+
+ private LocalDateTime paidTime;
+}
diff --git a/dating-agency-mall-server/pom.xml b/dating-agency-mall-server/pom.xml
index 6b3ee33..a24e455 100644
--- a/dating-agency-mall-server/pom.xml
+++ b/dating-agency-mall-server/pom.xml
@@ -72,6 +72,11 @@
weixin-java-pay
3.3.4.B
+
+ com.qniao
+ dating-agency-mall-event
+ 0.0.1-SNAPSHOT
+
diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/notify/user/NotifyUserCommandController.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/notify/user/NotifyUserCommandController.java
new file mode 100644
index 0000000..74c2cd3
--- /dev/null
+++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/notify/user/NotifyUserCommandController.java
@@ -0,0 +1,34 @@
+package com.qniao.dam.api.command.notify.user;
+
+import cn.hutool.core.util.StrUtil;
+import com.qniao.dam.application.service.notify.NotifyApplicationService;
+import com.qniao.framework.annotation.IgnoreResponseAdvice;
+import com.qniao.framework.exception.BizException;
+import io.swagger.annotations.Api;
+import org.apache.commons.io.IOUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+@Api(tags = "应用支付通知")
+@RestController
+@RequestMapping("user")
+public class NotifyUserCommandController {
+
+ @Resource
+ private NotifyApplicationService notifyApplicationService;
+
+ @RequestMapping("/notify/wx")
+ @IgnoreResponseAdvice
+ public String wx(HttpServletRequest request) throws IOException {
+ String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
+ if (StrUtil.isBlank(xmlResult)) {
+ throw new BizException("回调内容不能为空");
+ }
+ return notifyApplicationService.wx(xmlResult);
+ }
+
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..4a3ccd3
--- /dev/null
+++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/notify/NotifyApplicationService.java
@@ -0,0 +1,104 @@
+package com.qniao.dam.application.service.notify;
+
+import cn.hutool.core.date.DateUtil;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
+import com.qniao.dam.domain.aggregate.paymentchannelorder.PaymentChannelOrderAggregate;
+import com.qniao.dam.domain.aggregate.paymentchannelorder.entity.PaymentChannelOrder;
+import com.qniao.dam.domian.aggregate.paymentchannelorder.constant.PaymentChannelOrderStatusEnum;
+import com.qniao.dam.infrastructure.persistent.dao.domain.PaymentChannelOrderDao;
+import com.qniao.domain.BaseApplicationService;
+import com.qniao.domain.BaseDomainEvent;
+import com.qniao.framework.exception.BizException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+@Service
+@Slf4j
+public class NotifyApplicationService extends BaseApplicationService {
+
+ @Value("${weixin.mchid}")
+ private String mchId;
+ @Value("${weixin.mchkey}")
+ private String mchKey;
+ private static final String WX_SUCCESS_RTN = "";
+ private static final String WX_FAIL_RTN = "";
+ public static final String RETURN_VALUE_SUCCESS = "SUCCESS";
+
+ @Resource
+ private PaymentChannelOrderDao paymentChannelOrderDao;
+ @Resource
+ private PaymentChannelOrderAggregate paymentChannelOrderAggregate;
+
+ public String wx(String xmlResult) {
+ try {
+ WxPayOrderNotifyResult result = parseOrderNotifyResult(xmlResult);
+ // 查询订单
+ PaymentChannelOrder paymentChannelOrder = paymentChannelOrderDao.selectById(result.getOutTradeNo());
+ Assert.notNull(paymentChannelOrder, "支付订单不存在");
+ // 验证业务数据是否正确
+ checkWxPayParams(result, paymentChannelOrder);
+ // 更新订单信息
+ paymentChannelOrder.setPaidTime(DateUtil.parseLocalDateTime(result.getTimeEnd(), "yyyyMMddHHmmss"));
+ paymentChannelOrder.setExtOrderNo(result.getTransactionId());
+ BaseDomainEvent event = paymentChannelOrderAggregate.paid(paymentChannelOrder);
+ this.sendEvent(event);
+ return WX_SUCCESS_RTN;
+ } catch (WxPayException e) {
+ log.error("微信回调结果异常,异常原因", e);
+ }
+ return WX_FAIL_RTN;
+ }
+
+ private WxPayOrderNotifyResult parseOrderNotifyResult(String xmlResult) throws WxPayException {
+ WxPayService wxPayService = new WxPayServiceImpl();
+ WxPayOrderNotifyResult result = null;
+ WxPayConfig wxPayConfig = new WxPayConfig();
+ wxPayConfig.setMchId(mchId);
+ wxPayConfig.setMchKey(mchKey);
+ wxPayService.setConfig(wxPayConfig);
+ // 解析并校验参数
+ try {
+ result = wxPayService.parseOrderNotifyResult(xmlResult);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ /**
+ * 验证微信参数
+ */
+ private void checkWxPayParams(WxPayOrderNotifyResult params, PaymentChannelOrder paymentChannelOrder) {
+ //校验结果是否成功
+ if (!RETURN_VALUE_SUCCESS.equalsIgnoreCase(params.getResultCode())
+ && RETURN_VALUE_SUCCESS.equalsIgnoreCase(params.getReturnCode())) {
+ String err = "returnCode=" + params.getReturnCode() + ",resultCode=" + params.getResultCode() +
+ ",errCode={}" + params.getErrCode() + ",errCodeDes={}" + params.getErrCodeDes();
+ log.error(err);
+ throw new BizException("支付结果为失败");
+ }
+ checkCommonParams(new BigDecimal(params.getTotalFee()), paymentChannelOrder);
+ }
+
+ /**
+ * 验证订单数据
+ */
+ private void checkCommonParams(BigDecimal amount, PaymentChannelOrder paymentChannelOrder) {
+ if (!PaymentChannelOrderStatusEnum.UNPAID.equals(paymentChannelOrder.getStatus())) {
+ throw new BizException("支付订单状态不正确");
+ }
+ if (!(paymentChannelOrder.getAmount().multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP).compareTo(amount) == 0)) {
+ throw new BizException("支付金额错误");
+ }
+ }
+}
diff --git a/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentchannelorder/PaymentChannelOrderAggregate.java b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentchannelorder/PaymentChannelOrderAggregate.java
index d4abef3..9c95c27 100644
--- a/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentchannelorder/PaymentChannelOrderAggregate.java
+++ b/dating-agency-mall-server/src/main/java/com/qniao/dam/domain/aggregate/paymentchannelorder/PaymentChannelOrderAggregate.java
@@ -3,6 +3,9 @@ package com.qniao.dam.domain.aggregate.paymentchannelorder;
import com.qniao.dam.domain.aggregate.paymentchannelorder.entity.PaymentChannelOrder;
import com.qniao.dam.domain.aggregate.paymentchannelorder.repository.PaymentChannelOrderRepository;
import com.qniao.dam.domian.aggregate.paymentchannelorder.constant.PaymentChannelOrderStatusEnum;
+import com.qniao.dam.domian.aggregate.paymentchannelorder.event.PaymentChannelOrderPaidEvent;
+import com.qniao.domain.BaseDomainEvent;
+import com.qniao.framework.utils.TypeConvertUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -17,4 +20,10 @@ public class PaymentChannelOrderAggregate {
paymentChannelOrder.setStatus(PaymentChannelOrderStatusEnum.UNPAID);
paymentChannelOrderRepository.save(paymentChannelOrder);
}
+
+ public BaseDomainEvent paid(PaymentChannelOrder paymentChannelOrder) {
+ paymentChannelOrder.setStatus(PaymentChannelOrderStatusEnum.PAID);
+ paymentChannelOrderRepository.save(paymentChannelOrder);
+ return TypeConvertUtils.convert(paymentChannelOrder, PaymentChannelOrderPaidEvent.class);
+ }
}