1 回答

TA貢獻(xiàn)1725條經(jīng)驗(yàn) 獲得超8個(gè)贊
據(jù)我所知,這段代碼只是一個(gè)真正有效的代碼。我在堆棧溢出中找到的所有其他示例都不起作用,因?yàn)樵诰帉懞灻址畷r(shí),它們不是傳遞 webhook本身的 ID,而是使用 webhook 事件的 ID,因此驗(yàn)證將失敗。
在 Paypal 開發(fā)者后端添加 webhook 后,將生成 webhook ID。創(chuàng)建 Webhook 后,您將在已安裝的 Webhook 列表中看到其 ID。
其余部分非常簡單:我們獲取標(biāo)頭和 HTTP 正文,并使用 Paypal 的配方組成簽名:
為了生成簽名,PayPal 使用豎線 (|) 字符連接和分隔這些項(xiàng)目。
“這些項(xiàng)目”是:傳輸 ID、傳輸日期、Webhook ID 和 HTTP 正文上的 CRC。前兩個(gè)可以在請求的 header 中找到,開發(fā)者后端的 webhook id(當(dāng)然,該 id 永遠(yuǎn)不會改變),CRC 的計(jì)算如下所示。
證書的位置也位于標(biāo)頭中,因此我們加載它并提取私鑰。
最后要注意的是:Paypal 提供的算法名稱(同樣在標(biāo)頭字段中)與 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
...
}
- 1 回答
- 0 關(guān)注
- 323 瀏覽
添加回答
舉報(bào)