Verifizieren und testen
Verifizieren Sie den ursprünglichen Anfrageinhalt, verarbeiten Sie Duplikate und testen Sie Ihren Empfänger sicher.
Verifizieren Sie jeden Webhook, bevor Sie seine Payload verwenden, und senden Sie dann einen Test, um zu bestätigen, dass Ihr Empfänger durchgängig funktioniert.
Vorbereitung
- Ein gespeichertes Ziel und sein signing secret (Signaturschlüssel),
twhsec_.... Verwenden Sie nicht Ihr Server Secret Token, um Webhooks zu verifizieren. - Eine Empfängerroute, die den ursprünglichen Anfrageinhalt lesen kann, bevor ein JSON-Parser ihn verändert.
- Ein Speicher mit einer Eindeutigkeitsbedingung für die Ereignis-
id, damit Duplikate unbedenklich sind.
Webhook empfangen
Ursprünglichen Inhalt lesen
Tapaya sendet einen JSON-POST mit diesen Headern. Behalten Sie den Inhalt als ursprüngliche Bytes bei; ein geparster und erneut serialisierter Inhalt stimmt nicht mehr mit der Signatur überein.
Content-Type: application/json
X-Tapaya-Event-Id: 019a0000-0000-7000-8000-000000000001
X-Tapaya-Signature: t=1793361600,v1=<lowercase hexadecimal HMAC-SHA256>- Verwenden Sie mit Express für diese Route
express.raw({ type: "application/json" })vor einem globalen JSON-Parser.
Signatur prüfen
Berechnen Sie HMAC-SHA256 über den Zeitstempel, einen Punkt und den ursprünglichen Inhalt, und vergleichen Sie das Ergebnis dann mit konstanter Laufzeit mit v1.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyTapayaWebhook(rawBody, signatureHeader, secret, now = Date.now()) {
if (!Buffer.isBuffer(rawBody) || typeof signatureHeader !== "string") {
throw new Error("Missing raw body or signature");
}
if (typeof secret !== "string" || !secret.startsWith("twhsec_")) {
throw new Error("Missing signing secret");
}
const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(signatureHeader);
if (!match) throw new Error("Malformed signature");
const timestamp = Number(match[1]);
if (!Number.isSafeInteger(timestamp) || Math.abs(now / 1000 - timestamp) > 300) {
throw new Error("Expired signature");
}
const expected = createHmac("sha256", Buffer.from(secret, "utf8"))
.update(`${match[1]}.`, "utf8")
.update(rawBody)
.digest();
const received = Buffer.from(match[2], "hex");
if (!timingSafeEqual(expected, received)) throw new Error("Invalid signature");
return JSON.parse(rawBody.toString("utf8"));
}- Verwenden Sie das vollständige Geheimnis
twhsec_...als UTF-8-Schlüssel. Decodieren Sie es nicht und entfernen Sie sein Präfix nicht. - Weisen Sie Zeitstempel zurück, die mehr als fünf Minuten von Ihrer Uhrzeit abweichen, und halten Sie die Uhr synchronisiert.
- Während Sie das signing secret rotieren, prüfen Sie zuerst das neue Secret und dann das alte, bis die Warteschlange abgearbeitet ist.
Speichern und bestätigen
Nehmen Sie das Ereignis erst an, wenn es sicher gespeichert ist, damit ein Fehler auf Ihrer Seite eine Wiederholung auslöst.
import express from "express";
import { verifyTapayaWebhook } from "./verify-tapaya-webhook.mjs";
import { saveEventOnce } from "./events.mjs"; // your store, unique on event id
const app = express();
app.post(
"/webhooks/tapaya",
express.raw({ type: "application/json" }),
async (req, res) => {
let event;
try {
event = verifyTapayaWebhook(
req.body,
req.get("X-Tapaya-Signature"),
process.env.TAPAYA_WEBHOOK_SECRET,
);
} catch {
return res.sendStatus(400);
}
if (event.organizationId !== process.env.TAPAYA_ORGANIZATION_ID) {
return res.sendStatus(400);
}
await saveEventOnce(event); // skips an id it already stored
res.sendStatus(204);
},
);- Geben Sie für ein bereits gespeichertes Ereignis
2xxzurück. Wiederholungen behalten dieselbeidund denselben Inhalt, mit neuem Zeitstempel und neuer Signatur. - Geben Sie eine Antwort außerhalb von
2xxzurück, wenn Sie ein neues Ereignis nicht speichern können, damit die Zustellung wiederholt wird. - Verarbeiten Sie gespeicherte Ereignisse aus Ihrer eigenen Warteschlange. Die Zustellreihenfolge ist nicht garantiert; gleichen Sie ältere Snapshots daher mit dem aktuellen Zustand ab.
Test-Webhook senden
Die Testaktion der Platform sendet eine signierte Anfrage webhook.test an die gespeicherte URL. Sie funktioniert auch, wenn Webhooks deaktiviert sind oder der Typ nicht in Ihrem Abonnement enthalten ist, und erstellt weder eine Zahlung noch eine Erstattung noch einen Händler.
- Öffnen Sie API Keys für Ihre Organisation und speichern Sie das Ziel.
- Verwenden Sie die Webhook-Testaktion.
- Prüfen Sie das Ergebnis, die Dauer und das gesendete JSON, die in der Platform angezeigt werden.
{
"id": "019a0000-0000-7000-8000-000000000010",
"type": "webhook.test",
"apiVersion": "1",
"organizationId": "019a0000-0000-7000-8000-000000000002",
"merchantId": null,
"createdAt": "2026-10-30T12:00:00.000000Z",
"test": true,
"data": {
"message": "This is a test webhook from Tapaya. No payment was created."
}
}Lokale und Automatisierungsempfänger
Richten Sie einen Webhook auf einen Entwicklungsrechner oder ein No-Code-Tool, wenn Ihr Produktionsserver noch nicht bereit ist.
Fehler behandeln
Ereignistypen
Wählen Sie die Änderungen an Zahlungen, Erstattungen, Händlern und am Onboarding aus, die Ihre Integration benötigt.
Übersicht
Nehmen Sie Kartenzahlungen überall dort an, wo Ihre Händler ihre Kunden treffen, von der Ladentheke über den Restauranttisch bis zur Ladesäule für Elektrofahrzeuge, auf den Smartphones und Tablets, die sie bereits nutzen.