Entwickle mit der Vouchereto API
Eine schlanke REST-API für genau eine Aufgabe: einen Gutschein entgegennehmen, an einen Kunden binden und in Guthaben auf deiner Plattform verwandeln.
- Basis-URL
- api.vouchereto.com/v1
- Test und Live
- Schlüssel vch_test_… und vch_live_…
- Authentifizierung
- Bearer-Schlüssel + HMAC-SHA256
- Format
- JSON · Beträge in kleinster Währungseinheit
Deine erste Einlösung
Schlüssel holen
Erstelle im Händlerportal einen Testschlüssel. Den vollständigen Schlüssel siehst du nur einmal; sein letzter Teil ist zugleich das Secret, mit dem du Anfragen signierst.
Gutschein reservieren
Sende den Code, die Währung und deine Kundenreferenz. Der Gutschein wird an diesen Kunden gebunden und kann nirgendwo sonst verwendet werden.
Gutschreiben, dann erfassen
Schreib das Guthaben auf deiner Seite gut, dann erfasse die Einlösung. Schlägt die Aufladung fehl, stornierst du stattdessen, und der Gutschein wird freigegeben.
Webhooks empfangen
Registriere einen Endpunkt, um signierte Events zu Erfassungen, Stornierungen, Abläufen und Checkouts zu erhalten.
POST /v1/redemptions
Authorization: Bearer vch_test_…
Idempotency-Key: topup-88213
Vouchereto-Signature: t=1790500000,v1=9c1e5f07…
Content-Type: application/json
{ "code": "7K2M-9QXR-4HTB-2WNZ", "customer_ref": "acct_48213", "currency": "USD" }
# 201 Created
{ "id": "5f0c2a7e-…", "object": "redemption", "status": "reserved",
"amount_minor": 5000, "currency": "USD", "voucher_last4": "2WNZ",
"customer_ref": "acct_48213", "livemode": false,
"expires_at": "2026-09-27T14:12:00Z", "captured_at": null }
# Credit the customer first, then capture. Irreversible.
POST /v1/redemptions/5f0c2a7e-…/capture
Authorization: Bearer vch_test_…
Idempotency-Key: topup-88213-capture
Vouchereto-Signature: t=1790500012,v1=4b7d2e91…
# 200 OK
{ "id": "5f0c2a7e-…", "object": "redemption", "status": "captured",
"captured_at": "2026-09-27T14:02:31Z", … }
# The top-up failed: release the voucher back to the customer
POST /v1/redemptions/5f0c2a7e-…/cancel
Authorization: Bearer vch_test_…
Idempotency-Key: topup-88213-cancel
Vouchereto-Signature: t=1790500015,v1=77aa01c3…
# 200 OK
{ "id": "5f0c2a7e-…", "object": "redemption", "status": "cancelled", … }
// Vouchereto-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, t + "." + rawBody)>
// secret = the whsec_… signing secret of your webhook endpoint
import crypto from "node:crypto";
export function verifyWebhook(rawBody, header, secret) {
const parts = header.split(",").map((p) => p.trim().split("="));
const t = Number(parts.find(([k]) => k === "t")?.[1]);
const sigs = parts.filter(([k]) => k === "v1").map(([, v]) => Buffer.from(v, "hex"));
if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return sigs.some((s) => s.length === expected.length && crypto.timingSafeEqual(s, expected));
}
Der Lebenszyklus einer Einlösung
- erfasstDer Gutschein ist verbraucht. Unwiderruflich.
- storniertDu hast storniert. Der Gutschein ist wieder aktiv.
- Reservierung abgelaufenNicht rechtzeitig erfasst (standardmäßig 15 Minuten). Der Gutschein ist wieder aktiv.
Worauf du aufbaust
Anfragen signieren
Jede Anfrage enthält einen Vouchereto-Signature-Header: einen Zeitstempel und einen HMAC-SHA256 aus Zeitstempel, Methode, Pfad und Body, signiert mit dem Secret deines API-Schlüssels. Wir akzeptieren eine Zeitabweichung von bis zu 300 Sekunden.
// Sign every request with the secret part of your API key (the text after the last "_")
const t = Math.floor(Date.now() / 1000);
const payload = `${t}.${method} ${pathWithQuery}\n${body}`;
const v1 = crypto.createHmac("sha256", keySecret).update(payload).digest("hex");
headers["Vouchereto-Signature"] = `t=${t},v1=${v1}`;
Idempotenz
Jeder POST braucht einen Idempotency-Key-Header. Wiederholst du eine Anfrage mit demselben Schlüssel, erhältst du die ursprüngliche Antwort zurück, markiert mit Idempotent-Replayed: true. Schlüssel werden mindestens 30 Tage aufbewahrt.
Sandbox-Gutscheine
Mit einem Testschlüssel erstellt POST /v1/sandbox/vouchers einen Testgutschein im gewünschten Status (active, reserved, redeemed, expired, risk_hold oder void) und gibt seinen Code zurück. Testschlüssel sehen immer nur Testdaten.
Webhook-Events
| Event | Wann es gesendet wird |
|---|---|
| redemption.captured | Ein reservierter Gutschein wurde erfasst. Das gutgeschriebene Guthaben kann bleiben. |
| redemption.cancelled | Eine Reservierung wurde storniert. Der Gutschein ist wieder aktiv. |
| redemption.expired | Eine Reservierung ist ohne Erfassung abgelaufen. |
| checkout.completed | Ein gehosteter Checkout wurde bezahlt und der Gutschein eingelöst. |
| checkout.expired | Eine gehostete Checkout-Sitzung ist ohne Zahlung abgelaufen. |
| checkout.failed | Ein bezahlter Checkout wurde rückgängig gemacht, zum Beispiel nach einer Erstattung. |
Fehler
| Status | Code | Was du dem Kunden sagst |
|---|---|---|
| 404 | VOUCHER_INVALID | Wir konnten diesen Code nicht finden. Prüfe ihn und versuche es erneut. |
| 409 | VOUCHER_ALREADY_REDEEMED | Dieser Gutschein wurde bereits eingelöst. |
| 409 | VOUCHER_RESERVED | Dieser Gutschein wird gerade in einer anderen Zahlung verwendet. |
| 422 | VOUCHER_EXPIRED | Dieser Gutschein ist abgelaufen. |
| 422 | UNIVERSAL_NOT_ACCEPTED | Wir akzeptieren keine Universal-Gutscheine. Verwende einen Gutschein für diese Website. |
| 422 | CURRENCY_MISMATCH | Dieser Gutschein lautet auf eine andere Währung. |
| 429 | TOO_MANY_INVALID_ATTEMPTS | Zu viele Versuche. Warte ein paar Minuten und versuche es erneut. |
Fehler folgen RFC 7807 (application/problem+json) mit einem stabilen Code und einer request_id.
Diese Seite fasst die API zusammen. Die vollständige Referenz mit allen Feldern findest du unter www.vouchereto.com/docs/reference.
Irgendwo hängen geblieben?
Schreib an [DEVELOPER SUPPORT EMAIL]. Jede Nachricht liest ein Entwickler.
- OpenAPI-Spezifikation
- Postman-Collection
- API-Status · [URL]
- Changelog