AfterHours Booker is operated by Washboard Labs LLC.

AfterHours Booker

How later pieces plug in

Booking storage stays local. Stripe test checkout is wired for the 7-day trial. Calendar and live Twilio send are still seams.

Stripe test checkout
7-day Starter trial. Live mode is rejected.

Set `STRIPE_SECRET_KEY` to an `sk_test_` key. Checkout creates a subscription with `trial_period_days` 7 and `payment_method_collection` always, so a card is on file. Unless the shop cancels, Stripe converts it to the locked $29/month Starter price, or to $290/year when the shop chose annual. Each business email has its own trial window and booking count. Checkout, the card statement (`WASHBOARD LABS LLC`), and the invoice footer identify Washboard Labs LLC. The operator line also stays in the header, footer, and Terms.

One trial per business email or phone (contact identity only — not a live after-hours line). Intake stops at 25 bookings with an upgrade link. Optional `STRIPE_PRICE_ID` must be that same $29/month test price. `STRIPE_WEBHOOK_SECRET` verifies `POST /api/stripe/webhook`.

Google Calendar
Replace the stub slot writer, keep the same request id.

After OAuth for the business calendar, map `PendingSlot.windowStart` / `windowEnd` to an event with status `tentative` and extended property `afterhoursBookingId`.

Confirm in the inbox should PATCH the event to `confirmed`. Decline should cancel it. Use a Google service account or Calendar API user tokens stored per location — not in this repo.

Cal.com
Use Cal.com as the availability source, AfterHours as intake.

Call the Cal.com booking API with the captured attendee and a slot from their availability endpoint. Store `calBookingId` next to `slotId`. Incoming Cal.com webhooks can flip inbox status if a customer later reschedules on Cal.

Twilio
Parked for several weeks. Routes exist for later; this build does not answer live calls.

Buy a number, set Voice URL to `https://afterhoursbooker.com/api/twilio/voice` and Messaging URL to `/api/twilio/sms`. Verify `X-Twilio-Signature` with `TWILIO_AUTH_TOKEN` before calling `ingestTwilioEvent`. Gather speech or keypad input, then return the existing TwiML helper.

Text / email send
Stubs already store the copy.
Swap `queueConfirmationStubs` for Twilio Messaging or Resend. Keep the queued / sent / skipped fields on the booking so the inbox still shows delivery state.