Availability correctness
Calendar pooling, buffers, resources, class capacity, global limits, and race conditions at the final booking request.
Owned scheduling + commerce · 13 August 2026
Yes, but “all of Acuity” is a scheduling, payments, commerce, ledger, communications, and operations programme. There is no single open-source fork that gives us the whole thing.
Build the owned product on the existing Nowhere stack if long-term control is the goal. For a prototype, inspect Easy!Appointments for scheduler ideas, Cal.com for modern scheduling/API patterns, LibreBooking for resources, and Saleor/Medusa or ERPNext for commerce. Do not assume any of them removes the work of building credit packs, appointment capacity, cancellation/refund semantics, and a safe payment/booking ledger.
Yes. We can own the guest experience while Acuity remains the scheduling engine. Its public API exposes appointment types, dates, times, classes, forms, certificates, add-ons, appointment creation, rescheduling, cancellation, and webhooks. That is enough to build a branded flow around the bathhouse journey instead of presenting a generic scheduler.
| Surface | Our opportunity | Difficulty |
|---|---|---|
| Service discovery | Explain the experience, inclusions, restrictions, and best choice before showing times. | Low |
| Availability | Show clearer alternatives and a “choose experience, then time” flow while querying Acuity live. | Medium |
| Cart | Support several compatible sessions, products, add-ons, or pass redemptions in one branded flow. | Medium-high |
| Forms | Use progressive disclosure, better copy, conditional questions, and saved guest details. | Medium |
| Checkout | Use Stripe for a clearer total, package balance, receipt, and product upsell experience. | Medium |
| Confirmation | Combine booking, payment, balance, directions, and next steps into one useful confirmation. | Medium |
The clean architecture is to separate financial truth from scheduling truth. Stripe owns charges and refunds; Nowhere owns the order, payment ledger, entitlement balance, and reconciliation state; Acuity owns appointment availability and the operational calendar.
| System | Source of truth |
|---|---|
| Stripe | Payment intents or Checkout Sessions, charges, refunds, disputes, and processor webhooks. |
| Nowhere D1 | Order, payment transaction, refund, booking intent, package/credit ledger, and dashboard payment status. |
| Acuity | Availability, calendar/resource assignment, appointment record, forms, reminders, and schedule operations. |
Acuity’s public API documents reading appointment payments, but not creating a payment or marking an external Stripe transaction as paid. Its documented appointment update fields include client details, forms, certificates, notes, and labels. Acuity also says invoice payments do not update the appointment record. We can add an “Externally paid” label or payment reference to the appointment, but the native Acuity paid icon is not a supported public integration contract.
HitPay is a plausible second rail for WhatsApp and staff-assisted bookings. Its API can create a payment request with an amount, currency, allowed methods, expiry, customer details, an internal reference, metadata, and a checkout URL. HitPay documents redirect checkout, drop-in UI, payment links, QR methods, cards, and local payment methods that vary by merchant country.
| Channel | Recommended rail | Reason |
|---|---|---|
| Main booking widget | Stripe | Best fit for an embedded branded checkout and tightly controlled guest journey. |
| WhatsApp booking | HitPay | Generate a one-off payment request and send the link in the conversation; local methods may improve cost or completion. |
| Staff-assisted booking | Either | Choose based on customer preference, payment method, and current fee economics. |
| Products and packages | Either | Use one provider-neutral local order and entitlement ledger. |
The backend should expose one payment interface with Stripe and HitPay adapters. Store the provider, provider payment/request ID, booking intent ID, order ID, currency, amount, status, and refund state. HitPay says to confirm payment from its signed webhook rather than the redirect, and its newer dashboard webhook system supports payment_request.completed. The per-request webhook field is documented as deprecated.
For multi-appointment carts, use an idempotent finalization worker with compensation logic. Acuity does not document a general-purpose multi-item hold, so the first release should keep carts simple or accept explicit partial-success/refund handling.
Calendar pooling, buffers, resources, class capacity, global limits, and race conditions at the final booking request.
Payment can succeed after a slot disappears, or booking can succeed before payment. Both cases need idempotency and compensation.
Certificates and packages change payment status, balances, expiry, cancellation returns, and who owns versus redeems the credit.
Recurring series, rescheduling, no-shows, reminders, calendar sync, webhook retries, audit history, and staff exceptions.
| Area | Parity we would need to own |
|---|---|
| Services | Appointment types, categories, duration, price, add-ons, padding, locations, and direct booking links. |
| Availability | Calendars, calendar pooling, availability groups, start intervals, advance notice, blocks, daily limits, look-busy and gap rules. |
| Capacity | One-to-one appointments, overlap rules, classes, seats, class series, rooms/resources, and waitlists. |
| Booking flow | Date/time selection, add another time, recurring bookings, quantity/multiple spots, timezones, client accounts, and confirmation. |
| Client data | Profiles, history, forms, agreements, file uploads, internal forms, notes, and labels. |
| Commerce | Full payment, deposits, saved card details, later charges, payment links, invoices, cash, tips, refunds, receipts, and payment status. |
| Products | Packages, gift certificates, subscriptions, booking codes, redemption, balance allocation, and expiry. |
| Growth and operations | Coupons, add-ons, reminders, email/SMS templates, calendar sync, webhooks, reports, exports, permissions, and mobile admin. |
A serious replacement needs explicit state for orders, payment intents, transactions, refunds, appointments, and entitlements. It must handle payment success followed by booking failure, booking success followed by payment failure, retries, disputes, and webhook reconciliation without double-charging or double-booking.
Authorize or collect full payment/deposit, handle processor webhooks, refunds, failed payments, saved methods, receipts, and reconciliation. Never store raw card data.
Product → order → certificate/code → immutable balance ledger → redemption tied to an appointment. Cancellations and manual adjustments become auditable events.
Guests should be able to buy a credit pack without a time, book with a code, pay for a single appointment, or buy a gift for someone else.
A browser retry, processor retry, or webhook retry must not create a second appointment or second charge. Partial success needs a documented compensation policy.
GPLv3, self-hosted PHP/MySQL. Services, providers, working plans, booking rules, Google/CalDAV sync, group sessions, REST API, and webhooks. Official marketing mentions payments, but public docs do not establish an Acuity-style product/package/certificate/subscription layer.
Verdict: useful scheduler reference or prototype fork; not a complete fit for Nowhere.
Modern React/Next.js-oriented scheduling with event types, custom fields, seats, recurring bookings, limits, buffers, APIs, webhooks, and Stripe payments. The repository documents AGPLv3 core plus commercial enterprise areas.
Verdict: best scheduling/API reference; weak for products, packages, certificates, and a credit ledger.
GPLv3 resource scheduling with multi-resource booking, waitlists, quotas/credits, reporting, and Stripe/PayPal gateways. PHP/MySQL and oriented around reservations rather than customer commerce.
Verdict: strongest resource-capacity reference; not an Acuity commerce fork.
GPLv3 ERP with products, orders, invoices, payment requests, pricing rules, subscriptions, accounting, and commerce. Its appointment feature is a basic lead/employee meeting flow.
Verdict: strong commerce/accounting base; custom scheduling app required.
Saleor provides API-first products, checkout, promotions, gift cards, customers, orders, and payments. Medusa provides MIT commerce modules for carts, payments, products, promotions, bundles, and subscriptions.
Verdict: useful commerce components; neither supplies appointment capacity or booking rules.
The open-source ecosystem is fragmented by domain. A mature scheduler, a mature commerce engine, and a custom entitlement ledger still need to be integrated and operated together.
Verdict: choose a base for the hardest domain, not by star count.
| Requirement | Easy | Cal | Libre | ERPNext | Saleor/Medusa | Nowhere |
|---|---|---|---|---|---|---|
| Appointment types/schedules | Strong | Strong | Partial | Partial | None | Build |
| Calendars/providers | Strong | Strong | Strong | Partial | None | Build |
| Classes/seats/recurrence | Partial | Partial | Partial | Weak | None | Build |
| Shared resources | Unclear | Partial | Strong | Partial | None | Build |
| Payments at booking | Unclear | Stripe | Stripe/PayPal | Gateway | Strong | Provider |
| Products/cart | Weak | None | Weak | Strong | Strong | Build/module |
| Packages/credits/certificates | None documented | None documented | Credits | Custom | Gift cards | Domain fit |
| Fit with Next/Cloudflare/D1 | Poor | Better | Poor | Poor | Separate service | Best |
| License simplicity | GPLv3 | AGPL + EE | GPLv3 | GPLv3 | MIT/BSD options | Own code |
Build the owned product on the current Next.js + Cloudflare Workers + D1 foundation if we decide that booking rules, customer experience, product economics, and data ownership are strategic. Do not replace the whole system in one pass.