Webhook — это обратный вызов HTTP, который происходит, когда что-то происходит; простая система уведомлений о событиях через HTTP POST, которая позволяет разработчикам легко получать доступ к уведомлениям об операциях оплаты, таких как обновление статуса платежа или периодические платежи Вы можете выполнять действия на своем сервере после обработки каждого уведомления, например:
- Отправить подтверждение покупки вашему клиенту.
- Включить загрузку цифрового мультимедиа.
- Выдать возврат.
- Следите за тем, какие подписки активны.
Чтобы создать веб-крючок, перейдите на панель инструментов PayPal и нажмите « Мои приложения и учетные данные» . Затем выберите приложение, в котором вы хотите настроить Webhooks.
Вы можете увидеть подробную информацию о вашем приложении. Обратите внимание, что в правом верхнем углу есть две кнопки (Sandbox, Live), я буду использовать Sandbox в этом уроке, но вам нужно настроить параметры Live, прежде чем переходить в Live. Чтобы настроить Webhooks для этого приложения, нажмите Add Webhook, как показано на скриншоте:
Выберите типы событий, которые вы заинтересованы в получении уведомлений, и введите URL-адрес, на который будут отправляться веб-хуки (это должен быть HTTPS). Для обработки вызовов Webhook я собираюсь добавить новый метод действия в HomeController под названием «Webhook»:
1
2
3
4
|
public IActionResult Webhook()
{
// TODO: Handle Webhook call
}
|
Таким образом, URL-адрес Webhook в этом случае будет следующим: https://pedroalonso.localtunnel.me/home/webhook . Я объясню часть ‘localtunnel’ в следующем разделе.
Когда вы сохраните Webhook, вы увидите этот экран подтверждения:
Теперь, когда Webhook настроен, вы можете увидеть в левом меню «Webhooks Simulator», здесь вы можете отправить «тестовые» события webhook на ваш URL, чтобы проверить, работает ли ваш код. Кроме того, в разделе «События Webhooks» вы можете увидеть все события, отправленные PayPal для этого приложения. Вы можете проверить правильность обработки событий и повторно отправить их, если хотите провести дальнейшее тестирование.
Чтобы увидеть, как работают веб-хуки, я запустил проект, который мы создали в предыдущем уроке, и создал «авторизовать платеж и захватить позже», чтобы PayPal отправил событие. После запуска примера я нажал «Событие Webhooks» и увидел, что событие отправлено:
Как видите, справа есть кнопка « Переслать» , если вы хотите отладить свой код и посмотреть, как правильно реализовать обработчик. Кроме того, если вы нажмете на событие, вы можете увидеть все детали:
Это полный JSON для события Webhook:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
{
«id»: «WH-9U51749144910293K-8LX80763BC1567402»,
«create_time»: «2016-01-19T17:50:30Z»,
«resource_type»: «sale»,
«event_type»: «PAYMENT.SALE.COMPLETED»,
«summary»: «Payment completed for $ 100.0 USD»,
«resource»: {
«amount»: {
«total»: «100.00»,
«currency»: «USD»,
«details»: {
«subtotal»: «100.00»,
«tax»: «15.00»,
«shipping»: «10.00»
}
},
«id»: «73G8209522783053E»,
«parent_payment»: «PAY-7MB27930V5981832YK2PHN7Q»,
«update_time»: «2016-01-19T17:49:05Z»,
«create_time»: «2016-01-19T17:49:05Z»,
«payment_mode»: «INSTANT_TRANSFER»,
«state»: «completed»,
«links»: [
{
«href»: «https://api.sandbox.paypal.com/v1/payments/sale/73G8209522783053E»,
«rel»: «self»,
«method»: «GET»
},
{
«href»: «https://api.sandbox.paypal.com/v1/payments/sale/73G8209522783053E/refund»,
«rel»: «refund»,
«method»: «POST»
},
{
«href»: «https://api.sandbox.paypal.com/v1/payments/payment/PAY-7MB27930V5981832YK2PHN7Q»,
«rel»: «parent_payment»,
«method»: «GET»
}
],
«protection_eligibility_type»: «ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE»,
«transaction_fee»: {
«value»: «3.20»,
«currency»: «USD»
},
«protection_eligibility»: «ELIGIBLE»
},
«status»: «PENDING»,
«transmissions»: [
{
«webhook_url»: «https://pedroalonso.localtunnel.me/home/webhook»,
«response_headers»: {
«Date»: «Wed, 20 Jan 2016 12:53:51 GMT»,
«Content-Length»: «53»,
«HTTP/1.1 502 Bad Gateway»: «»,
«SERVER_INFO»: «»,
«Connection»: «keep-alive»,
«Server»: «nginx/1.7.8»
},
«transmission_id»: «218dc9c0-bed5-11e5-927f-6b62a8a99ac4»,
«status»: «PENDING»,
«timestamp»: «2016-01-19T17:50:30Z»
}
],
«links»: [
{
«href»: «https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-9U51749144910293K-8LX80763BC1567402»,
«rel»: «self»,
«method»: «GET»,
«encType»: «application/json»
},
{
«href»: «https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-9U51749144910293K-8LX80763BC1567402/resend»,
«rel»: «resend»,
«method»: «POST»,
«encType»: «application/json»
}
]
}
|
Как вы можете видеть на картинке, детали события закодированы в JSON, и они отправляются как тело запроса в ваш обработчик URL Webhook. Также есть несколько важных свойств, которые нам нужно использовать в нашем обработчике:
- id : это идентификатор события webhook, и нам нужно отправить этот параметр в PayPal, если мы хотим получить конкретное событие webhook.
- event_type : это используется, чтобы узнать тип события, которое мы получаем, поскольку нам, вероятно, нужно обрабатывать различные типы событий по-разному.
- resource.parent_payment : это идентификатор платежа, с которым связано это событие. Возможно, этот идентификатор хранится в базе данных, и мы можем отправить электронное письмо нашему клиенту или отправить товары, приобретенные клиентом.
Исходя из предыдущего объяснения, это код контроллера действий для обработки Webhook:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
public IActionResult Webhook()
{
// The APIContext object can contain an optional override for the trusted certificate.
var apiContext = PayPalConfiguration.GetAPIContext();
// Get the received request’s headers
var requestheaders = HttpContext.Request.Headers;
// Get the received request’s body
var requestBody = string.Empty;
using (var reader = new System.IO.StreamReader(HttpContext.Request.Body))
{
requestBody = reader.ReadToEnd();
}
dynamic jsonBody = JObject.Parse(requestBody);
string webhookId = jsonBody.id;
var ev = WebhookEvent.Get(apiContext, webhookId);
// We have all the information the SDK needs, so perform the validation.
// Note: at least on Sandbox environment this returns false.
// var isValid = WebhookEvent.ValidateReceivedEvent(apiContext, ToNameValueCollection(requestheaders), requestBody, webhookId);
switch (ev.event_type)
{
case «PAYMENT.CAPTURE.COMPLETED»:
// Handle payment completed
break;
case «PAYMENT.CAPTURE.DENIED»:
// Handle payment denied
break;
// Handle other webhooks
default:
break;
}
return new HttpStatusCodeResult(200);
}
|
Несколько вещей, чтобы объяснить из предыдущей функции. Из строк 10-16 я только читаю тело запроса и анализирую объект JSON для динамического объекта C #. В строке 18, которая является необязательной, я вызываю API PayPal с идентификатором события, чтобы получить полную информацию о событии. Это сделано для безопасности, чтобы убедиться, что я использую действительный объект PayPal. В строке 24 я создал переключатель для оценки типов веб-хуков, которые я хочу обрабатывать, и по мере необходимости пишу собственный код.
Как вы также можете видеть, строка 22 закомментирована. Очевидно, этот метод проверяет, что сертификат SSL из запроса действителен и принадлежит PayPal, но он не работает в режиме песочницы. Это может работать в Live, но мне не нравится, что в Live не тестируется код, особенно если он работает с платежным шлюзом, поэтому я решил удалить его и использовать другой подход. Если вы используете PHP-версию библиотеки PayPal SDK, имейте в виду, что функция ValidateReceivedEvent даже не существует.
Тестирование Webhooks: безопасный туннель
Как вы видели ранее, для тестирования Webhooks нам нужно настроить публичный URL, который PayPal может использовать для отправки событий. Если мы работаем локально, обычно мы разрабатываем с использованием ‘localhost’, так что это будет небольшой проблемой. Чтобы решить эту проблему, нам нужно настроить безопасный туннель к нашему локальному компьютеру.
Localtunnel — это небольшая часть программного обеспечения, которая создает безопасный туннель между вашим локальным компьютером и общедоступным доменом. Это полезно для тестирования Webhooks, но вы также можете использовать его, чтобы делиться живыми URL-адресами с веб-приложениями, работающими на вашем компьютере разработчика, для целей тестирования, обратной связи или других задач.
Вам нужно иметь Node.js, чтобы иметь возможность установить localtunnel. Затем просто откройте консоль или терминал и запустите:
$ npm install -g localtunnel
Чтобы создать туннель, запустите:
$ lt --port 5000 --subdomain pedroalonso
Это отобразит URL « https://pedroalonso.localtunnel.me » на «localhost: 5000». Если вы запустите свой проект на IIS Express, вы, вероятно, будете использовать другой порт, поэтому вам необходимо отразить это в своей команде.
После настройки localtunnel и запуска нашего проекта я добавил точку останова в Visual Studio, чтобы оценить полученные данные. Как вы можете видеть на этом снимке экрана, я сопоставил объект события JSON с динамическим объектом C #.
Получая событие из API PayPal, используя идентификатор события, мы также получаем детали события, как вы можете видеть здесь:
Вывод
Webhooks становятся стандартным способом для REST API уведомлять приложения о событиях. Как вы можете видеть, с ними довольно легко обращаться, и они используются многими компаниями, такими как Stripe, SendGrid, MailChimp и т. Д. PayPal имел уведомление о мгновенных платежах, и он все еще используется, но они рекомендуют внедрять Webhooks, когда это возможно. ,
Я думаю, что было бы действительно интересно, если бы другие потребительские приложения также предлагали Webhooks. Возможность запуска процесса на основе события в отдельном приложении чрезвычайно полезна и дает представление о будущем сети в реальном времени.