Browse Source

基础配置

master
张彭杰 1 year ago
parent
commit
82dea98802
5 changed files with 118 additions and 21 deletions
  1. 9
      dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/notify/user/NotifyUserCommandController.java
  2. 21
      dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/notify/user/response/WeChatNotification.java
  3. 11
      dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/notify/user/response/WeChatNotificationVo.java
  4. 42
      dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/notify/NotifyApplicationService.java
  5. 56
      dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/wechat/utils/WXPayV3Util.java

9
dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/notify/user/NotifyUserCommandController.java

@ -1,6 +1,7 @@
package com.qniao.dam.api.command.notify.user;
import cn.hutool.core.util.StrUtil;
import com.qniao.dam.api.command.notify.user.response.WeChatNotificationVo;
import com.qniao.dam.application.service.notify.NotifyApplicationService;
import com.qniao.framework.annotation.IgnoreResponseAdvice;
import com.qniao.framework.exception.BizException;
@ -23,12 +24,8 @@ public class NotifyUserCommandController {
@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);
public WeChatNotificationVo wx(HttpServletRequest request){
return notifyApplicationService.wx(request);
}
}

21
dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/notify/user/response/WeChatNotification.java

@ -0,0 +1,21 @@
package com.qniao.dam.api.command.notify.user.response;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class WeChatNotification {
private String code;
private String message;
@ApiModelProperty("微信支付系统生成的订单号")
private String transactionId;
@ApiModelProperty("商户系统内部订单号")
private String outTradeNo;
@ApiModelProperty("支付完成时间")
private String successTime;
}

11
dating-agency-mall-server/src/main/java/com/qniao/dam/api/command/notify/user/response/WeChatNotificationVo.java

@ -0,0 +1,11 @@
package com.qniao.dam.api.command.notify.user.response;
import lombok.Data;
@Data
public class WeChatNotificationVo {
private String code = "FAIL";
private String message = "失败";
}

42
dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/notify/NotifyApplicationService.java

@ -6,6 +6,9 @@ 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.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.utils.WXPayV3Util;
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;
@ -13,14 +16,18 @@ 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 com.qniao.framework.utils.TypeConvertUtils;
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 javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Service
@Slf4j
@ -34,29 +41,34 @@ public class NotifyApplicationService extends BaseApplicationService {
private static final String WX_FAIL_RTN = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
public static final String RETURN_VALUE_SUCCESS = "SUCCESS";
public DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
@Resource
private PaymentChannelOrderDao paymentChannelOrderDao;
@Resource
private PaymentChannelOrderAggregate paymentChannelOrderAggregate;
@Resource
private WXPayV3Util wxPayV3Util;
public String wx(String xmlResult) {
public WeChatNotificationVo wx(HttpServletRequest request) {
WeChatNotificationVo notificationVo = new WeChatNotificationVo();
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) {
WeChatNotification notification = wxPayV3Util.weChatNotificationHandler(request);
notificationVo = TypeConvertUtils.convert(notification, WeChatNotificationVo.class);
if (RETURN_VALUE_SUCCESS.equals(notification.getCode())) {
// 查询订单
PaymentChannelOrder paymentChannelOrder = paymentChannelOrderDao.selectById(notification.getOutTradeNo());
Assert.notNull(paymentChannelOrder, "支付订单不存在");
// 更新订单信息
paymentChannelOrder.setPaidTime(LocalDateTime.parse(notification.getSuccessTime(), formatter));
paymentChannelOrder.setExtOrderNo(notification.getTransactionId());
BaseDomainEvent event = paymentChannelOrderAggregate.paid(paymentChannelOrder);
this.sendEvent(event);
}
} catch (Exception e) {
log.error("微信回调结果异常,异常原因", e);
}
return WX_FAIL_RTN;
return notificationVo;
}
private WxPayOrderNotifyResult parseOrderNotifyResult(String xmlResult) throws WxPayException {

56
dating-agency-mall-server/src/main/java/com/qniao/dam/application/service/paymentchannelorder/processor/wechat/utils/WXPayV3Util.java

@ -1,12 +1,16 @@
package com.qniao.dam.application.service.paymentchannelorder.processor.wechat.utils;
import com.alibaba.fastjson.JSONObject;
import com.qniao.dam.api.command.notify.user.response.WeChatNotification;
import com.qniao.framework.exception.BizException;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
@ -20,6 +24,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
@ -226,4 +231,55 @@ public class WXPayV3Util {
throw new RuntimeException("无效的密钥格式");
}
}
public WeChatNotification weChatNotificationHandler(HttpServletRequest request) {
WeChatNotification weChatNotification = new WeChatNotification();
try {
BufferedReader br = request.getReader();
String str = null;
StringBuilder sb = new StringBuilder();
while ((str = br.readLine()) != null) {
sb.append(str);
}
// 构建request传入必要参数
NotificationRequest requests = new NotificationRequest.Builder()
.withSerialNumber(request.getHeader("Wechatpay-Serial"))
.withNonce(request.getHeader("Wechatpay-Nonce"))
.withTimestamp(request.getHeader("Wechatpay-Timestamp"))
.withSignature(request.getHeader("Wechatpay-Signature"))
.withBody(String.valueOf(sb))
.build();
//验签
NotificationHandler handler = new NotificationHandler(verifier, v3Key.getBytes(StandardCharsets.UTF_8));
//解析请求体
Notification notification = handler.parse(requests);
String decryptData = notification.getDecryptData();
//解析
JSONObject jsonObject = JSONObject.parseObject(decryptData);
//支付状态交易状态枚举值 SUCCESS支付成功 REFUND转入退款 NOTPAY未支付 CLOSED已关闭 REVOKED已撤销付款码支付
// USERPAYING用户支付中付款码支付 PAYERROR支付失败(其他原因如银行返回失败)
String trade_state = String.valueOf(jsonObject.get("trade_state"));
if (trade_state.equals("SUCCESS")) {
//订单号
String outTradeNo = String.valueOf(jsonObject.get("out_trade_no"));
//微信支付微信生成的订单号
String transactionId = String.valueOf(jsonObject.get("transaction_id"));
//支付时间
String successTime = String.valueOf(jsonObject.get("success_time"));
weChatNotification.setOutTradeNo(outTradeNo);
weChatNotification.setTransactionId(transactionId);
weChatNotification.setSuccessTime(successTime);
//此处处理业务
weChatNotification.setCode("SUCCESS");
weChatNotification.setMessage("成功");
} else {
weChatNotification.setCode("FAIL");
weChatNotification.setMessage("失败");
}
} catch (Exception e) {
e.printStackTrace();
}
return weChatNotification;
}
}
Loading…
Cancel
Save