无法成功执行 Paypal webhook 验证

Sno*_*lor 1 paypal elixir webhooks phoenix-framework paypal-webhooks

我正在努力验证 Paypal webhook 数据,但我遇到了一个问题,它总是为验证状态返回 FAILURE。我想知道是不是因为这一切都发生在沙盒环境中,而 Paypal 不允许对沙盒 webhook 事件进行验证?我按照这个 API 文档来实现调用:https : //developer.paypal.com/docs/api/webhooks/v1/#verify-webhook-signature

相关代码(来自单独的 elixir 模块):

def call(conn, _opts) do
  conn
    |> extract_webhook_signature(conn.params)
    |> webhook_signature_valid?()
    |> # handle the result
end

defp extract_webhook_signature(conn, params) do
  %{
    auth_algo: get_req_header(conn, "paypal-auth-algo") |> Enum.at(0, ""),
    cert_url: get_req_header(conn, "paypal-cert-url") |> Enum.at(0, ""),
    transmission_id: get_req_header(conn, "paypal-transmission-id") |> Enum.at(0, ""),
    transmission_sig: get_req_header(conn, "paypal-transmission-sig") |> Enum.at(0, ""),
    transmission_time: get_req_header(conn, "paypal-transmission-time") |> Enum.at(0, ""),
    webhook_id: get_webhook_id(),
    webhook_event: params
  }
end

def webhook_signature_valid?(signature) do
  body = Jason.encode!(signature)
  case Request.post("/v1/notifications/verify-webhook-signature", body) do
    {:ok, %{verification_status: "SUCCESS"}} -> true
    _ -> false
  end
end
Run Code Online (Sandbox Code Playgroud)

我从 Paypal 收到了 200,这意味着 Paypal 收到了我的请求,并且能够正确解析它并通过验证运行它,但是它总是返回一个 FAILURE 验证状态,这意味着请求的真实性不能得到验证。我查看了我发布到他们端点的数据,看起来一切都是正确的,但由于某种原因,它没有经过验证。我将我发布到 API(来自extract_webhook_signature)的 JSON放入 Pastebin 中,因为它非常大:https : //pastebin.com/SYBT7muv

如果有人有这方面的经验并知道它为什么会失败,我很想听听。

Sno*_*lor 5

我解决了我自己的问题。Paypal 不会规范化他们的 webhook 验证请求。当您收到来自 Paypal 的 POST 时,请不要解析请求正文,然后再在验证调用中将其发送回给他们。如果您webhook_event有任何不同(即使字段的顺序不同),该事件将被视为无效,您将收到 FAILURE。您必须阅读原始 POST 正文并将该确切数据在您的webhook_event.

示例:如果您收到{"a":1,"b":2}并回发{..., "webhook_event":{"b":2,"a":1}, ...}(注意 json 字段与我们收到的内容和我们回发的内容的顺序不同),您将收到 FAILURE。你的帖子需要{..., "webhook_event":{"a":1,"b":2}, ...}