Anmelden um den Slug und den veröffentlichbaren Schlüssel Ihrer Location in jedem Beispiel zu sehen.
Ihr Konto hat noch keine Location, die Beispiele behalten daher ihre Platzhalter. Abmelden
Angemeldet als · . Legen Sie in der Konsole einen veröffentlichbaren Schlüssel an und laden Sie die Seite neu, um ihn hier zu sehen. Abmelden
Angemeldet als · . Die Beispiele zeigen den veröffentlichbaren Schlüssel Ihrer Location. Abmelden
Entwicklerdokumentation
Gutscheine
Geschenkgutscheine online verkaufen, einen ohne Schlüssel über seinen Code abfragen und Gäste damit Tab, Anzahlung oder Tickets bezahlen lassen.
Eine Location verkauft über diese Routen Geschenkgutscheine, und Gäste lösen sie am Tisch oder online ein. Es gibt drei Arten: einen Betrag (in Teilen einlösbar, bis das Guthaben aufgebraucht ist), einen Prozentrabatt auf eine Rechnung und einen Menüartikel. Die Location legt fest, was sie verkauft, zu welchem Preis und wie lange ein Gutschein gilt; in der Konsole stellt sie Gutscheine in jedem Tarif von Hand aus, der Online-Verkauf braucht Premium.
Zwei der Routen unten brauchen Ihren Schlüssel, wie jede Route unter /api/venues/**: die Angebote und der Checkout. Die dritte, die Abfrage per Code, braucht keinen: Wer den Code eines Gutscheins hat, hat den Gutschein. Zum Bezahlen mit einem Gutschein gibt es keine eigene Route – Tab-, Anzahlungs- und Ticketzahlung nehmen einen optionalen Gutscheincode an (Mit einem Gutschein bezahlen).
Der Code ist ein Credential
Ein Gutscheincode hat 20 Zeichen und wird in fünf Gruppen angezeigt (K7QM-2XRP-9DTA-HV3N-8W4F). Das letzte Zeichen ist ein Prüfzeichen, sodass ein Tippfehler vor jeder Anfrage auffällt; die SDKs prüfen es für Sie. Wer den Code hat, sieht den Wert des Gutscheins und kann ihn ausgeben, genau wie bei einer Geschenkkarte. Deshalb:
- Loggen Sie ihn nie und setzen Sie ihn nie in eine eigene URL – nur die Abfrage unten trägt ihn im Pfad, und BookDinePlay entfernt ihn aus den eigenen Logs und Traces.
- Senden Sie ihn sonst im Request-Body: Tab-Zahlung, Anzahlung und Ticket-Checkout nehmen ihn alle als
voucherCode. - Zeigen Sie keinen Code, den Sie nicht vom Gast haben. Der Code entsteht erst, wenn der Gutschein bezahlt ist; er erreicht Käufer oder Beschenkte per E-Mail, nie über die Antwort des Checkouts.
- Rechnen Sie mit einer Antwort für „nein“. Ein vertippter, unbekannter, unbezahlter oder fremder Code ist dasselbe
404voucher-not-found, damit Codes nicht durchprobiert werden können.
Die reference (GV-…), die ein Checkout zurückgibt, ist kein Credential: Sie bezeichnet den Kauf für den Support und darf geloggt werden.
Endpunkte
GET /api/vouchers/{code}
Ohne Schlüssel. code ist der Gutscheincode in jeder Form, die ein Gast tippen oder scannen könnte: die Anzeigeform (K7QM-2XRP-9DTA-HV3N-8W4F), die 20 Zeichen ohne Bindestriche, jeweils auch in Kleinbuchstaben. Eine vollständige URL der Gastseite wird hier nicht angenommen: Nehmen Sie ihr letztes Segment. Senden Sie ihn prozentkodiert als ein Pfadsegment und halten Sie ihn aus Ihren eigenen Logs heraus – er ist ein Inhaber-Credential. Hängt nicht am Tarif: Ein Gutschein, der ausgegeben wurde, als der Tarif der Location es erlaubte, funktioniert auch nach einem Downgrade weiter.
Antwort 200 OK
| Feld | Typ | Bedeutung |
|---|---|---|
venueSlug, venueName |
string | Die Location, die den Gutschein ausgegeben hat |
displayCode |
string | Der Code in seiner Anzeigeform |
kind |
string | Amount, Percentage oder Item |
status |
string | Active, PartlyUsed, UsedUp, Expired oder Voided |
currency |
string | ISO-4217-Währung aller Geldfelder |
balance |
number oder null | Was ein Amount-Gutschein noch bezahlen kann; null bei den anderen Arten |
faceValue |
number oder null | Der Wert, mit dem ein Amount-Gutschein ausgegeben wurde |
percentage, maxDiscount |
number oder null | Der Rabatt eines Percentage-Gutscheins und seine optionale Obergrenze in Geld |
itemName |
string oder null | Der Menüartikel eines Item-Gutscheins |
expiresOn |
string | Der letzte gültige Tag, Ortszeit der Location, yyyy-MM-dd |
terms |
string oder null | Die Gutscheinbedingungen der Location zum Zeitpunkt der Ausgabe |
recipientName, giftMessage |
string oder null | Was der Käufer für den Empfänger geschrieben hat |
guestUrl |
string | Die Gastseite dieses Gutscheins |
qrSvg |
string | Ein SVG-QR-Code von guestUrl |
Die Antwort enthält nie die Buchungshistorie des Gutscheins oder Name und E-Mail-Adresse des Käufers. balance ist, was sich jetzt ausgeben lässt: Wert, den eine laufende Zahlung reserviert hält, zählt nicht mit.
Fehler. 404 mit dem Problemtyp https://bookdineplay.com/docs/api/errors/voucher-not-found für jeden Code, der zu keinem ausgegebenen Gutschein gehört – vertippt, unbekannt oder ein nie bezahlter Kauf. Ein abgelaufener oder entwerteter Gutschein ist kein Fehler: Er antwortet mit 200 und diesem status. Die Antwort ist für alle gleich, damit Codes nicht durchprobiert werden können. 429 mit einem Retry-After-Header, wenn ein Client mehr als 30-mal pro Minute fragt – die einzige Route der API mit Ratenbegrenzung, weil es keinen Schlüssel gibt, an dem man zählen könnte (Ratenbegrenzung).
curl
curl "https://api.bookdineplay.com/api/vouchers/K7QM-2XRP-9DTA-HV3N-8W4F"JavaScript
const voucher = await client.voucher(code); // sendet keinen Schlüssel; null, wenn unbekannt oder vertippt (bei einem vertippten Code ganz ohne Anfrage)C#
var voucher = await client.GetVoucherAsync(code, cancellationToken); // sendet keinen Schlüssel; null, wenn unbekanntGET /api/venues/{venueSlug}/vouchers/offers
Was die Location gerade online verkauft. Antwortet in jedem Tarif: Wenn Gutscheine nicht online gekauft werden können, ist onlineSaleAvailable false, offers leer und unavailableReason nennt den Grund. Titel, Bedingungen und der Gültigkeitssatz folgen dem Accept-Language der Anfrage.
Antwort 200 OK
| Feld | Typ | Bedeutung |
|---|---|---|
venueSlug, venueName, currency |
string | Die Location und die Währung aller Preise |
onlineSaleAvailable |
boolean | Ob ein Checkout gestartet werden kann |
unavailableReason |
string oder null | not-offered, validity-not-set, validity-too-short, payments-off, not-in-plan oder payouts-not-connected |
offers |
array | Ein Eintrag je Produkt: productId, kind, title, price (null, wenn der Käufer den Betrag wählt), customAmount, minAmount, maxAmount, itemName |
terms |
string oder null | Die Gutscheinbedingungen der Location |
validityDescription |
string oder null | Wie lange ein heute gekaufter Gutschein gültig ist |
Zeigen Sie einem Gast für jeden unavailableReason denselben Satz, höchstens not-offered eigens: Die anderen Gründe betreffen die Einrichtung der Location, nicht etwas, das ein Gast ändern kann. Der Gutschein-Shop macht genau das.
curl
curl "https://api.bookdineplay.com/api/venues/your-venue/vouchers/offers" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example"JavaScript
const offers = await client.voucherOffers();
if (!offers.onlineSaleAvailable) showNotAvailable(offers.unavailableReason);C#
var offers = await client.GetVoucherOffersAsync("your-venue", cancellationToken); // null, wenn die Location unbekannt istPOST /api/venues/{venueSlug}/vouchers/checkout
Einen Gutschein kaufen: öffnet eine Stripe-Checkout-Sitzung auf dem eigenen verbundenen Stripe-Konto der Location und gibt die URL zurück, zu der Sie den Käufer schicken. Braucht den Premium-Tarif, eingeschaltete Online-Zahlungen und ein Auszahlungskonto, das verkaufen darf. Der Code des Gutscheins existiert noch nicht: Er wird erst erzeugt, wenn die Zahlung bestätigt ist, und erreicht den Käufer oder die beschenkte Person per E-Mail. Senden Sie einen Idempotency-Key-Header, damit eine wiederholte Anfrage denselben Checkout zurückgibt statt einen zweiten zu öffnen; siehe Idempotenz-Probleme. Das .NET SDK und der Gutschein-Shop senden einen für Sie; bei client.checkoutVoucher übergeben Sie { idempotencyKey } selbst – ohne ihn sendet der JavaScript-Client keinen, und ein Wiederholungsversuch kann einen zweiten Checkout öffnen.
Request-Body (Content-Type: application/json)
| Feld | Pflicht | Bedeutung |
|---|---|---|
productId |
ja | Die productId eines Angebots |
amount |
freie Beträge | Der zu kaufende Wert, zwischen minAmount und maxAmount des Angebots |
buyerName, buyerEmail |
ja | Wer bezahlt |
recipientName, recipientEmail, giftMessage |
nein | Für wen der Gutschein ist; die Nachricht hat höchstens 500 Zeichen |
deliverOn |
nein | yyyy-MM-dd, Ortszeit der Location, von heute bis ein Jahr im Voraus: der Tag, an dem die E-Mail an die beschenkte Person geht. Braucht recipientEmail |
language |
nein | en oder de; Standard ist das Accept-Language der Anfrage, danach die Sprache der Location |
successUrl, cancelUrl |
nein | Wohin Checkout den Käufer schickt. Muss https sein und auf der Origin-Liste dieses API-Schlüssels oder der eigenen Gast-App der Plattform liegen; ohne Angabe gilt die eingebaute Dankeseite |
Antwort 201 Created: reference (GV-…, nur zur Anzeige), checkoutUrl (dorthin schicken Sie den Käufer) und expiresAt (ab wann die Checkout-Sitzung keine Zahlung mehr annimmt).
Ein bezahlter Gutschein gilt mindestens ein Jahr ab dem Tag seiner Ausgabe. Ein Kauf, dessen Zahlung nie eintrifft, erzeugt keinen Gutschein; er wird 30 Tage nach Ablauf seines Checkouts gelöscht.
Fehler
| Status | Wann |
|---|---|
400 |
Ein Feld ist ungültig (errors nennt es), eine Rücksprung-URL wird abgelehnt, oder die Gültigkeitsregel der Location gibt einem bezahlten Gutschein weniger als ein Jahr (voucher-validity-too-short) |
400 |
errors["Idempotency-Key"]: Der Schlüssel ist länger als 200 Zeichen |
403 |
feature-not-in-plan: Online-Verkauf braucht Premium |
404 |
Keine Location mit diesem Slug |
409 |
voucher-sale-not-available (Online-Verkauf aus, Produkt nicht online verkauft, Zahlungen aus oder kein Auszahlungskonto, das verkaufen darf) oder voucher-validity-not-set |
409 |
idempotency-key-reused oder checkout-in-progress |
curl
curl -X POST "https://api.bookdineplay.com/api/venues/your-venue/vouchers/checkout" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example" \
-H "Idempotency-Key: 4f9c2a1e8b7d4c3f9e0a1b2c3d4e5f60" \
-H "Content-Type: application/json" \
-d '{ "productId": "3f2a1b4c5d6e4f708192a3b4c5d6e7f8", "buyerName": "Ben Buyer", "buyerEmail": "ben@example.com", "recipientName": "Ada" }'JavaScript
const checkout = await client.checkoutVoucher(
{ productId, buyerName: 'Ben Buyer', buyerEmail: 'ben@example.com', recipientName: 'Ada' },
{ idempotencyKey: attemptKey } // ein crypto.randomUUID() je Versuch, beim Wiederholen derselbe
);
window.location.assign(checkout.checkoutUrl);C#
var checkout = await client.StartVoucherCheckoutAsync("your-venue",
new StartVoucherCheckoutRequest { ProductId = productId, BuyerName = "Ben Buyer", BuyerEmail = "ben@example.com", RecipientName = "Ada" },
idempotencyKey: attemptKey, cancellationToken);Mit einem Gutschein bezahlen
Ein Gast löst einen Gutschein online ein, indem er dessen Code zu einer Zahlung gibt, die er ohnehin macht. Die drei Zahlungen nehmen ein optionales voucherCode im Body; ohne ändert sich nichts.
| Zahlung | Feld | Akzeptierte Arten | Was zurückkommt |
|---|---|---|---|
Ein Tisch-Tab, /api/qr/{token}/payment |
voucherCode |
Amount, Percentage |
voucherAmount, paidInFull |
Eine Reservierungsanzahlung, /api/venues/{venueSlug}/payment-intents |
voucherCode |
Amount |
voucherAmount, cardAmount |
Event-Tickets, /api/venues/{venueSlug}/events/{eventSlug}/tickets/checkout |
voucherCode |
Amount |
voucherAmount, amountDue |
Für alle drei gelten dieselben Regeln:
- Erst zahlt der Gutschein, die Karte zahlt den Rest. Der Wert wird reserviert, solange der Gast auf der Stripe-Seite ist, sodass er nicht zweimal ausgegeben werden kann; bricht der Gast ab, verfällt die Reservierung von selbst.
- Die Karte zahlt mindestens den Mindestbetrag von Stripe – 0,50 € in EUR; Stripe legt ihn je Währung fest. Stripe lehnt kleinere Kartenzahlungen ab. Läge der Rest zwischen 0,01 € und 0,49 €, zahlt der Gutschein etwas weniger, sodass die Karte genau 0,50 € zahlt, und der Gutschein behält die Differenz: Ein 50-€-Gutschein auf einem Tab über 50,30 € zahlt 49,80 €. Beträgt der ganze Betrag 0,50 € oder weniger und deckt der Gutschein ihn nicht, lässt er sich dafür nicht verwenden:
409mitreasonbelow-card-minimum, bei allen drei Zahlungen. - Ein Gutschein, der alles deckt, öffnet keine Zahlungsseite. Die Zahlung ist sofort abgeschlossen, und
checkoutUrlist die Erfolgsseite – ein Client, der einfachcheckoutUrlfolgt, funktioniert also in beiden Fällen. Prüfen SiepaidInFull,cardAmountoderamountDue, um die Weiterleitung zu sparen. - Eine Erstattung geht beim Gutscheinteil auf den Gutschein zurück. Nur der Kartenteil geht zurück auf die Karte. Ein abgelaufener Gutschein wird um 30 Tage ab der Erstattung verlängert, damit der Gast den zurückgebuchten Wert noch nutzen kann. Ein Gutschein, den die Location entwertet hat, bleibt entwertet: Die Erstattung wird auf ihm vermerkt, den Wert klärt die Location direkt mit dem Gast.
- Ein Prozentgutschein ist ein Rabatt auf die ganze Rechnung, vor jedem Betragsgutschein angerechnet und auf den offenen Betrag begrenzt. Er wird einmal eingelöst.
- Kein Tarif-Gate. Bezahlen mit einem Gutschein und dessen Erstattung funktionieren in jedem Tarif. Die eigenen Bedingungen einer Zahlung gelten weiter – ein Tab braucht Bestellen, eine Anzahlung braucht Anzahlungen, Tickets brauchen Ticketverkauf –, und der Kartenteil braucht Online-Zahlungen wie ohne Gutschein.
- Überall dieselben Probleme. Ein Code wird mit einem der Gutschein-Probleme abgelehnt, egal zu welcher Zahlung er gegeben wurde.
Artikelgutscheine löst das Personal am Tisch ein und wählt dabei die Rechnungszeile, die sie bezahlen.
Nächste Schritte
- JavaScript-Gutscheine – der Gutschein-Shop, die Guthabenabfrage und die Gutscheinfelder in den Widgets.
- .NET SDK – die typisierten Gutschein-Aufrufe.
- Fehler – jedes Gutschein-Problem und was Sie anzeigen.