微信验签及支付回调

pull/1/head
czc 2 years ago
parent ecea6553c8
commit e535868c89

@ -0,0 +1,104 @@
package com.cyl.h5.controller;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.cyl.h5.pojo.dto.PayNotifyMessageDTO;
import com.cyl.h5.service.H5OrderService;
import com.cyl.wechat.WechatPayData;
import com.cyl.wechat.response.WeChatPayNotify;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
/**
* Controller
*
* @author sjm
* @date 2023-04-05
*/
@Api(description ="微信回调接口列表")
@RestController
@RequestMapping("/wechat/pay/callback")
public class PayNotifyController {
private static final Logger log = LoggerFactory.getLogger(PayNotifyController.class);
@Autowired
private H5OrderService h5OrderService;
private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
/**
*
* @param request
* @throws IOException
*/
@PostMapping("/weChatPayNotify")
public void weChatPayNotify(HttpServletRequest request) throws Exception {
log.info("收到了微信支付回调");
// 从请求头中获取信息
String timestamp = request.getHeader("Wechatpay-Timestamp");
String nonce = request.getHeader("Wechatpay-Nonce");
String signature = request.getHeader("Wechatpay-Signature");
String singType = request.getHeader("Wechatpay-Signature-Type");
String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial");
// 拿到请求体body
StringBuilder requestBody = new StringBuilder();
String line;
BufferedReader reader;
reader = request.getReader();
while (null != (line = reader.readLine())) {
requestBody.append(line);
}
// 构造 RequestParam
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(wechatPayCertificateSerialNumber)
.nonce(nonce)
.signature(signature)
.timestamp(timestamp)
.body(requestBody.toString())
.build();
//初始化了 RSAAutoCertificateConfig
Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(WechatPayData.merchantId)
.privateKeyFromPath(WechatPayData.privateKeyPath)
.merchantSerialNumber(WechatPayData.merchantSerialNumber)
.apiV3Key(WechatPayData.apiV3key)
.build();
// 初始化解析器 NotificationParser
NotificationParser parser = new NotificationParser((NotificationConfig) config);
// 以支付通知回调为例,验签、解密并转换成 Transaction
Transaction transaction = parser.parse(requestParam, Transaction.class);
PayNotifyMessageDTO message = new PayNotifyMessageDTO();
message.setTradeNo(transaction.getOutTradeNo());
message.setMemberId(Long.valueOf(transaction.getAttach()));
message.setTradeStatus(transaction.getTradeState());
if (StrUtil.isEmpty(transaction.getSuccessTime())){
throw new RuntimeException("微信支付回调失败");
}
message.setPayTime(formatter.parse(transaction.getSuccessTime().substring(0, transaction.getSuccessTime().indexOf("+"))));
message.setTradeNo(transaction.getTransactionId());
h5OrderService.payCallBack(message);
}
}

@ -0,0 +1,29 @@
package com.cyl.h5.pojo.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* @author: Jinxin
* @date: 2023/4/16 10:22
* @Description:
*/
@Getter
@Setter
public class MicroMallOrderSyncMsg {
@ApiModelProperty(
name = "orderId",
value = "订单id",
required = true,
dataType = "String"
)
private Long orderId;
@ApiModelProperty(
name = "type",
value = "type 0延时关闭 1新下单 2退款",
required = true,
dataType = "Integer"
)
private Integer type;
}

@ -1,5 +1,6 @@
package com.cyl.h5.pojo.dto; package com.cyl.h5.pojo.dto;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import lombok.Data; import lombok.Data;
import java.util.Date; import java.util.Date;
@ -23,7 +24,7 @@ public class PayNotifyMessageDTO {
* USERPAYING * USERPAYING
* PAYERROR * PAYERROR
*/ */
private Integer tradeStatus; private Transaction.TradeStateEnum tradeStatus;
/**支付时间**/ /**支付时间**/
private Date payTime; private Date payTime;

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyl.h5.pojo.dto.MicroMallOrderSyncMsg;
import com.cyl.h5.pojo.dto.OrderCreateDTO; import com.cyl.h5.pojo.dto.OrderCreateDTO;
import com.cyl.h5.pojo.dto.OrderProductListDTO; import com.cyl.h5.pojo.dto.OrderProductListDTO;
import com.cyl.h5.pojo.dto.PayNotifyMessageDTO; import com.cyl.h5.pojo.dto.PayNotifyMessageDTO;
@ -50,6 +51,7 @@ import com.ruoyi.common.enums.OrderStatus;
import com.ruoyi.common.enums.TradeStatusEnum; import com.ruoyi.common.enums.TradeStatusEnum;
import com.ruoyi.common.utils.IDGenerator; import com.ruoyi.common.utils.IDGenerator;
import com.ruoyi.framework.config.LocalDataUtil; import com.ruoyi.framework.config.LocalDataUtil;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@ -533,7 +535,7 @@ public class H5OrderService {
try{ try{
redisService.lock(redisKey, redisValue, 60); redisService.lock(redisKey, redisValue, 60);
//先判断回信回调的是否未success //先判断回信回调的是否未success
if (!TradeStatusEnum.SUCCESS.getStatus().equals(messageDTO.getTradeStatus())){ if (!Transaction.TradeStateEnum.SUCCESS.equals(messageDTO.getTradeStatus())){
log.error("【订单支付回调】订单状态不是支付成功状态" + messageDTO.getTradeStatus()); log.error("【订单支付回调】订单状态不是支付成功状态" + messageDTO.getTradeStatus());
throw new RuntimeException(); throw new RuntimeException();
} }

@ -0,0 +1,23 @@
package com.cyl.wechat.response;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* @author: Jinxin
* @date: 2023/4/18 23:04
* @Description:
*/
@Getter
@Setter
public class WeChatAmount {
@ApiModelProperty("CNY人民币境内商户号仅支持人民币。")
private String currency;
@ApiModelProperty("用户支付币种")
private String payer_currency;
@ApiModelProperty("用户支付金额,单位为分。(指使用优惠券的情况下,这里等于总金额-优惠券金额)")
private Long payer_total;
@ApiModelProperty("订单总金额,单位为分")
private Long total;
}

@ -0,0 +1,39 @@
package com.cyl.wechat.response;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* @author: Jinxin
* @date: 2023/4/18 23:03
* @Description:
*/
@Getter
@Setter
public class WeChatPayNotify {
@ApiModelProperty("微信支付系统生成的订单号")
private String transaction_id;
@ApiModelProperty("商户号")
private String mchid;
@ApiModelProperty("订单金额信息")
private WeChatAmount amount;
@ApiModelProperty("商户订单号")
private String out_trade_no;
@ApiModelProperty("交易类型")
private String trade_type;
@ApiModelProperty("交易状态")
private String trade_state;
@ApiModelProperty("交易状态描述")
private String trade_state_desc;
@ApiModelProperty("付款银行")
private String bank_type;
@ApiModelProperty("附加数据")
private String attach;
@ApiModelProperty("支付完成时间")
private String success_time;
@ApiModelProperty("支付者信息")
private WeChatPayer payer;
}

@ -0,0 +1,17 @@
package com.cyl.wechat.response;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* @author: Jinxin
* @date: 2023/4/18 23:03
* @Description:
*/
@Getter
@Setter
public class WeChatPayer {
@ApiModelProperty("用户标识")
private String openid;
}
Loading…
Cancel
Save