mirror of
https://gitee.com/dromara/dax-pay
synced 2026-08-10 06:46:04 +08:00
fix(adapay): 回调改用表单参数 data/sign, 修复 body 为空导致回调失败
Adapay 异步通知为 application/x-www-form-urlencoded 表单格式(data+sign), 原实现 getBody() 因 Servlet 已消费 inputStream 读到空串。 - CallbackParseReq: body 字段 -> data + sign 两字段 - AdapayPayCallbackService/AdapayRefundCallbackService: getBody -> request.getParameter 提取 data+sign
This commit is contained in:
@@ -6,13 +6,20 @@ import lombok.Data;
|
||||
/// # Adapay 回调验签解析请求(主应用 → 子应用)
|
||||
///
|
||||
/// 与子应用 dax-pay-channel-two 的 `AdapayCallbackParseReq` 镜像。
|
||||
/// 主应用组装凭证(publicKey 为空时子应用用全局平台公钥) + 原始 body 下发, 子应用验签并解析。
|
||||
/// 主应用从异步通知 HTTP 请求中提取表单参数 data + sign, 连同通道凭证下发, 子应用验签并解析。
|
||||
///
|
||||
/// Adapay 异步通知为 application/x-www-form-urlencoded 表单格式, 含两个字段:
|
||||
/// - data: 业务数据 JSON 明文(待验签内容)
|
||||
/// - sign: data 的 SHA1withRSA 签名(Base64)
|
||||
@Data
|
||||
public class AdapayCallbackParseReq {
|
||||
|
||||
/// 通道调用凭证(用于获取平台公钥验签, publicKey 为空时子应用用默认公钥)
|
||||
private AdapaySdkCredential credential;
|
||||
|
||||
/// 回调原始 body(Adapay 异步通知 JSON: {data, signature})
|
||||
private String body;
|
||||
/// 回调业务数据 JSON 明文(表单参数 data, 待验签内容)
|
||||
private String data;
|
||||
|
||||
/// 回调签名(表单参数 sign, 对 data 的 SHA1withRSA Base64 签名)
|
||||
private String sign;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import cn.daxpay.open.payment.trade.record.service.PayCallbackRecordService;
|
||||
import cn.daxpay.open.payment.trade.runtime.service.callback.PayCallbackService;
|
||||
import cn.daxpay.open.platform.core.enums.pay.notice.CallbackStatusEnum;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -38,22 +37,24 @@ public class AdapayPayCallbackService {
|
||||
|
||||
/// 支付回调处理
|
||||
public String payHandle(String channelMchNo, HttpServletRequest request) {
|
||||
// 1. 提取回调原始 body
|
||||
String body = JakartaServletUtil.getBody(request);
|
||||
// 1. 提取回调表单参数(Adapay 异步通知为 application/x-www-form-urlencoded, 含 data + sign)
|
||||
String data = request.getParameter("data");
|
||||
String sign = request.getParameter("sign");
|
||||
Map<String, Object> notify = new HashMap<>();
|
||||
notify.put("body", body);
|
||||
if (StrUtil.isBlank(body)) {
|
||||
log.error("Adapay 支付回调: body 为空");
|
||||
notify.put("data", data);
|
||||
notify.put("sign", sign);
|
||||
if (StrUtil.isBlank(data) || StrUtil.isBlank(sign)) {
|
||||
log.error("Adapay 支付回调: data 或 sign 为空");
|
||||
CallbackData failData = new CallbackData();
|
||||
failData.setCallbackData(notify);
|
||||
failData.setCallbackStatus(CallbackStatusEnum.FAIL);
|
||||
failData.setCallbackErrorMsg("Adapay 支付回调: body 为空");
|
||||
failData.setCallbackErrorMsg("Adapay 支付回调: data 或 sign 为空");
|
||||
payCallbackRecordService.savePay(channelMchNo, failData);
|
||||
return AdapayCode.NOTIFY_FAIL;
|
||||
}
|
||||
|
||||
// 2. 转发子应用验签解析(publicKey 为空, 子应用用全局默认平台公钥)
|
||||
AdapayCallbackParseResp resp = parse(body, false);
|
||||
AdapayCallbackParseResp resp = parse(data, sign, false);
|
||||
if (resp == null || !Boolean.TRUE.equals(resp.getSuccess())) {
|
||||
log.error("Adapay 支付回调验签失败");
|
||||
CallbackData failData = new CallbackData();
|
||||
@@ -93,11 +94,12 @@ public class AdapayPayCallbackService {
|
||||
}
|
||||
|
||||
/// 转发子应用验签解析
|
||||
private AdapayCallbackParseResp parse(String body, boolean refund) {
|
||||
private AdapayCallbackParseResp parse(String data, String sign, boolean refund) {
|
||||
AdapaySdkCredential credential = new AdapaySdkCredential();
|
||||
AdapayCallbackParseReq req = new AdapayCallbackParseReq();
|
||||
req.setCredential(credential);
|
||||
req.setBody(body);
|
||||
req.setData(data);
|
||||
req.setSign(sign);
|
||||
var result = refund
|
||||
? adapayChannelClient.parseRefundCallback(req)
|
||||
: adapayChannelClient.parsePayCallback(req);
|
||||
|
||||
@@ -10,7 +10,6 @@ import cn.daxpay.open.payment.trade.record.service.PayCallbackRecordService;
|
||||
import cn.daxpay.open.payment.trade.runtime.service.callback.RefundCallbackService;
|
||||
import cn.daxpay.open.platform.core.enums.pay.notice.CallbackStatusEnum;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -22,7 +21,7 @@ import java.util.Objects;
|
||||
|
||||
/// # Adapay 退款回调处理服务
|
||||
///
|
||||
/// Adapay 退款异步通知 → 主应用接收原始 body → 转发子应用验签与解析 →
|
||||
/// Adapay 退款异步通知(表单参数 data + sign) → 主应用提取表单参数 → 转发子应用验签与解析 →
|
||||
/// 构建 [RefundCallbackData] 交由 [RefundCallbackService] 更新退款单状态。
|
||||
///
|
||||
/// 验签只需全局平台公钥(子应用内置默认), 主应用零加密代码。
|
||||
@@ -37,15 +36,18 @@ public class AdapayRefundCallbackService {
|
||||
|
||||
/// 退款回调处理
|
||||
public String refundHandle(String channelMchNo, HttpServletRequest request) {
|
||||
String body = JakartaServletUtil.getBody(request);
|
||||
// 提取回调表单参数(Adapay 异步通知为 application/x-www-form-urlencoded, 含 data + sign)
|
||||
String data = request.getParameter("data");
|
||||
String sign = request.getParameter("sign");
|
||||
Map<String, Object> notify = new HashMap<>();
|
||||
notify.put("body", body);
|
||||
if (StrUtil.isBlank(body)) {
|
||||
log.error("Adapay 退款回调: body 为空");
|
||||
notify.put("data", data);
|
||||
notify.put("sign", sign);
|
||||
if (StrUtil.isBlank(data) || StrUtil.isBlank(sign)) {
|
||||
log.error("Adapay 退款回调: data 或 sign 为空");
|
||||
RefundCallbackData failData = new RefundCallbackData();
|
||||
failData.setCallbackData(notify);
|
||||
failData.setCallbackStatus(CallbackStatusEnum.FAIL);
|
||||
failData.setCallbackErrorMsg("Adapay 退款回调: body 为空");
|
||||
failData.setCallbackErrorMsg("Adapay 退款回调: data 或 sign 为空");
|
||||
payCallbackRecordService.saveRefund(channelMchNo, failData);
|
||||
return AdapayCode.NOTIFY_FAIL;
|
||||
}
|
||||
@@ -54,7 +56,8 @@ public class AdapayRefundCallbackService {
|
||||
AdapaySdkCredential credential = new AdapaySdkCredential();
|
||||
AdapayCallbackParseReq req = new AdapayCallbackParseReq();
|
||||
req.setCredential(credential);
|
||||
req.setBody(body);
|
||||
req.setData(data);
|
||||
req.setSign(sign);
|
||||
var result = adapayChannelClient.parseRefundCallback(req);
|
||||
if (result.getCode() != 0) {
|
||||
log.error("Adapay 退款回调: 子应用解析失败: {}", result.getMsg());
|
||||
|
||||
Reference in New Issue
Block a user