API referenceCheckout

Checkout

6 operations. Every schema and example on this page is generated from the platform contract.

Preview a promo code against the current basket.

Read-only cart promo preview using the SAME validator checkout uses. Enumeration-safe: invalid / expired / used-up codes all collapse to one generic "can't be used" message; only min_spend and email_required stay specific. With basket lines it returns a server-computed discount + per-line strike (display == charge).

auth none, publicop previewPromoCodeidempotent retryrate limitederrors

Request body

store_codestring, nullableoptional
store_idstring, nullableoptional
codestring, nullableoptional

The promo code entered in the cart (absent/null/empty/oversized collapses to the generic message).

subtotal_penceintegerrequired

Current basket subtotal in pence.

customer_idstring, nullableoptional
customer_emailstring, nullableoptional
device_fingerprintstring, nullableoptional
linesarray of objectoptional

Optional basket lines → a server-computed estimate + per-line strike for item-scope codes.

3 child fields
menu_item_idstringoptional
quantitynumberoptional
unit_amount_pencenumberoptional

Response, 200

validbooleanrequired
reasonstringoptional

min_spend | email_required (the only non-collapsed reasons).

messagestringoptional

Shopper-facing message (generic "can't be used" collapses all enumeration-sensitive failures).

discount_typestring, nullableoptional
discount_valuenumber, nullableoptional
descriptionstring, nullableoptional
stackable_with_voucherbooleanoptional
min_spend_pencenumber, nullableoptional
estimated_discount_pencenumberoptional
applies_tostringoptional
affected_item_idstring, nullableoptional
discounted_unit_pencenumber, nullableoptional
curl -X POST "https://www.membber.com/api/v1/checkout/promo/preview" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "subtotal_pence": 1500
  }'
Response, 200
{
  "valid": true,
  "reason": "Added at the front desk",
  "message": "Added at the front desk",
  "discount_type": "<discount_type>",
  "discount_value": 1,
  "description": "Added at the front desk",
  "stackable_with_voucher": true,
  "min_spend_pence": 1500,
  "estimated_discount_pence": 1500,
  "applies_to": "<applies_to>",
  "affected_item_id": "257c9efc-0000-4000-8000-d0c500000025",
  "discounted_unit_pence": 1500
}

Create a public guest-checkout (hosted Stripe Checkout) session.

Public guest checkout for the Android stopgap / web /pay. Re-prices + re-validates the basket server-side and creates a hosted Stripe Checkout session. Idempotent via the body idempotency_key (order-level replay reuses the same session). When a member is signed in (verified Bearer session) the order is anchored to their customer id so loyalty lands on their card; a client-supplied customer_id is always ignored.

auth none, publicop createCheckoutSessionidempotent retryrate limitederrors

Request body

store_codestringrequired

Public store code.

itemsarray of objectrequired

Basket lines (re-priced + re-validated server-side).

2 child fields
menu_item_idstringrequired
quantityintegerrequired
idempotency_keystringoptional

Order idempotency key (body, or the Idempotency-Key header). Order-level replay reuses the same session.

fulfilmentobjectoptional
2 child fields
modestring, nullableoptional
table_numberstring, nullableoptional
checkout_trace_idstring, nullableoptional
tip_penceinteger, nullableoptional
customerobjectoptional

Anonymous contact details (loyalty resolves by email at webhook time when no member is signed in).

4 child fields
emailstring, nullableoptional
namestring, nullableoptional
phonestring, nullableoptional
marketing_consentboolean, nullableoptional
device_fingerprintstring, nullableoptional
promo_codestring, nullableoptional
order_typeenumoptional
buy_nowcollect
collection_modeenumoptional
nowscheduled
slot_idstring, nullableoptional
requested_collection_atstring, nullableoptional
fulfilment_groupsarray of objectoptional

Mixed-cart groups (take-now + collect).

5 child fields
roleenumrequired
nowcollect
itemsarray of objectrequired
2 child fields
menu_item_idstringrequired
quantityintegerrequired
collection_modeenumoptional
nowscheduled
requested_collection_atstring, nullableoptional
slot_idstring, nullableoptional

Response, 200

sessionobjectrequired

The created hosted-checkout session (Stripe Checkout URL + order handle).

8 child fields
order_idstringrequired
order_numberstringrequired
statusstringrequired
checkout_urlstring, nullablerequired
stripe_checkout_session_idstring, nullablerequired
expires_atstring, nullablerequired
total_pencenumberrequired
currencystringrequired
curl -X POST "https://www.membber.com/api/v1/checkout/sessions" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "store_code": "EXAMPLE10",
    "items": [
      {
        "menu_item_id": "ca65a6e7-0000-4000-8000-d0c5000000ca",
        "quantity": 1
      }
    ]
  }'
Response, 200
{
  "session": {
    "order_id": "4991ffac-0000-4000-8000-d0c500000049",
    "order_number": "<order_number>",
    "status": "<status>",
    "checkout_url": "https://example.com/image.jpg",
    "stripe_checkout_session_id": "3c37c50b-0000-4000-8000-d0c50000003c",
    "expires_at": "<expires_at>",
    "total_pence": 1500,
    "currency": "GBP"
  }
}

Get the order status behind a hosted-checkout session.

Public status poll after a hosted Stripe Checkout redirect: resolves the order by stripe_checkout_session_id and returns its status (paid/expired/etc.), totals, and collection code. 404 when no order matches the session.

auth none, publicop getCheckoutSessionrate limitederrors

Parameters

sessionIdstringpathrequired

Response, 200

orderobjectrequired

The order behind the checkout session (post-redirect status polling).

11 child fields
idstringrequired
order_numberstring, nullablerequired
statusstringrequired
total_pencenumber, nullablerequired
currencystring, nullablerequired
customer_emailstring, nullablerequired
created_atstringrequired
paid_atstring, nullablerequired
expires_atstring, nullablerequired
order_typestring, nullablerequired
collection_codestring, nullablerequired
curl -G "https://www.membber.com/api/v1/checkout/sessions/243a3e51-0000-4000-8000-d0c500000024"
Response, 200
{
  "order": {
    "id": "00000d1b-0000-4000-8000-d0c500000000",
    "order_number": "<order_number>",
    "status": "<status>",
    "total_pence": 1500,
    "currency": "GBP",
    "customer_email": "alex@example.com",
    "created_at": "<created_at>",
    "paid_at": "<paid_at>",
    "expires_at": "<expires_at>",
    "order_type": "<order_type>",
    "collection_code": "EXAMPLE10"
  }
}

Ask to be told when this order is ready (App Clip's eight-hour window).

Binds an APNs device token to the order behind a hosted-checkout session, for the eight hours Apple grants an App Clip without a permission prompt. Authenticated by possession of the session id, the same secret the status poll uses. Refuses an order that has not been paid for (409): an unpaid basket may never become an order, and the window would be spent on nothing. Idempotent per (order, device), re-registering EXTENDS the window rather than producing a second banner. 404 when no order matches the session.

auth none, publicop registerCheckoutSessionNotificationsidempotent retryrate limitederrors

Parameters

sessionIdstringpathrequired

Request body

device_tokenstringrequired

The APNs device token, lowercase hex. Bound to this order only, and only for Apple's eight-hour window.

bundle_idstring, nullableoptional

The Clip's OWN APNs topic, the parent bundle id with `.Clip` appended. A push aimed at the parent id never reaches the Clip.

sandboxbooleanoptional

True for a DEBUG build (APNs sandbox). Sending the wrong one is the classic silent "push never arrives".

Response, 200

expires_atstringrequired

When the grant lapses. Never extended beyond Apple's window.

window_hoursnumberrequired

Apple's ephemeral grant, in hours. Not a tunable, it is the length of the grant.

curl -X POST "https://www.membber.com/api/v1/checkout/sessions/243a3e51-0000-4000-8000-d0c500000024/notifications" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "device_token": "<device_token>"
  }'
Response, 200
{
  "expires_at": "<expires_at>",
  "window_hours": 1
}

Fetch a store's checkout + Order & Collect settings.

Merchant read of the full checkout configuration for one store.

Parameters

store_idstring · uuidqueryrequired

Store whose checkout settings to fetch.

Response, 200

checkout_enabledbooleanrequired
menu_checkout_enabledbooleanrequired
allow_guest_checkoutbooleanrequired
test_mode_enabledbooleanrequired
currencystringrequired
min_amount_pencenumberrequired
max_amount_pencenumberrequired
prices_include_vatbooleanrequired
vat_receipts_enabledbooleanrequired
vat_numberstring, nullablerequired
tip_enabledbooleanrequired
tip_presets_pencearray of numberrequired
service_charge_enabledbooleanrequired
service_charge_percentnumberrequired
service_charge_labelstringrequired
customer_receipts_enabledbooleanrequired
receipt_email_collectionstringrequired
refund_window_daysnumberrequired
purchase_to_loyalty_enabledbooleanrequired
loyalty_on_dropsbooleanrequired

Drop orders (guest_orders.batch_drop_id set) earn a stamp. Off by default.

loyalty_on_click_collectbooleanrequired

Click & Collect orders (order_type collect, no drop) earn a stamp. On by default.

loyalty_on_buy_nowbooleanrequired

Buy-now orders and POS card payments earn a stamp. On by default.

loyalty_rulestringrequired
loyalty_spend_threshold_pencenumber, nullablerequired
order_fulfilment_modestringrequired
public_notestring, nullablerequired
offline_messagestring, nullablerequired
buy_now_enabledbooleanrequired
collect_enabledbooleanrequired
collect_modestringrequired
default_prep_minutesnumberrequired
max_concurrent_ordersnumber, nullablerequired
orders_per_slotnumber, nullablerequired
collection_window_daysnumberrequired
slot_minutesnumberrequired
collect_window_startstringrequired
collect_window_endstringrequired
collect_daily_release_timestringrequired
collect_timezonestringrequired
collect_lead_time_minutesnumberrequired
collect_cutoff_minutesnumberrequired
collect_pausedbooleanrequired
collect_instructionsstring, nullablerequired
auto_acceptbooleanrequired
show_slot_spotsbooleanrequired
curl -G "https://www.membber.com/api/v1/checkout/settings" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  --data-urlencode "store_id=6659c139-0000-4000-8000-d0c500000066"
Response, 200
{
  "checkout_enabled": true,
  "menu_checkout_enabled": true,
  "allow_guest_checkout": true,
  "test_mode_enabled": true,
  "currency": "GBP",
  "min_amount_pence": 1500,
  "max_amount_pence": 1500,
  "prices_include_vat": true,
  "vat_receipts_enabled": true,
  "vat_number": "<vat_number>",
  "tip_enabled": true,
  "tip_presets_pence": [
    1500
  ],
  "service_charge_enabled": true,
  "service_charge_percent": 1,
  "service_charge_label": "<service_charge_label>",
  "customer_receipts_enabled": true,
  "receipt_email_collection": "alex@example.com",
  "refund_window_days": 1,
  "purchase_to_loyalty_enabled": true,
  "loyalty_on_drops": true,
  "loyalty_on_click_collect": true,
  "loyalty_on_buy_now": true,
  "loyalty_rule": "<loyalty_rule>",
  "loyalty_spend_threshold_pence": 1500,
  "order_fulfilment_mode": "<order_fulfilment_mode>",
  "public_note": "Added at the front desk",
  "offline_message": "Added at the front desk",
  "buy_now_enabled": true,
  "collect_enabled": true,
  "collect_mode": "<collect_mode>",
  "default_prep_minutes": 1,
  "max_concurrent_orders": 1,
  "orders_per_slot": 1,
  "collection_window_days": 1,
  "slot_minutes": 1,
  "collect_window_start": "<collect_window_start>",
  "collect_window_end": "<collect_window_end>",
  "collect_daily_release_time": "<collect_daily_release_time>",
  "collect_timezone": "Europe/London",
  "collect_lead_time_minutes": 1,
  "collect_cutoff_minutes": 1,
  "collect_paused": true,
  "collect_instructions": "<collect_instructions>",
  "auto_accept": true,
  "show_slot_spots": true
}

Get a store's public guest-checkout payload by code.

Public (Android stopgap / web /pay) store payload: branding, checkout + Order & Collect settings, and the purchasable menu with media, allergens, stock and prices. checkout_available reflects the resolved entitlement + Stripe readiness. fulfilment_today carries today's ordering state (whether the at-counter lanes are shut, why, and when they reopen) so a surface can say so before a basket is built.

auth none, publicop getCheckoutShoprate limitederrors

Parameters

storeCodestringpathrequired

Response, 200

storeobjectrequired

Public guest-checkout store payload (branding + settings + menu).

20 child fields
idstringrequired
codestringrequired
namestringrequired
descriptionstring, nullablerequired
logo_urlstring, nullablerequired
primary_colorstring, nullablerequired
brand_colorstring, nullablerequired
secondary_colorstring, nullablerequired
loyalty_goalnumber, nullablerequired
reward_titlestring, nullablerequired
stamp_icon_filled_urlstring, nullablerequired
stamp_icon_empty_urlstring, nullablerequired
is_activebooleanrequired
checkout_availablebooleanrequired
unavailable_reasonstring, nullablerequired
menu_versionstringrequired
menu_updated_atstring, nullablerequired
settingsobjectrequired

Full public checkout settings (currency, tips, VAT, Order & Collect, loyalty).

menu_itemsarray of objectrequired

Purchasable menu items with media, allergens, stock, prices.

fulfilment_todayobjectrequired

Today's ordering state. Null when the shop is unavailable for other reasons (nothing to time) or the resolve failed, a blip must never hide a working shop.

7 child fields
closedbooleanrequired

The AT-COUNTER lanes (buy-now / ASAP collect) are not serving right now, the day is switched off, or we are outside today's hours. NOT "no orders at all": order-ahead can still be open.

hours_closedbooleanrequired

True when `closed` is caused by the clock (outside today's Order & Collect hours) rather than by the day or a date override being switched off. Scheduled Click & Collect keeps taking pre-orders.

now_availablebooleanrequired

Buy-now (at-counter) is orderable this instant: lane on, day on, doors open, inside the hours.

opens_atstring, nullablerequired

Today's configured opening time, "HH:MM" store-local. Null when unset or open all day.

closes_atstring, nullablerequired

Today's configured closing time, "HH:MM" store-local, always the merchant's OWN value, never a normalised midnight. Null when unset or open all day.

next_open_atstring, nullablerequired

Store-local "YYYY-MM-DDTHH:MM" the at-counter lane next reopens (scanned up to 7 days over the weekday rules + date overrides, intersected with the physical door hours when buy-now is offered). Emitted only while closed; null when no reopen can be computed, show no hint rather than a wrong one.

closed_messagestringrequired

Pre-rendered reason + reopen time, the SAME sentence checkout would reject with.

curl -G "https://www.membber.com/api/v1/checkout/shop/EXAMPLE10"
Response, 200
{
  "store": {
    "id": "00000d1b-0000-4000-8000-d0c500000000",
    "code": "EXAMPLE10",
    "name": "Example name",
    "description": "Added at the front desk",
    "logo_url": "https://example.com/image.jpg",
    "primary_color": "<primary_color>",
    "brand_color": "<brand_color>",
    "secondary_color": "<secondary_color>",
    "loyalty_goal": 1,
    "reward_title": "<reward_title>",
    "stamp_icon_filled_url": "https://example.com/image.jpg",
    "stamp_icon_empty_url": "https://example.com/image.jpg",
    "is_active": true,
    "checkout_available": true,
    "unavailable_reason": "Added at the front desk",
    "menu_version": "<menu_version>",
    "menu_updated_at": "<menu_updated_at>",
    "settings": {},
    "menu_items": [
      {}
    ],
    "fulfilment_today": {
      "closed": true,
      "hours_closed": true,
      "now_available": true,
      "opens_at": "<opens_at>",
      "closes_at": "<closes_at>",
      "next_open_at": "<next_open_at>",
      "closed_message": "Added at the front desk"
    }
  }
}
WhatsApp
Book a Call
Start Free