Coupons
Create, publish, distribute, and report location-scoped offers
Managers and administrators use /coupons for campaigns in their authorized
restaurants. A campaign spanning restaurants outside your scope is Read-only
for campaign-wide changes. Only authorized restaurant names and guest rows are
shown; remaining capacity is a campaign-wide total.
Availability depends on the team's rollout configuration and readiness checks. A deployed feature or completed database migration does not by itself enable publication, QR distribution, finite capacity, or retry.
Create, save, and publish
- Open
/coupons/newand choose the authorized restaurants. A campaign uses one restaurant timezone; create separate campaigns for other timezones. - Choose a percentage, fixed amount, or free-item offer. For a new fixed-amount offer, enter the amount in USD; the currency display is read-only. Enter the title, guest-visible terms, restrictions, and exact Toast discount name.
- Set the restaurant-local start/end times, redemption period, and capacity. New campaigns default to a configurable 15-minute redemption period. Zero capacity means unlimited; finite capacity requires its readiness checks.
- Save a draft. Review the saved offer summary, then use the separate Publish confirmation. Preview checks layout and creates no reservation.
Publication creates an immutable offer version. Active reservations keep their accepted terms, offer, and deadline when the campaign changes. Material edits require Unpublish before publishing a new version. Historical offers without a configured Toast discount name must be corrected and published before new activation; an existing accepted reservation keeps its own version.
A reload may show Unsaved changes found. Resume restores the current operator's campaign draft; Discard removes it. Drafts expire after 24 hours. If another operator saved newer values, reload and review those values before applying your changes. Stale saves and publication cannot overwrite them. Browser-storage failures are visible; restoring a draft never publishes it.
Public QR codes and location selection
Each restaurant has a reusable public assignment link and QR card. Distribute
its code only for that restaurant. Old /coupon/[slug] links no longer resolve
and must be replaced.
An eligible multi-location campaign can also offer a gated location-selector link. The guest chooses a restaurant, then enters that restaurant's assignment flow. Selection records intent, not proof that the guest is physically there. Rotating an entry token invalidates the old QR without erasing an existing accepted session. Retiring an assignment blocks new claims while a valid existing session can finish; emergency revocation cancels active reservations. Re-adding a retired restaurant creates a new assignment and QR when admitted.
Unique one-use links
- Open the campaign's Unique Issuances tab and choose Issue Unique Coupon.
- Select an eligible restaurant, optionally a confirmed existing Contact, and optionally an expiry in that restaurant's timezone. Each action creates one issuance.
- Copy the private URL from its one-time reveal. The raw link is never available from the history list or a repeated creation request.
- If the response is lost, check the original creation attempt instead of creating another. Recovery confirms the issuance ID without revealing its private token again. Closing the dialog does not undo an accepted request.
The private entry exchanges its token for an issuance-bound browser session and
redirects to /coupon/i/[issuanceId]. One issuance permits at most one completed
redemption. Revocation cancels its active holds, releases their reserved capacity,
and blocks future claims. Cancelled or expired holds can retry
only when the server explicitly allows it and the issuance is still valid.
Search by issuance ID or masked recipient, filter by restaurant/status, and use Load more or Refresh. Created and expiry times display the assigned restaurant's timezone on desktop and mobile. Missing or invalid timezone data is unavailable; absent expiry displays Campaign end. History is a live view, not a frozen export.
If browser storage is unavailable, recovery cannot survive a reload. Never put private links, cookies, or staff proof into support tickets or screenshots.
Guest activation and redemption
The guest enters first name, last name, and email; phone is optional. They review and explicitly accept the offer terms. Check offer is advisory and does not hold capacity. The next step is Start Redemption Period when the server is present: activation rechecks the accepted offer, restaurant, identity, dates, and capacity together.
The guest shows the active screen to staff. Staff applies the displayed discount in Toast, then the guest taps Confirm discount applied in front of them. The button is disabled while pending/checking or after the deadline. Wait for the server-confirmed result. Danvas records Guest confirmed (Toast not verified) and consumes campaign capacity. It does not modify the Toast check or verify that the discount was applied.
| State | Meaning |
|---|---|
| Active | A server-confirmed reservation holds capacity until its deadline. |
| Redeemed | The guest confirmed completion; fulfillment evidence is labeled separately. |
| Cancelled | The reservation was cancelled and its held capacity released. |
| Expired | The server deadline passed and held capacity was released. |
Reload resumes the server-owned deadline through an HttpOnly cookie. Changing the device clock cannot extend it. If a reply is lost or status is unavailable, use the existing recovery/status action; do not assume success or start another claim. Cancellation and expiry do not consume completed-redemption capacity. Retry is available only when the current page/server admits it. A completed redemption blocks another claim by that campaign/customer.
After redemption, the guest may leave a 1–5 rating and optional note or skip it. This is separate from the 0–10 NPS survey.
The authenticated /coupons/confirm staff route remains for legacy proof-enabled
reservations. The current guest flow displays no staff proof and requires no
staff scan. A scan on the legacy route only opens review; staff must explicitly
confirm an authorized, unexpired reservation.
Reports and Contacts
Reports distinguish claims, current holds, completed redemptions, cancellations, expirations, and fulfillment evidence. Verified redemptions require complete staff or POS evidence; guest confirmation alone does not qualify. Durable audit evidence remains available when notification transport rows are pruned.
Report dates use each restaurant's 04:00 service-day boundary. Totals follow the selected authorized filters; remaining capacity remains campaign-wide. Use Load more and Refresh; a failed query or invalid timezone displays unavailable rather than zero.
Coupon contact fields are masked for every role. A dedicated authorized repair form changes the association with a reason and an eligible confirmed Contact; it cannot rewrite the accepted offer or guest evidence. Raw personal-data exports require a separate authorized, audited action. See Contacts and guest history for identity and consent.
Toast aggregate comparison is advisory. Shared discount labels are ambiguous, unrelated discounts are separate, and incomplete source windows are unavailable. These totals cannot verify a particular guest's discount.
Help and availability
For a stale save, reload the latest campaign. For an uncertain issuance or activation, recover the original attempt. For unavailable dates/counts, refresh and report the campaign, restaurant, timestamp, and safe outcome category. Never edit counters or change a Contact to work around eligibility.
The Manager Guide, guest support guide, and rollout runbook own detailed troubleshooting and acceptance gates. Release completion is separate from team flags, real-device/privacy checks, and POS pilot acceptance.