Track 3 · Operate

One-Off Purchases

Day passes — Stripe charge + OfficeRnD member + kiosk-compatible pass + branded receipt.

Single-visit day pass. Stripe charge + OfficeRnD member + day pass with kiosk-compatible config + branded receipt.

At a glance

Worker labour-temple-checkout.labourtemple.workers.dev (shared with Track 1)
Deploy cd cloudflare-worker && npx wrangler deploy
Product config PRODUCT_CONFIG in worker.js
Email template MailerSend pr9084zxnvjlw63d
OfficeRnD plan Day Pass — Plan ID 66b399ef3de7dbab92b5c985
Critical setting Day Pass plan's passesValidityPeriod.intervalCount must be ≥ 1 (currently 12 months)
CMS Webflow → Memberships with Purchase Type = "One-Time"

The rule that matters most

If a customer can't check in at the kiosk, check whether the pass exists in OfficeRnD first. The kiosk is a dumb reader of OfficeRnD state. No pass = no kiosk recognition = not a kiosk problem.

The five surfaces

  1. Stripe → Payments, search by email → confirm PaymentIntent succeeded
  2. OfficeRnD → Member → Day Passes tab → active pass with today's date
  3. Worker logswrangler tail --format pretty
  4. MailerSend → Activity for template pr9084zxnvjlw63d
  5. OfficeRnD plan configpassesValidityPeriod.intervalCount non-zero

When to escalate


Incident playbooks

1. Kiosk doesn't recognize the customer — they're standing there, card in hand

Check in order.

  1. Is the pass in OfficeRnD? Search by email → member → Day Passes tab → today's date, status "active".
  2. Pass exists but kiosk rejects. Confirm: - type = "hotdesk" - grantActiveStatus = true - validFrom and validTo are both today (UTC — watch the midnight boundary) - Day Pass plan's passesValidityPeriod.intervalCount is non-zero (should be 12 months)
  3. No pass exists. See playbook #2.

In the moment: let them in manually. You can create a one-off pass in OfficeRnD with the fields above to get them through.

After: check Worker logs for whether POST /passes failed.

2. Payment succeeded but no day pass in OfficeRnD — partial-failure case

This is the documented gap in Track 3. Customer was charged; our job is to make them whole.

Check. Worker logs for this PaymentIntent. Common causes: - Member doesn't exist (member creation failed silently) - OfficeRnD API returned an error (transient, rate limit, config) - passesValidityPeriod.intervalCount = 0 — pass created but zero validity - type not set to "hotdesk" (defaults don't apply)

Fix.

  1. Find member in OfficeRnD. If missing, create with name + email from Stripe PaymentIntent.
  2. Create pass with: type: hotdesk, count: 1, validFrom: today 00:00 UTC, validTo: today 00:00 UTC, intervalLength: once, grantActiveStatus: true.
  3. Confirm active on the Day Passes tab.
  4. Email: "Your day pass is ready — tap your card at the kiosk."

Systemic fix. Recurring misses = Worker needs retry on POST /passes. Flag to Chris.

3. Email says "Hi Guest" or has no name

Known client-side issue: the frontend may not be passing customerName as the 4th arg of _complete().

Customer is fine — they got the pass. Systemic: have Chris verify the 4th arg is passed from the embed's form; fix + redeploy.

4. No confirmation email received

MailerSend Activity → filter by recipient (template pr9084zxnvjlw63d).

  • "Sent" → check spam; forward a manual confirmation with the Stripe receipt URL.
  • "Bounced" / "Failed" → address may be wrong. Correct in OfficeRnD + Stripe; resend.
  • No attempt → check MAILERSEND_API_KEY and MailerSend status.

Email failure doesn't affect payment or pass creation.

5. Duplicate charge

Stripe → Customers → count PaymentIntents in last 24 h for day-pass product.

Fix. Refund the second ("Duplicate"). Delete the duplicate pass in OfficeRnD if one was created.

Prevention. No idempotency key on POST /create-purchase — rapid double-clicks can create two PaymentIntents. Hardening pass in roadmap.md.

6. Refund request for unused day pass

Check. OfficeRnD → Day Passes tab shows check-in history — was the pass used? Within refund window?

Fix. Unused + in-policy → refund in Stripe + deactivate pass in OfficeRnD + email confirmation.

Policy to publish. Typical: full refund if unused + requested before end-of-day; no refund after use. Add to the checkout page copy.

7. "Invalid product" error in the browser

Check. CMS Purchase Type is "One-Time" (not "Subscription"). CMS plan-slug matches a key in PRODUCT_CONFIG exactly. Browser: #purchase element exists; window._S defined; stripe_purchase_v1 applied.

Fix. Correct the CMS field (not the Worker). Republish.

8. Chargeback / dispute

Same as Track 2. Respond via Stripe Dashboard with: PaymentIntent metadata, OfficeRnD pass record (proves delivery), email history, published refund policy.

9. Adding a new one-off product — not an incident, a deploy

Flag to Chris.

  1. Create Product + Price in Stripe (Live).
  2. Add entry to PRODUCT_CONFIG in worker.js.
  3. cd cloudflare-worker && npx wrangler deploy.
  4. Create CMS item: Purchase Type = "One-Time", correct plan-slug, copy, pricing, terms URL.
  5. Publish CMS.
  6. Smoke-test: buy in Live at low price, refund, confirm pass + receipt.