package com.ruoyi.payment.interfaces.controller;
|
|
import com.ruoyi.common.annotation.Anonymous;
|
import com.ruoyi.payment.application.service.PaymentNotifyService;
|
import com.ruoyi.payment.infrastructure.channel.alipay.AlipayUtil;
|
import com.ruoyi.payment.infrastructure.channel.wechat.WxPayUtil;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.bind.annotation.*;
|
|
import javax.servlet.http.HttpServletRequest;
|
import java.io.BufferedReader;
|
import java.util.Enumeration;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* 渠道回调接口控制器
|
*
|
* @author ruoyi
|
*/
|
@Slf4j
|
@RestController
|
@RequestMapping("/api/pay/notify")
|
public class PaymentNotifyController {
|
|
@Autowired
|
private WxPayUtil wxPayUtil;
|
|
@Autowired
|
private AlipayUtil alipayUtil;
|
|
@Autowired
|
private PaymentNotifyService paymentNotifyService;
|
|
/**
|
* 微信支付回调
|
*/
|
@Anonymous
|
@PostMapping("/wechat/notify")
|
public String wechatNotify(HttpServletRequest request) {
|
try {
|
log.info("接收到微信支付回调");
|
|
// 1. 读取XML报文
|
String xmlData = readRequestBody(request);
|
log.info("微信回调报文: {}", xmlData);
|
|
// 2. 解析XML为Map
|
Map<String, String> params = wxPayUtil.xmlToMap(xmlData);
|
|
// 3. 验证签名
|
if (!wxPayUtil.verifySign(params)) {
|
log.error("微信回调签名验证失败");
|
return wxPayUtil.buildFailResponse("签名验证失败");
|
}
|
|
log.info("微信回调签名验证通过");
|
|
// 4. 处理回调(更新订单状态、触发业务回调)
|
paymentNotifyService.processWechatNotify(params, xmlData);
|
|
// 5. 返回微信要求的XML应答
|
return wxPayUtil.buildSuccessResponse();
|
} catch (Exception e) {
|
log.error("处理微信回调失败", e);
|
return wxPayUtil.buildFailResponse("处理失败");
|
}
|
}
|
|
@Anonymous
|
@GetMapping("/hello")
|
public String hello() {
|
return "hello";
|
}
|
|
/**
|
* 支付宝回调
|
*/
|
@Anonymous
|
@PostMapping("/alipay/notify")
|
public String alipayNotify(HttpServletRequest request) {
|
try {
|
log.info("接收到支付宝回调");
|
|
// 1. 获取所有参数
|
Map<String, String> params = new HashMap<>();
|
Enumeration<String> parameterNames = request.getParameterNames();
|
while (parameterNames.hasMoreElements()) {
|
String name = parameterNames.nextElement();
|
params.put(name, request.getParameter(name));
|
}
|
|
log.info("支付宝回调参数: {}", params);
|
|
// 2. 验证签名
|
if (!alipayUtil.verifySign(params)) {
|
log.error("支付宝回调签名验证失败");
|
return "fail";
|
}
|
|
log.info("支付宝回调签名验证通过");
|
|
// 3. 处理回调(更新订单状态、触发业务回调)
|
paymentNotifyService.processAlipayNotify(params);
|
|
// 4. 返回支付宝要求的应答
|
return "success";
|
} catch (Exception e) {
|
log.error("处理支付宝回调失败", e);
|
return "fail";
|
}
|
}
|
|
/**
|
* 第三方支付宝回调(GET请求)
|
* <p>
|
* 第三方支付宝通过GET方式回调,参数通过URL传递
|
* <p>
|
* 参数格式:
|
* method=xxx&APPID=xxx&PaidMoneyType=xxx&PaidMoney=xxx&PaidRemarks=xxx&UnixTime=xxx&Sign=xxx
|
* <p>
|
* 参数说明:
|
* - method: 方法名
|
* - APPID: 应用ID
|
* - PaidMoneyType: 支付类型
|
* - PaidMoney: 支付金额(单位:分)
|
* - PaidRemarks: 支付备注(包含订单号和交易号信息)
|
* - UnixTime: 时间戳
|
* - Sign: 签名
|
* <p>
|
* 示例:
|
* GET /api/pay/notify/alipay/thirdparty?method=alipay.pay&APPID=123456&PaidMoneyType=alipay&PaidMoney=100&PaidRemarks=1234567890&UnixTime=1638360000&Sign=abc123
|
*/
|
@Anonymous
|
@GetMapping("/alipay/thirdparty")
|
public String alipayThirdPartyNotify(HttpServletRequest request) {
|
try {
|
log.info("接收到第三方支付宝回调(GET请求)");
|
|
// 1. 获取所有参数
|
Map<String, String> params = new HashMap<>();
|
Enumeration<String> parameterNames = request.getParameterNames();
|
while (parameterNames.hasMoreElements()) {
|
String name = parameterNames.nextElement();
|
params.put(name, request.getParameter(name));
|
}
|
|
log.info("第三方支付宝回调参数: {}", params);
|
|
// 2. 第三方支付宝不需要验签,或者根据第三方平台的签名规则进行验证
|
// 这里直接处理,如果需要验签可以在Service层添加
|
|
// 3. 处理回调(更新订单状态、触发业务回调)
|
paymentNotifyService.processAlipayThirdPartyNotify(params);
|
|
// 4. 返回第三方支付宝要求的应答
|
return "success";
|
} catch (Exception e) {
|
log.error("处理第三方支付宝回调失败", e);
|
return "fail";
|
}
|
}
|
|
/**
|
* 第三方微信回调(GET请求)
|
* <p>
|
* 第三方微信通过GET方式回调,参数通过URL传递
|
* <p>
|
* 参数格式:
|
* method=xxx&APPID=xxx&PaidMoneyType=xxx&PaidMoney=xxx&PaidRemarks=xxx&UnixTime=xxx
|
* <p>
|
* 参数说明:
|
* - method: 方法名
|
* - APPID: 应用ID
|
* - PaidMoneyType: 支付类型
|
* - PaidMoney: 支付金额(单位:分)
|
* - PaidRemarks: 支付备注(包含订单号和交易号信息)
|
* - UnixTime: 时间戳
|
* <p>
|
* 示例:
|
* GET /api/pay/notify/wechat/thirdparty?method=wechat.pay&APPID=123456&PaidMoneyType=wechat&PaidMoney=100&PaidRemarks=1234567890&UnixTime=1638360000
|
*/
|
@Anonymous
|
@GetMapping("/wechat/thirdparty")
|
public String wechatThirdPartyNotify(HttpServletRequest request) {
|
try {
|
log.info("接收到第三方微信回调(GET请求)");
|
|
// 1. 获取所有参数
|
Map<String, String> params = new HashMap<>();
|
Enumeration<String> parameterNames = request.getParameterNames();
|
while (parameterNames.hasMoreElements()) {
|
String name = parameterNames.nextElement();
|
params.put(name, request.getParameter(name));
|
}
|
|
log.info("第三方微信回调参数: {}", params);
|
|
// 2. 第三方微信不需要验签,或者根据第三方平台的签名规则进行验证
|
// 这里直接处理,如枟需要验签可以在Service层添加
|
|
// 3. 处理回调(更新订单状态、触发业务回调)
|
paymentNotifyService.processWechatThirdPartyNotify(params);
|
|
// 4. 返回第三方微信要求的应答
|
return "success";
|
} catch (Exception e) {
|
log.error("处理第三方微信回调失败", e);
|
return "fail";
|
}
|
}
|
|
/**
|
* 读取请求体
|
*/
|
private String readRequestBody(HttpServletRequest request) throws Exception {
|
StringBuilder sb = new StringBuilder();
|
try (BufferedReader reader = request.getReader()) {
|
String line;
|
while ((line = reader.readLine()) != null) {
|
sb.append(line);
|
}
|
}
|
return sb.toString();
|
}
|
}
|