Как проверить самодельный стиль уведомления веб-перехватчика Paypal (без использования Paypal SDK) - PullRequest
1 голос
/ 13 июля 2020

После интеграции интеллектуальной кнопки Paypal у меня возникли проблемы с проверкой уведомлений веб-перехватчиков, отправленных Paypal. Примеры, которые я нашел, либо устарели, либо не работают.

Есть ли способ проверить уведомления веб-перехватчиков, в идеале самодельным способом (ie. Без использования громоздкого и сложного API Paypal) ?

1 Ответ

1 голос
/ 13 июля 2020

Насколько мне известно, этот код - единственный, который действительно работает. Все другие примеры переполнения стека, которые я нашел, не будут работать, потому что вместо передачи идентификатора веб-перехватчика самого при составлении строки подписи они используют идентификатор события веб-перехватчика, поэтому проверка не удастся.

Идентификатор веб-перехватчика будет сгенерирован после добавления веб-перехватчика в серверную часть Paypal для разработчиков. После создания веб-перехватчика вы увидите его идентификатор в списке установленных веб-перехватчиков.

Остальное довольно просто: мы получаем заголовки и тело HTTP и составляем подпись, используя рецепт Paypal:

Чтобы создать подпись, PayPal объединяет и разделяет эти элементы вертикальной чертой (|).

«Эти элементы»: идентификатор передачи, дата передачи, идентификатор веб-перехватчика. и CR C по телу HTTP. Первые два можно найти в заголовке запроса, идентификаторе веб-перехватчика в бэкэнде разработчика (конечно, этот идентификатор никогда не изменится), CR C рассчитывается, как показано ниже.

Сертификат местоположение также находится в заголовке, поэтому мы загружаем его и извлекаем закрытый ключ.

Последнее, на что нужно обратить внимание: имя алгоритма, предоставляемого 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
    ...
}
...