Subscription billing
The venue subscription model: trials, the grace window, survivor entitlements and what happens when renewal is cancelled.
This page is about DineGlobe’s own subscription ledger — what a venue pays to use DineGlobe, not how a venue charges its guests (that is Payments, /docs/money/payments/). The V1 plan is simple: one monthly per-venue plan, a 30-day trial and a 7-day dunning grace. The subscription state changes only through signature-verified billing events, and even then only one entitlement can ever be taken away: new bookings. Existing bookings, guest cancellation, refunds and exports keep working no matter what billing does.
The plan and the lifecycle
V1 sells a single plan: monthly, per venue, USD 49.00 (4,900 minor units), plan id v1-venue-monthly. The expected price id is owned by the server (default price_v1_venue_monthly_usd_4900); an event that names any other price is refused — see BILLING_PRICE_MISMATCH below.
- Starting. The owner or org admin starts the venue’s 30-day trial from the
SaaS subscriptionpanel at/app/panels. A manager or host session is refused: the commercial contract is never delegated below organization level. A venue that already holds a live subscription refuses with 409SUBSCRIPTION_EXISTS. - Stopping renewal. Cancelling at period end stops the next charge; the venue keeps every entitlement it paid for through the end of the current period.
Subscription states and what each means for booking intake:
| State | New booking intake | Reason codes | Notes |
|---|---|---|---|
TRIAL |
Open until the trial deadline, then suspended | trial / trial_ended |
An expired trial suspends intake like anything else. |
ACTIVE |
Open | active |
Paid and current. |
PAST_DUE |
Open during the 7-day grace, then suspended | dunning_grace / grace_ended |
A failed payment starts the grace window. |
CANCELLED |
Open until the paid period ends, then suspended | paid_through_period / period_ended |
Entitlements survive to the period end. |
| no subscription row | Open | no_subscription |
The pilot posture — see below. |
The subscription view in the panel shows the state, the trial, period and grace deadlines, the cancel-at-period-end flag and the latest invoice line (reference, amount, currency, status); the intake probe shows whether new bookings are open right now and which reason code applies.
What can and cannot stop
This is the load-bearing rule of the billing module: when billing goes wrong, existing guest obligations survive. Whatever the subscription state, these always keep working:
- managing existing bookings,
- guest cancellation,
- refunds,
- exports.
Only new booking intake can stop. When it does, every booking path — guest self-service, staff walk-in and CSV import — refuses with 402 SUBSCRIPTION_INTAKE_SUSPENDED. The remedy is to settle the subscription (pay or renew); new bookings resume automatically once entitlement is restored. Nobody needs to re-enable anything by hand.
Do not confuse this with a platform suspension: an operator can also suspend a venue’s intake directly, which answers 422 PLATFORM_INTAKE_SUSPENDED — same survivor rights, different actor and code.
How the state changes
Entitlements change only through signature-verified billing events. A browser success return proves nothing and is not input anywhere in the billing module. The discipline:
- The signature is verified over the raw bytes before anything is parsed or trusted — a strict
t=…,v1=…scheme with a 5-minute tolerance. A forged body is refused before anything is stored (BILLING_WEBHOOK_REJECTED). - A verified event is stored exactly once; a duplicate delivery answers “the original receipt stands, nothing stored”.
- Routing comes from our own subscription rows, never from the callback alone: an event about a subscription nobody owns is unroutable and stores nothing (
BILLING_EVENT_UNROUTABLE).
| Event | Effect on the subscription |
|---|---|
subscription.created |
Binds the subscription and moves to ACTIVE. The event’s price must be the V1 plan price, or the event is refused. |
subscription.updated (provider state active) |
ACTIVE, grace cleared. |
subscription.updated (provider state past_due) |
PAST_DUE with a fresh 7-day grace window. |
subscription.updated (provider state canceled) |
CANCELLED. |
invoice.paid |
ACTIVE; any grace clears. |
invoice.payment_failed |
PAST_DUE with a 7-day grace window. |
subscription.canceled |
CANCELLED. |
A reconciliation sweep — the worker’s tick, or staff-fired from the panel — applies stored events to their subscriptions: duplicate and out-of-order events (older than the newest applied) reconcile to a no-op, and each applied state change bumps the row version and writes its invoice reference.
Billing events do not arrive on the booking-payments webhook endpoint: that endpoint refuses the SAAS_BILLING domain, and SaaS billing carries its own surface with the same signature discipline.
Billing error codes
| Code | Meaning and remedy |
|---|---|
SUBSCRIPTION_EXISTS |
This venue already has a live subscription. Manage the existing one instead of starting another. |
BILLING_WEBHOOK_REJECTED |
Signature or routing failed before anything was stored. Check the provider configuration; the sender must not replay the same callback. |
BILLING_EVENT_UNROUTABLE |
No stored subscription matches the event. Reconcile the billing account; the event stays evidenced. |
BILLING_PRICE_MISMATCH |
The event names a price the platform does not sell. Verify the provider’s price configuration. |
SUBSCRIPTION_INTAKE_SUSPENDED |
New bookings are blocked (grace-expired, expired trial or ended period). Settle the subscription; existing management, cancellation, refunds and exports stay available. |
Who may manage billing
billing.manage and billing.read belong to the ownership tier — owner and org admin only, as described in the Owner & org admin guide. A manager or host session is refused on every commercial command; reading the state is also owner-tier.
The pilot posture
No billing provider is configured in the live pilot environment and no commercial activation has happened; the subscription ledger runs in sandbox posture. Pilot venues carry no subscription rows at all, so booking intake stays open for everyone — the gate only suspends a venue that actually has a subscription telling it to. Commercial activation waits on the operator’s launch review (payment account and pricing evidence) plus a real non-sandbox provider; until then nothing bills, and nothing pretends to.
What this means for you as a venue owner during the pilot: you pay nothing, no trial clock is running against you, and the entitlement machinery you see in the panel is real code awaiting a real provider. See What works today & known limits for the pilot’s full honest picture, and Error codes & fixes for the complete code reference.