Booking policies, deposits & sources
Each restaurant can define deposit and guarantee policies, configure separate reservation types, and attribute every booking to a source.
Restaurants don't take every booking on the same terms — a wedding party needs a deposit, a Tuesday lunch does not. Onboard ships three policy modes that you can combine per restaurant and per reservation type (indoor, terrace, lounge…).
Three policy modes
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| Free | free | — | — | No payment details required. Default for most tables. Free cancellation up to a configurable window before the booking. |
| Deposit | deposit | — | — | Guest pays a fixed amount or a percentage of expected revenue via Stripe. On no-show the deposit is captured. |
| Guarantee | guarantee | — | — | Card on file as a guarantee — not charged unless the guest no-shows, in which case a configurable flat fee applies. |
Deposit flow
A booking with a deposit redirects the guest from the standard reservation form to a Stripe Checkout page. The reservation is only confirmed once payment succeeds — otherwise it expires automatically after 15 minutes. The confirmation email shows the amount and a receipt.
Cancellation window
Each policy defines how long before the reservation a guest can cancel for free. The default for deposits is 48 hours; after that the restaurant keeps the amount. Late cancellations can still be refunded manually — admins decide case by case.
Reservation types
A named slot type (e.g. "Indoor", "Terrace", "Lounge") that bundles a subset of tables and can carry its own hours, capacity and policy.
Reservation types are opt-in via widget settings. When on, the booking form shows a picker and only displays slots available for the chosen type. The AI booking gateway reads the same schema and returns the available types to the agent.
Source attribution
Every reservation carries a source_id column that points at a row in reservation_sources. The table is per restaurant and stores a name, a slug, a kind (direct, widget, ai-agent, phone, google …) and optional UTM parameters.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| kind | 'direct' | 'widget' | 'ai-agent' | 'phone' | 'google' | 'other' | — | — | Coarse class for reports and filters. |
| integration_name | string | — | — | Friendly connector name, e.g. "ChatGPT", "Claude.ai Connector", "Concierge XY". |
| utm_source / medium / campaign | string | — | — | Optional. Picked up by the widget embed if present and surfaced in reports. |
kind='ai-agent' source row is upserted per restaurant. The legacy source free-text column is kept for compatibility, but new reports read source_id.