如何验证 Paypal webhook 通知 DIY 风格(不使用 Paypal SDK) [英] How to verify a Paypal webhook notification DIY style (without using Paypal SDK)

查看:178
本文介绍了如何验证 Paypal webhook 通知 DIY 风格(不使用 Paypal SDK)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在集成 Paypal 的智能按钮后,我在验证由 Paypal 发送的 webhook 通知时遇到问题.我发现的例子要么已经过时,要么不起作用.

Upon integrating the smart button of Paypal I have issues to verify webhook notifications sent by Paypal. The examples I have found are either outdated or do not work.

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

Is there a way to verify the webhook notifications, ideally in a DIY way (ie. without having to use the bulky and complex Paypal API)?

推荐答案

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

To the best of my knowledge, this code is only one that actually works. All other examples I have found on stack overflow will not work because instead of passing the ID of the webhook itself when composing the signature string, they use the ID of the webhook event, thus the verify will fail.

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

The webhook ID will be generated once you add the webhook in the developer backend of Paypal. After creation of the webhook you will see its id in the list of installed webhooks.

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

The rest is pretty straight forward: We get the headers and the HTTP body and compose the signature using Paypal's recipe:

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

To generate the signature, PayPal concatenates and separates these items with the pipe (|) character.

这些项目"是:传输 id、传输日期、webhook id 和 HTTP 主体上的 CRC.前两个可以在请求头中找到,开发者后端的webhook id(当然那个id永远不会改变),CRC计算如下所示.

"These items" are: The transmission id, the transmission date, the webhook id and a CRC over the HTTP body. The first two can be found in the header of the request, the webhook id in the developer backend (of course, that id will never change), the CRC is calculated like shown below.

证书的位置也在标题中,所以我们加载它并提取私钥.

The certificate's location is in the header, too, so we load it and extract the private key.

最后要注意的是:Paypal 提供的算法名称(再次在标题字段中)与 PHP 所理解的并不完全相同.Paypal 称其为sha256WithRSA".但 openssl_verify 会期待sha256WithRSAEncryption".

Last thing to watch out for: The name of the algorithm provided by Paypal (again in a header field) is not exactly the same as understood by PHP. Paypal calls it "sha256WithRSA" but openssl_verify will expect "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
    ...
}

这篇关于如何验证 Paypal webhook 通知 DIY 风格(不使用 Paypal SDK)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆