diff --git a/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/client/req/AdapayCallbackParseReq.java b/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/client/req/AdapayCallbackParseReq.java index c3285433a..95bcbb284 100644 --- a/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/client/req/AdapayCallbackParseReq.java +++ b/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/client/req/AdapayCallbackParseReq.java @@ -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; } diff --git a/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/service/callback/AdapayPayCallbackService.java b/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/service/callback/AdapayPayCallbackService.java index d3d4962e3..edf3e02a2 100644 --- a/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/service/callback/AdapayPayCallbackService.java +++ b/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/service/callback/AdapayPayCallbackService.java @@ -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 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); diff --git a/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/service/callback/AdapayRefundCallbackService.java b/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/service/callback/AdapayRefundCallbackService.java index 2ca7ca7ed..9cc164bef 100644 --- a/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/service/callback/AdapayRefundCallbackService.java +++ b/daxpay-channel/daxpay-channel-adapay/src/main/java/cn/daxpay/open/channel/adapay/service/callback/AdapayRefundCallbackService.java @@ -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 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());