Developer docs

Payment intents

Create a provider-agnostic payment intent for a reservation's deposit — what you send, what comes back, and why no card data ever touches this API.

A payment intent records that a deposit is owed for a reservation and hands you what a payment provider needs to collect it. The API never sees card numbers: the intent carries a clientSecret for the provider's own client-side flow, or a checkoutUrl to send the guest to. It follows the same key rules as the rest of /api/venues/**. The embeddable widget does not call it — it stops at the reservation and leaves the deposit to the venue's console or to your server (Booking flow); your own page may call it with a publishable key after a reservation with depositRequired: true, exactly as shown below.

Endpoints

POST /api/venues/{venueSlug}/payment-intents

Request body (Content-Type: application/json)

Field Required Meaning
reservationReference yes The reservation's reference (BDP-XXXX)
amount yes 0.01–100000, normally the reservation's depositAmount
currency yes Three-letter ISO 4217 code, the reservation's currency
provider no Reserved for choosing a provider when more than one is configured; today it is ignored — the provider is decided by server configuration (fake by default, stripe once Stripe:SecretKey is set)

Response 201 Created

Field Type Meaning
id GUID The intent
reservationReference string What it pays for
amount, currency decimal, string What is owed
status string The provider's status — provider-specific, e.g. RequiresConfirmation for fake, a Stripe Checkout Session status such as open for stripe
provider string Which provider created it
clientSecret string Hand this to the provider's client library on the guest's device — never log it
checkoutUrl string or null When set, redirect the guest there instead
createdAt ISO 8601 instant When the intent was created
{
  "id": "79501bb3-1e05-4827-82ed-1086e889b3bd",
  "reservationReference": "BDP-KSQS",
  "amount": 20.00,
  "currency": "EUR",
  "status": "RequiresConfirmation",
  "provider": "fake",
  "clientSecret": "pi_fake_156d81370b0445619159a5028cc87bff_secret_82d75f634cbb4beaaf530982b18e492c",
  "createdAt": "2026-09-15T12:55:15.2187185+00:00",
  "checkoutUrl": null
}

Errors

Status When
400 A field fails validation (errors names it)
404 No venue with that slug, or no reservation with that reference at this venue
409 This venue has not enabled online payments — skip the deposit step and treat the reservation as confirmed by the venue

curl

curl -X POST "https://api.bookdineplay.com/api/venues/your-venue/payment-intents" \
  -H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
  -H "Origin: https://www.your-venue.example" \
  -H "Content-Type: application/json" \
  -d '{ "reservationReference": "BDP-7K2Q", "amount": 20.00, "currency": "EUR" }'

JavaScript

const intent = await (await fetch('https://api.bookdineplay.com/api/venues/your-venue/payment-intents', {
  method: 'POST',
  headers: { 'X-BookDinePlay-Key': 'bdp_pk_your_publishable_key', 'Content-Type': 'application/json' },
  body: JSON.stringify({ reservationReference: reservation.reference, amount: reservation.depositAmount, currency: reservation.currency })
})).json();
if (intent.checkoutUrl) location.assign(intent.checkoutUrl);

C#

var intent = await client.CreatePaymentIntentAsync("your-venue", new CreatePaymentIntentRequest
{
    ReservationReference = reservation.Reference,
    Amount = reservation.DepositAmount ?? 0m,
    Currency = reservation.Currency
}, cancellationToken);

Next steps

  • Reservations — where depositAmount comes from.
  • .NET SDKCreatePaymentIntentAsync and the exception it throws on 409.