【问题标题】:How to verify a Paypal webhook notification DIY style (without using Paypal SDK)如何验证 Paypal webhook 通知 DIY 样式(不使用 Paypal SDK)
【发布时间】:2020-11-02 08:05:05
【问题描述】:

集成 Paypal 的智能按钮后,我无法验证 Paypal 发送的 webhook 通知。我发现的示例要么已经过时,要么不起作用。

有没有办法验证 webhook 通知,最好是 DIY 方式(即无需使用庞大而复杂的 Paypal API)?

【问题讨论】:

    标签: php paypal paypal-webhooks


    【解决方案1】:

    对此做出响应以节省潜在的麻烦,但上述示例不起作用,因为需要将身份验证令牌与您对证书文件“file_get_contents($header['Paypal-Cert-Url'])”的获取请求一起发送将无法单独工作。

    只需在标头中包含您的身份验证令牌即可。

    【讨论】:

    • 我从 2020 年中期开始使用此代码,完全如图所示,它的工作原理绝对如图所示。 100%。
    【解决方案2】:

    据我所知,此代码只是实际有效的代码。我在堆栈溢出中发现的所有其他示例都不起作用,因为在编写签名字符串时,它们没有传递 webhook 本身 的 ID,而是使用 webhook 事件的 ID,因此验证将失败。

    在 Paypal 的开发人员后端添加 webhook 后,将生成 webhook ID。创建 webhook 后,您将在已安装的 webhook 列表中看到它的 id。

    剩下的很简单:我们获取标头和 HTTP 正文,并使用 Paypal 的配方组成签名:

    为了生成签名,PayPal 将这些签名连接并分开 带有竖线 (|) 字符的项目。

    “这些项目”是:传输 id、传输日期、webhook id 和 HTTP 正文上的 CRC。前两个可以在请求的header中找到,开发者后端的webhook id(当然那个id永远不会改变),CRC计算如下图。

    证书的位置也在标头中,因此我们加载它并提取私钥。

    最后要注意的是:Paypal 提供的算法名称(同样在标头字段中)与 PHP 所理解的不完全相同。 Paypal 将其称为“sha256WithRSA”,但 openssl_verify 将期望“sha256WithRSAEncryption”。

    // get request headers
    $headers=apache_request_headers();
    
    // get http payload
    $body=file_get_contents('php://input');
    
    // compose signature string: The third part is the ID of the webhook ITSELF(!),
    // NOT the ID of the webhook event sent. You find the ID of the webhook
    // in Paypal's developer backend where you have created the webhook
    $data=
        $headers['Paypal-Transmission-Id'].'|'.
        $headers['Paypal-Transmission-Time'].'|'.
        '[THE_ID_OF_THE_WEBHOOK_ACCORDING_TO_DEVELOPER_BACKEND]'.'|'.
        crc32($body);
    
    // load certificate and extract public key
    $pubKey=openssl_pkey_get_public(file_get_contents($headers['Paypal-Cert-Url']));
    $key=openssl_pkey_get_details($pubKey)['key'];
    
    // verify data against provided signature 
    $result=openssl_verify(
        $data,
        base64_decode($headers['Paypal-Transmission-Sig']),
        $key,
        'sha256WithRSAEncryption'
    );
    
    if ($result==1) {
        // webhook notification is verified
        ...
    }
    elseif ($result==0) {
        // webhook notification is NOT verified
        ...
    }
    else {
        // there was an error verifying this
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2020-09-19
      • 2021-07-26
      • 2016-04-25
      • 2020-08-22
      • 2020-05-25
      • 2021-08-06
      • 2020-07-17
      • 2021-01-25
      • 2016-05-17
      相关资源
      最近更新 更多