So testen Sie Webhooks, wenn Sie lokal entwickeln

Webhooks können von einem externen System verwendet werden, um Ihr System über ein bestimmtes Ereignis oder Update zu informieren. Der wahrscheinlich bekannteste Typ ist der, bei dem ein Zahlungsdienstleister (PSP) Ihr System über Statusaktualisierungen von Zahlungen informiert.

Oft kommen sie in der Form, in der Sie eine vordefinierte URL abhören. Zum Beispiel //example.com/webhooks/payment-update. In der Zwischenzeit sendet das andere System eine POST-Anfrage mit einer bestimmten Nutzlast an diese URL (z. B. eine Zahlungs-ID). Sobald die Anfrage eingeht, rufen Sie die Zahlungs-ID ab, fragen die PSP über ihre API nach dem neuesten Status und aktualisieren anschließend Ihre Datenbank.

Weitere Beispiele finden Sie in dieser hervorragenden Erklärung zu Webhooks. //sendgrid.com/blog/whats-webhook/.

Das Testen dieser Webhooks verläuft ziemlich reibungslos, solange das System über das Internet öffentlich zugänglich ist. Dies kann Ihre Produktionsumgebung oder eine öffentlich zugängliche Staging-Umgebung sein. Es wird schwieriger, wenn Sie lokal auf Ihrem Laptop oder in einer virtuellen Maschine (VM, z. B. einer Vagrant-Box) entwickeln. In diesen Fällen sind die lokalen URLs für die Partei, die den Webhook sendet, nicht öffentlich zugänglich. Außerdem ist es schwierig, die gesendeten Anforderungen zu überwachen, was die Entwicklung und das Debuggen erschweren kann.

Was wird dieses Beispiel lösen:

  • Testen von Webhooks aus einer lokalen Entwicklungsumgebung, auf die über das Internet nicht zugegriffen werden kann. Der Dienst, auf den die Daten von ihren Servern an den Webhook gesendet werden, kann nicht darauf zugreifen.
  • Überwachen Sie die Anforderungen und Daten, die gesendet werden, aber auch die Antwort, die Ihre Anwendung generiert. Dies ermöglicht ein einfacheres Debuggen und damit einen kürzeren Entwicklungszyklus.

Voraussetzungen:

  • Optional : Wenn Sie mit einer virtuellen Maschine (VM) entwickeln, stellen Sie sicher, dass diese ausgeführt wird, und stellen Sie sicher, dass die nächsten Schritte in der VM ausgeführt werden.
  • In diesem Tutorial wird davon ausgegangen, dass Sie einen vhost unter definiert haben webhook.example.vagrant. Ich habe für dieses Tutorial eine Vagrant-VM verwendet, aber Sie können den Namen Ihres vhost frei wählen.
  • Installieren Sie ngrokdie Installation, indem Sie den Installationsanweisungen folgen. In einer VM finde ich die Node-Version auch nützlich: //www.npmjs.com/package/ngrok, aber Sie können auch andere Methoden verwenden.

Ich nehme an, Sie haben keine SSL in Ihrer Umgebung ausgeführt wird , aber wenn Sie das tun, können Sie den Port 80 mit dem Port 433 und ersetzen //mit //in den folgenden Beispielen.

Machen Sie den Webhook testbar

Nehmen wir den folgenden Beispielcode an. Ich werde PHP verwenden, es aber als Pseudocode lesen, da ich einige wichtige Teile weggelassen habe (z. B. API-Schlüssel, Eingabevalidierung usw.).

Die erste Datei: payment.php . Diese Datei erstellt ein Zahlungsobjekt und registriert es dann bei der PSP. Anschließend wird die URL abgerufen, die der Kunde zum Bezahlen besuchen muss, und der Benutzer wird an den dortigen Kunden weitergeleitet.

Beachten Sie, dass dies webhook.example.vagrantin diesem Beispiel der lokale vhost ist, den wir für unser Entwicklungssetup definiert haben. Es ist nicht von außen zugänglich.

 123, 'amount' => 25.00, 'description' => 'Test payment', 'redirect_url' => '//webhook.example.vagrant/redirect.php', 'webhook_url' => '//webhook.example.vagrant/webhook.php', ]; $payment = $paymentProvider->createPayment($payment); header("Location: " . $payment->getPaymentUrl());

Zweite Datei: webhook.php . Diese Datei wartet darauf, von der PSP aufgerufen zu werden, um über Updates benachrichtigt zu werden.

getPayment($paymentId); $status = $paymentInfo->getStatus(); // Perform actions in here to update your system if ($status === 'paid') { .. } elseif ($status === 'cancelled') { .. }

Unsere Webhook-URL ist nicht über das Internet zugänglich (denken Sie daran :) webhook.example.vagrant. Daher wird die Datei webhook.php von der PSP niemals aufgerufen. Ihr System wird den Zahlungsstatus nie erfahren. Dies führt letztendlich dazu, dass Bestellungen niemals an Kunden versendet werden.

Glücklicherweise kann ngrok dieses Problem lösen. ngrok beschreibt sich selbst als:

ngrok stellt lokale Server hinter NATs und Firewalls über sichere Tunnel dem öffentlichen Internet zur Verfügung.

Beginnen wir einen einfachen Tunnel für unser Projekt. Führen Sie in Ihrer Umgebung (entweder auf Ihrem System oder auf der VM) den folgenden Befehl aus:

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

Weitere Konfigurationsoptionen finden Sie in der Dokumentation: //ngrok.com/docs.

Ein Bildschirm wie dieser wird angezeigt:

Was haben wir gerade angefangen? Grundsätzlich haben wir angewiesen ngrok, einen Tunnel zu //webhook.example.vagrantPort 80 zu starten. Dieselbe URL kann jetzt über //39741ffc.ngrok.iooder erreicht werden //39741ffc.ngrok.io. Sie sind über das Internet für jeden öffentlich zugänglich, der diese URL kennt.

Beachten Sie, dass sowohl HTTP als auch HTTPS sofort verfügbar sind. Die Dokumentation enthält Beispiele, wie Sie dies nur auf HTTPS beschränken können: //ngrok.com/docs#bind-tls.

Wie bringen wir unseren Webhook jetzt zum Laufen? Aktualisieren Siezahlung.php auf den folgenden Code:

 123, 'amount' => 25.00, 'description' => 'Test payment', 'redirect_url' => '//webhook.example.vagrant/redirect.php', 'webhook_url' => '//39741ffc.ngrok.io/webhook.php', ]; $payment = $paymentProvider->createPayment($payment); header("Location: " . $payment->getPaymentUrl());

Jetzt haben wir die PSP angewiesen, die Tunnel-URL über HTTPS aufzurufen. ngrok stellt sicher, dass Ihre interne URL mit einer unveränderten Nutzlast aufgerufen wird, sobald die PSP den Webhook über den Tunnel aufruft.

Wie kann ich Anrufe an den Webhook überwachen?

Der Screenshot, den Sie oben gesehen haben, gibt einen Überblick über die Anrufe, die an den Tunnelhost getätigt werden. Diese Daten sind eher begrenzt. Glücklicherweise ngrokbietet es ein sehr schönes Dashboard, mit dem Sie alle Anrufe überprüfen können:

Ich werde nicht sehr tief darauf eingehen, weil es selbsterklärend ist, sobald Sie es laufen lassen. Daher werde ich erklären, wie man auf der Vagrant-Box darauf zugreift, da es nicht sofort funktioniert.

Über das Dashboard können Sie alle Anrufe, ihre Statuscodes, die Header und Daten anzeigen, die gesendet werden. Sie sehen auch die Antwort, die Ihre Anwendung generiert hat.

Eine weitere nette Funktion des Dashboards ist, dass Sie einen bestimmten Anruf erneut abspielen können. Angenommen, Ihr Webhook-Code ist auf einen schwerwiegenden Fehler gestoßen. Es wäre mühsam, eine neue Zahlung zu starten und auf den Aufruf des Webhooks zu warten. Durch die Wiederholung des vorherigen Aufrufs wird Ihr Entwicklungsprozess erheblich beschleunigt.

Auf das Dashboard kann standardmäßig unter // localhost: 4040 zugegriffen werden.

Dashboard in einer VM

Damit dies in einer VM funktioniert, müssen Sie einige zusätzliche Schritte ausführen:

Stellen Sie zunächst sicher, dass auf die VM über Port 4040 zugegriffen werden kann. Erstellen Sie dann eine Datei in der VM mit dieser Konfiguration:

web_addr: 0.0.0.0:4040

Beenden Sie nun ngrokden noch laufenden Prozess und starten Sie ihn mit diesem leicht angepassten Befehl:

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

You will get a screen looking similar to the previous screenshot though the ID’s have changed. The previous URL doesn’t work anymore, but you got a new URL. Also, the Web Interface URL got changed:

Now direct your browser to //webhook.example.vagrant:4040 to access the dashboard. Also, make a call to //e65642b5.ngrok.io/webhook.php.This will probably result in an error in your browser, but the dashboard should show the request being made.

Final remarks

The examples above are pseudo-code. The reason is that every external system uses webhooks in a different way. I tried to give an example based on a fictive PSP implementation, as probably many developers have to deal with payments at some moment.

Please be aware that your webhook URL can also be used by others with bad intentions. Make sure to validate any input being sent to it.

Preferably also add a token to the URL which is unique for each payment. This token must only be known by your system and the system sending the webhook.

Good luck testing and debugging your webhooks!

Note: I haven’t tested this tutorial on Docker. However, this Docker container looks like a good starting point and includes clear instructions. //github.com/wernight/docker-ngrok.

Stefan Doorn

//github.com/stefandoorn

//twitter.com/stefan_doorn

//www.linkedin.com/in/stefandoorn