You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PayPal沙箱订阅支付未触发Subscription Activated事件且onApprove回调未执行问题

PayPal沙箱订阅支付未触发Subscription Activated事件且onApprove回调未执行问题

遇到这种订阅流程卡壳的情况确实头疼,我帮你从沙箱配置、前端代码、后端逻辑三个维度梳理排查方向和修复建议:


一、先排查PayPal沙箱环境的基础配置(最容易踩坑的点)

  1. 确认订阅计划状态
    你代码里硬编码的P-1CK57730EG37NBR3D6I这类Plan ID,必须在PayPal沙箱后台处于Active状态(不能是Draft)。登录PayPal沙箱开发者平台,进入Billing > Plans,检查对应计划的状态,确保已发布激活。

  2. 使用正确的沙箱测试资源

    • 必须用PayPal官方提供的沙箱测试卡号(不能用真实信用卡或随便填的假卡),比如:
      Visa卡号:4032037785858459
      有效期:12/28(未来任意日期)
      CVV:123
      邮编:95131
      
    • 测试用的买家账号必须是沙箱后台创建的Personal类型账号,不能用真实PayPal账号登录沙箱。
  3. Webhook配置验证
    你说后端只收到Subscription Created事件,没收到Activated,先做这两步:

    • 沙箱后台Webhook页面,确认已订阅BILLING.SUBSCRIPTION.ACTIVATED事件;
    • 用PayPal的Webhook Simulator手动触发BILLING.SUBSCRIPTION.ACTIVATED事件,测试后端是否能正常接收(本地开发需用ngrok暴露后端端口,PayPal无法访问localhost);
    • 务必确保后端正确验证PayPal Webhook的签名,签名验证失败会导致事件被忽略,PayPal官方有现成的签名验证SDK可以直接用。

二、前端代码的潜在问题修复

1. 优化PayPalScriptProvider配置

确保配置和订阅计划的参数匹配,比如添加货币类型(必须和你创建的Plan货币一致):

<PayPalScriptProvider
  options={{
    clientId: "AX6MHzLGwPRzkcrnhNw-JCT0aE1d5h8jiMcXqpG7PGD2lNiAM5UWLTeuo",
    vault: true,
    intent: "subscription",
    components: "buttons",
    currency: "USD", // 替换为你计划对应的货币
    locale: "en_US"
  }}
>
  {paypalButtons}
</PayPalScriptProvider>

2. 确保onApprove回调被触发

先添加日志确认回调是否真的没执行:

onApprove={async (data, actions) => {
  console.log("=== onApprove 已触发 ==="); // 先加这行日志看控制台输出
  console.log("[3] Approval Data:", data);
  try {
    if (!data.subscriptionID) {
      throw new Error("No subscription ID received from PayPal");
    }
    // 把后端请求和PayPal弹窗流程解耦,避免阻塞SDK自动关闭弹窗
    setTimeout(async () => {
      await handlePayPalSuccess(data.subscriptionID);
    }, 100);
    // 主动让PayPal完成流程关闭弹窗
    await actions.subscription.get();
  } catch (err) {
    console.error("onApprove error:", err);
    alert("Payment failed. Please try again.");
  }
}}

如果控制台没看到=== onApprove 已触发 ===,说明PayPal在创建订阅后没有完成授权流程,问题回到沙箱配置;如果有输出,说明是handlePayPalSuccess里的逻辑有问题。

3. 检查handlePayPalSuccess的字段映射

你在请求后端时做了字段重映射:

body: JSON.stringify({
  ...formData,
  paypalSubscriptionId: subscriptionId,
  website: formData.name,
  name: formData.username,
})

务必确认后端接口/auth/brand/signup期望的字段和你传递的完全一致,字段不匹配会导致请求失败,但这不会影响PayPal的onApprove触发,只是会导致前端跳转到错误页。


三、后端逻辑补充验证

  1. 后端收到paypalSubscriptionId后,主动调用PayPal的订阅详情API:

    GET https://api-m.sandbox.paypal.com/v1/billing/subscriptions/{subscription_id}
    

    检查返回的订阅状态是否为ACTIVE,如果是PENDING,说明沙箱里的订阅需要手动激活(极少数情况,比如试用计划设置了手动激活)。

  2. 确保后端的Webhook接收逻辑没有过滤掉BILLING.SUBSCRIPTION.ACTIVATED事件,并且正确处理了事件的签名验证。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 12:18:04