PHP проверить подпись Paypal - PullRequest
0 голосов
/ 05 апреля 2020

У меня возникают проблемы при попытке проверить подписи PayPal с помощью PHP. Используя новую версию API PayPals, я получаю веб-крючок PayPal на своей странице. Тем не менее, я не могу успешно проверить подпись.

По ссылке ЗДЕСЬ Я получил пример кода проверки веб-хука PHP от PayPal.

Я не могу заставить его работать, я не знаю, откуда я должен получить bootstrap. php из кода PayPal. Информация PayPal кажется неполной или наполовину запеченной. Paypal кажется ужасным в настройке по сравнению с Stripe.

Кто-нибудь имел опыт проверки подписей PayPal с помощью webhook с PHP при использовании V2 API PayPal?

1 Ответ

2 голосов
/ 06 апреля 2020

Ну, я пришел к выводу, что информация для разработчиков Paypal довольно скудная, она разбросана повсеместно, на разных страницах и сайтах. Примеры, которые они приводят на веб-сайте разработчиков PayPal ЗДЕСЬ , не являются полной картиной того, что требуется для проверки подписи webhook. Документация для разработчиков Stripe намного лучше отформатирована и лаконична.

Установка Paypal Checkout V2 SDK не дает вам необходимых инструментов разработки для проверки подписей PayPal, например, вы можете обрабатывать платежи и получать веб-крючки, но вы не можете проверять подписи веб-крюка .... Я знаю, глупо. Совет: не загружайте SDK напрямую, поскольку вы не включите необходимый файл автозагрузки. php. Используйте composer для установки Paypal Checkout V2 SDK, чтобы получить файл автозагрузки. php.

После того, как вы сможете обрабатывать платежи и получать webhooks из PayPal, вам необходимо установить еще один SKD, называемый Paypal Rest API SDK. Снова используйте composer для установки SDK, чтобы получить автозагрузку. php файл, который вам понадобится.

Когда вы установите Paypal Rest API SDK удивительным образом, у вас все еще будут отсутствовать файлы, необходимые для проверки подписи Payapl. Я не могу найти упоминания об этом нигде на веб-сайте разработчиков PayPal.

bootstrap. php & common. php

Благодаря @Grumpy я получил несколько образцов на github ЗДЕСЬ

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

После создания bootstrap. php & common. php файлов вы можете создавать напишите код для своей страницы конечной точки webhook, т.е. страницы, на которую paypal отправляет webhook. Я включил свой PHP код ниже для того, чтобы проверить и затем обработать PayPal Webhook. Подсказка в приведенном ниже коде, вам необходимо указать идентификатор webhook, каждый webhook, который вы создаете в PayPal, имеет уникальный идентификатор. Также, когда вы тестируете, вы не можете использовать симулятор webhook, так как это не пройдет валидацию, вы можете сделать платеж вручную, используя данные своей учетной записи в песочнице, что вызовет событие оплаты webhook. их документация повсюду по сравнению с Stripe. Веб-заездам Paypal иногда может потребоваться несколько минут, чтобы прийти после совершения платежа, что очень расстраивает при попытке отладки. Также немного смешно, что у них есть веб-симулятор на веб-сайте разработчиков PayPal, который нельзя использовать для проверки подписей ... если Stripe может это сделать, почему не может PayPal.

<?php





//get the webhook payload

$requestBody = file_get_contents('php://input');

//check if webhook payload has data
if($requestBody) {
//request body is set
} else {
//request body is not set
exit(); 
}




use \PayPal\Api\VerifyWebhookSignature;
use \PayPal\Api\WebhookEvent;

$apiContext = require __DIR__ . '/bootstrap.php';




//Receive HTTP headers that you received from PayPal webhook.

$headers = getallheaders();


//need header keys to be UPPERCASE

$headers = array_change_key_case($headers, CASE_UPPER);


/*

example header paypal signature content for webhook, these values are recieved as an array, we then need to use this data to verify the payload


CONTENT-LENGTH : 1376

CORRELATION-ID : 6db85170269e7

USER-AGENT : PayPal/AUHD-214.0-54377828

CONTENT-TYPE: application/json

PAYPAL-AUTH-ALGO : SHA256withRSA

PAYPAL-CERT-URL : https://api.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a784-5edc0ebc

PAYPAL-AUTH-VERSION : v2

PAYPAL-TRANSMISSION-SIG : Hc2lsDedYdSjOM4/t3T/ioAVQqFPNVB/AY/EyPNlavXk5WYUfnAmt9dyEP6neAPOjFHiVkXMK+JlLODbr6dalw6i26aFQdsPXqGl38Mafuu9elPE74qgsqNferUFgHi9QFXL+UZCNYcb4mvlDePXZIIAPbB0gOuFGOdEv2uqNwTCSAa/D8aguv1/51FWb3RkytFuVwXK/XNfIEy2oJCpDs8dgtYAZeojH8qO6IAwchdSpttMods5YfNBzT7oCoxO80hncVorBtjj1zQrkoynEB9WNNN9ytepNCkT8l29fQ4Sx/WRndm/PESCqxqmRoYJoiSosxYU3bZP7QTtILDykQ==

PAYPAL-TRANSMISSION-TIME : 2020-04-05T14:40:43Z

PAYPAL-TRANSMISSION-ID : 6dec99b0-774b-11ea-b306-c3ed128f0c4b


*/


//if any of the relevant paypal signature headers are not set exit()

if(
(!array_key_exists('PAYPAL-AUTH-ALGO', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-ID', $headers)) ||
(!array_key_exists('PAYPAL-CERT-URL', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-SIG', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-TIME', $headers)) 
)
{

exit();     
}

//specify the ID for the webhook that you have set up on the paypal developer website, each web hook that you create has a unique ID


$webhookID = "ENTER_YOUR_WEBHOOK_ID_HERE";




//start paypal webhook signature validation 

$signatureVerification = new VerifyWebhookSignature();
$signatureVerification->setAuthAlgo($headers['PAYPAL-AUTH-ALGO']);
$signatureVerification->setTransmissionId($headers['PAYPAL-TRANSMISSION-ID']);
$signatureVerification->setCertUrl($headers['PAYPAL-CERT-URL']);
$signatureVerification->setWebhookId($webhookID); 
$signatureVerification->setTransmissionSig($headers['PAYPAL-TRANSMISSION-SIG']);
$signatureVerification->setTransmissionTime($headers['PAYPAL-TRANSMISSION-TIME']);

$signatureVerification->setRequestBody($requestBody);
$request = clone $signatureVerification;

try {

$output = $signatureVerification->post($apiContext);

} catch (Exception $ex) {

//error during signature validation, capture error and exit

ResultPrinter::printError("Validate Received Webhook Event", "WebhookEvent", null, $request->toJSON(), $ex);
exit(1);

}


$sigVerificationResult = $output->getVerificationStatus();

// $sigVerificationResult is a string and will either be "SUCCESS" or "FAILURE"


//if not webhook signature failed validation exit
if($sigVerificationResult != "SUCCESS"){

exit(); 
}
else if($sigVerificationResult == "SUCCESS"){

//paypay webhook signature is valid

//proceed to process webhook payload


//decode raw request body

$requestBodyDecode = json_decode($requestBody);


//pull whatever info required from decoded request body, some examples below


$paymentSystemID = $requestBodyDecode->id;


$eventType = $requestBodyDecode->event_type;


//do something with info captured from the webhook payload


} 
...