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

PayPal Webhook签名验证始终失败,返回{ verification_status: "FAILURE" }

PayPal Webhook签名验证始终返回FAILURE的解决方案

核心问题及修复步骤


1. 环境地址不匹配

你代码中调用的是沙盒环境API地址(https://api-m.sandbox.paypal.com),但你明确说明使用正式密钥和真实交易,正式环境必须切换到生产地址:https://api-m.paypal.com。不管是获取授权令牌还是验证签名的接口,都要替换为生产环境地址,沙盒地址仅适用于沙盒测试场景。

2. webhook_event参数错误

你当前传递的是req.body.resource,但PayPal的verify-webhook-signature接口要求webhook_event是完整的Webhook事件体(即整个req.body),而非仅resource部分。签名是基于完整事件内容生成的,仅传递resource会直接导致验证失败。


修正后的代码示例

获取授权令牌(正式环境)

const params = new URLSearchParams()
params.append('grant_type', 'client_credentials')

const getAuthToken = await axios.post(
  'https://api-m.paypal.com/v1/oauth2/token',
  params,
  {
    headers: { 'content-type': 'application/x-www-form-urlencoded' },
    auth: {
      username: '你的正式环境Client ID',
      password: '你的正式环境Secret',
    },
  },
)

验证Webhook签名(正式环境)

const verifyWebhook = await axios.post('https://api-m.paypal.com/v1/notifications/verify-webhook-signature', {
  auth_algo: req.headers['paypal-auth-algo'],
  cert_url: req.headers['paypal-cert-url'],
  transmission_id: req.headers['paypal-transmission-id'],
  transmission_sig: req.headers['paypal-transmission-sig'],
  transmission_time: req.headers['paypal-transmission-time'],
  webhook_id: '你的正式环境Webhook ID',
  webhook_event: req.body, // 传递完整事件体,而非req.body.resource
}, {
  headers: {
    Authorization: `Bearer ${getAuthToken.data.access_token}`,
    'Content-Type': 'application/json',
  },
})

console.log(verifyWebhook.data);

额外检查点

  • 确认Webhook ID是正式环境生成的,而非沙盒环境的ID;
  • 确保接收Webhook的服务器没有修改原始请求体(比如解析后重新序列化时改变了空格、字段顺序等),签名验证对内容一致性要求极高,任何格式变动都会导致失败;
  • 检查请求头是否完整传递,没有遗漏PayPal的自定义头字段。

内容的提问来源于stack exchange,提问作者Darkbound

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:30:40