Как тестировать Webhooks во время локальной разработки

1658178018 kak testirovat webhooks vo vremya lokalnoj razrabotki

Стефан Дорн

i9KeelZPH4sm6U5c4UMbTznxBweLcFAzfOZ-
Фото Фернандо Венцано на Unsplash

Веб-хуки могут использоваться внешней системой для оповещения вашей системы об определенном событии или обновлении. Пожалуй, наиболее известным типом является тот, в котором поставщик платежных услуг (PSP) информирует вашу систему об обновлении статуса платежей.

Часто они поступают в форме, где вы прослушиваете заранее определенный URL-адрес. Например, тем временем другая система отправляет запрос POST с определенной полезной нагрузкой на этот URL (например, идентификатор платежа). Как только поступает запрос, вы получаете идентификатор платежа, запрашиваете у PSP последний статус через их API, а затем обновляете свою базу данных.

Другие примеры можно найти в этом замечательном пояснении о Webhooks. https://sendgrid.com/blog/whats-webhook/.

Тестирование этих веб-хуков проходит довольно гладко, пока система общедоступна в Интернете. Это может быть ваша производственная среда или общедоступная промежуточная среда. Это становится сложнее, когда вы разрабатываете локально на своем ноутбуке или внутри виртуальной машины (VM, например Vagrant box). В таких случаях локальные URL-адреса не являются общедоступными сторонам, отправляющим веб-хук. Кроме того, трудно следить за посылаемыми запросами, что может усложнить разработку и отладку.

Что решит этот пример:

  • Тестирование веб-хуков из локальной среды разработки, которая недоступна через Интернет. Сервис, который посылает данные на вебхук со своих серверов, не может получить к нему доступ.
  • Отслеживайте запросы и данные, а также ответ, который создает программа. Это облегчит отладку, а значит, сократит цикл разработки.

Предпосылки:

  • Дополнительно: если вы разрабатываете с помощью виртуальной машины (VM), убедитесь, что она запущена, и убедитесь, что следующие шаги выполняются в VM.
  • Для этого учебника мы предполагаем, что у вас есть vhost, определенный в webhook.example.vagrant. Я использовал Vagrant VM для этого учебника, но вы можете свободно выбирать имя своего виртуального хоста.
  • установить ngrokследуя инструкциям по установке. Внутри виртуальной машины я считаю ее версию Node тоже полезной: но смело используйте другие методы.

Я предполагаю, что в вашей среде не запущен SSL, но если есть, не стесняйтесь заменить порт 80 на порт 433 и http:// с https:// в приведенных ниже примерах.

Сделайте вебхук доступным для проверки

Предположим следующий пример кода. Я буду использовать PHP, но читаю его как псевдокод, поскольку я пропустил некоторые важные части (например, ключи API, проверку ввода и т.д.)

Первый файл: payment.php. Этот файл создает платежный объект, а затем регистрирует его в PSP. Затем он получает URL, который клиент должен посетить, чтобы оплатить, и перенаправляет пользователя к клиенту там.

Обратите внимание, что webhook.example.vagrant В этом примере это локальный vhost, который мы определили для наших настроек разработки. Он недоступен из внешнего мира.

<?php
/*
 * This file creates a payment and tells the PSP what webhook URL to use for updates
 * After creating the payment, we get a URL to send the customer to in order to pay at the PSP
 */
$payment = [
    'order_id' => 123,
    'amount' => 25.00,
    'description' => 'Test payment',
    'redirect_url' => '
    'webhook_url' => '
];

$payment = $paymentProvider->createPayment($payment);
header("Location: " . $payment->getPaymentUrl());

Второй файл: webhook.php. Этот файл ожидает вызов PSP для получения сообщения об обновлении.

<?php
/*
 * This file gets called by the PSP and in the $_POST they submit an 'id'
 * We can use this ID to get the latest status from the PSP and update our internal systems afterward
 */
 
$paymentId = $_POST['id'];
$paymentInfo = $paymentProvider->getPayment($paymentId);
$status = $paymentInfo->getStatus();

// Perform actions in here to update your system
if ($status === 'paid') {
    ..
}
elseif ($status === 'cancelled') {
    ..
}

Наш URL-адрес webhook недоступн в Интернете (помните: webhook.example.vagrant). Таким образом, файл webhook.php никогда не будет вызываться PSP. Ваша система никогда не узнает статус платежа. Это в конечном итоге приводит к тому, что заказы никогда не посылаются клиентам.

К счастью, ngrok может решать эту проблему. ngrok описывает себя как:

ngrok открывает локальные серверы по NAT и брандмауэрам для общедоступного Интернета через безопасные туннели.

Давайте начнем базовый тоннель для нашего проекта. В вашей среде (или в вашей системе или на виртуальной машине) выполните следующую команду:

ngrok http -host-header=rewrite webhook.example.vagrant:80

Дополнительные параметры конфигурации см. в их документации: https://ngrok.com/docs.

Появится следующий экран:

PuC-rg6uYtgl0ltFQUooZbU5VJju2qIESJ1F
выход ngrok

Что мы только начали? В принципе, мы инструктировали ngrok чтобы начать туннель до на порт 80. Этот же URL теперь можно получить через или https://39741ffc.ngrok.ioОни доступны в Интернете для всех, кто знает этот URL.

Примечание что вы получаете как HTTP, так и HTTPS, доступные из коробки. В документации приведены примеры того, как ограничить это только HTTPS: https://ngrok.com/docs#bind-tls.

Итак, как нам сделать так, чтобы наш вебхук теперь работал? обновление payment.php к следующему коду:

<?php
/*
 * This file creates a payment and tells the PSP what webhook URL to use for updates
 * After creating the payment, we get a URL to send the customer to in order to pay at the PSP
 */
$payment = [
    'order_id' => 123,
    'amount' => 25.00,
    'description' => 'Test payment',
    'redirect_url' => '
    'webhook_url' => '
];

$payment = $paymentProvider->createPayment($payment);
header("Location: " . $payment->getPaymentUrl());

Теперь мы сказали PSP вызвать URL-адрес туннеля через HTTPS. ngrok обеспечит вызов вашего внутреннего URL-адреса с неизмененной полезной нагрузкой, как только PSP вызовет вебхук через туннель.

Как отслеживать звонки на вебхук?

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

5qMSpanO5DID6fouWKns6mZcsj-cgVYXntV-

Я не буду вдаваться в это слишком глубоко, потому что это понятно, как только вы его запустите. Поэтому я объясню, как получить доступ к нему на окне Vagrant, поскольку это не работает из коробки.

Информационная панель позволит вам видеть все звонки, их коды состояния, заголовки и передаваемые данные. Вы также увидите ответ, созданный вашей заявкой.

Еще одна отличная функция информационной панели состоит в том, что она позволяет воспроизвести определенный вызов. Скажем, в вашем коде веб-хука произошла роковая ошибка, было бы утомительно начинать новый платеж и ждать, пока вызовется веб-хук. Воспроизведение предварительного вызова значительно ускоряет процесс разработки.

Информационная панель доступна по адресу http://localhost:4040.

Информационная панель в виртуальной машине

Чтобы это работало в виртуальной машине, необходимо выполнить несколько дополнительных шагов:

Сначала убедитесь, что к виртуальной машине можно получить доступ через порт 4040. Затем создайте файл внутри виртуальной машины, содержащей эту конфигурацию:

web_addr: 0.0.0.0:4040

Теперь убейте ngrok все еще работающий процесс и запустите его с помощью этой несколько скорректированной команды:

ngrok http -config=/path/to/config/ngrok.conf -host-header=rewrite webhook.example.vagrant:80

Вы получите экран, похожий на предыдущий снимок, хотя идентификаторы изменились. Предыдущий URL-адрес больше не работает, но вы получили новый URL-адрес. Кроме того, Web Interface URL изменен:

IR7nrGbuh0192n0CGzY2Az0qX-RA6kIwoMZs

Теперь направьте свой браузер на :4040 доступ к информационной панели. Также позвоните в https://e65642b5.ngrok.io/webhook.php.Вероятно, это приведет к ошибке в вашем браузере, но на информационной панели должен отображаться сделанный запрос.

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

Имейте в виду, что URL-адрес вашего вебхука также может быть использован другими с плохими намерениями. Убедитесь, что проверяете любые передаваемые ему входящие данные.

Желательно также добавить маркер к URL-адресу, который является уникальным для каждого платежа. Этот маркер должен быть известен только вашей системе и системе, отправляющей вебхук.

Удачи в тестировании и настройке веб-хуков!

Примечание: Я не тестировал это руководство на Docker. Однако этот контейнер Docker выглядит как отличная точка и содержит четкие инструкции. https://github.com/wernight/docker-ngrok.

Стефан Дорн

https://github.com/stefandoorn
https://twitter.com/stefan_doorn
https://www.linkedin.com/in/stefandoorn

Добавить комментарий

Ваш адрес email не будет опубликован.