# Coffee Club simple MVP specification

Revision 4 · Final MVP build specification · 18 October 2026 · Working name Daily

## Product decision

One customer card, two products, a focused staff counter, and a small owner dashboard. Launch with recurring loyalty stamps and prepaid ten-coffee packs. Monthly subscriptions, breakfast bundles, provider switching, campaign builders and elaborate reporting are deferred.

The user has agreed the product direction. This is the final specification handoff before execution; it incorporates both full-price payment routes, Apple sign-in and the Stripe Connect model. This supersedes earlier specifications and the broader first product preview. Implementation update: the current build uses a persistent D1 backend and real QR generation/scanning code. Review purchases are explicitly simulated. Stripe Connect and hosted customer auth handlers are implemented but require external runtime credentials and connected acceptance; no live-money service is enabled.

## Customer experience

Two navigation items only: My card and Buy. Buy contains the ten-coffee pack and a compact Pay for today option; it is not a food-ordering catalogue.

The shop's printed QR opens its customer website. A new visitor can join the free loyalty card or choose the ten-coffee pack. The live purchase journey is offer → hosted payment → verified payment → personal card. Email supports receipt and card recovery; marketing permission is separate and optional. No compulsory app install or password creation before payment.

One personal QR identifies the member in that café. The same card displays loyalty progress, earned rewards and prepaid coffee balance as distinct values. A prepaid coffee is already paid, not free. A loyalty reward is earned through qualifying purchases.

On return, scanning the same shop QR can open My card if the browser has a valid customer session. The public QR identifies the shop, not the person. If the customer changes phone/browser, clears storage or loses the session, they recover access through email. Optional wallet storage is a later convenience. Review data is now stored server-side. Production email/social recovery handlers require provider configuration; wallet pass issuance remains deferred.

The live personal QR contains an opaque member/redemption reference, not an email, password or balance. Viewing it does not debit credit. Staff authorization and server checks are required for every operation. A screenshot is not proof of current balance or identity; the first pilot must define whether named cards can be shared.

## Two products and one clear rule

| Product | Customer payment | Staff action | Balance effect |
|---|---|---|---|
| Loyalty | Pay full price on mobile, or use the existing café till | Mobile payment awards once; external till purchase uses a manual paid confirmation | Ten full-price eligible coffees earn one reward; next cycle starts again |
| Ten-coffee pack | Pay online through our checkout | Redeem prepaid coffee | Deduct one from prepaid balance |
| Earned loyalty reward | No payment for the included reward | Redeem reward | Deduct one available reward |

Ten stamps earn one reward: the eleventh eligible coffee is free. This is the agreed launch rule. Pack purchase, prepaid redemption and free-reward redemption earn no stamps. This avoids double-discounting. The customer card and staff guide must state it plainly.

Loyalty participation is free to the customer. The proposed platform fee applies to qualifying online sales through our service, not unrelated till revenue; the percentage remains to be agreed. Loyalty can be included with the pack service to build engagement and feed pack conversion. If a merchant wants loyalty alone, its commercial price needs a separate decision; do not assume external till purchases can be automatically commissioned.

## Exactly what staff do

The café keeps a phone or tablet at the counter. A manager signs in and opens Counter; access remains signed in under the selected session/device policy. Staff do not log in for each drink.

1. Customer shows the personal QR.
2. Staff taps Scan inside our counter webpage and points its camera at the code. Camera permission may be required.
3. The screen identifies the member and shows prepaid, reward, paid-order fulfillment and manual till-stamp actions as applicable. Select quantity; ineligible actions are disabled.
4. Staff confirms the appropriate action. Manual stamps require confirming an external till payment; mobile-paid orders are already stamped and must not be stamped again.
5. The server records the operation atomically and returns the new balance. Staff see success; the customer's card refreshes from the same data.

The web camera scanner is a simpler first route than relying on the phone's general camera to navigate on every sale. A code-entry fallback handles camera failure. Owner and staff operate on the same service; they do not need to send records to each other. The current implementation reads and writes a shared backend; customer cards refresh periodically while visible. Physical two-device camera validation remains a launch gate.

A retry after a network problem reuses the same request identifier and cannot spend a second credit. Another drink requires a new explicit action. No offline spending in v1. If the café honours an exception during an outage, record and reconcile it rather than silently fabricating a successful debit. Managers can reverse a mistake with an audit event; staff cannot erase history.

For manually awarded stamps, the system records a staff assertion, not verified external payment. A till receipt/reference can prevent repeat processing where feasible. Automatically generating a fresh reference for every tap only prevents network retries; it does not prove staff did not award twice for the same physical sale. Staff training and a visible history are necessary until a suitable POS integration exists.

## Owner backend

Three navigation items: Overview, Customers and Settings. A prominent Open counter action is available without making Counter a fourth permanent owner tab.

Overview shows the selected period, registered members, new members, online pack sales, online full-price coffee sales, prepaid redemptions, loyalty rewards and outstanding prepaid obligations. Headline: “€X sold through our programme this week.” Show pack and full-price sales separately beneath it; external till stamps are activity, not verified online revenue. This is attributable programme sales, not proven extra sales or profit. Show gross receipts and drill down to fees/refunds; do not call gross sales net money earned.

Customers is a small CRM: member name/identifier, loyalty progress, prepaid balance, last activity and marketing permission. Owner-only access; staff scanner does not expose an email list. Record customers even when they decline marketing, but do not count them as subscribers.

Settings holds café branding, one pack offer, loyalty terms, payment readiness, staff access and a printable counter kit. Do not make every setting a navigation tab. Production launch needs server-enforced roles; demo view switching is not authentication.

## Payments and existing tills

Stripe does not automatically connect Square, SumUp or a bank card terminal. Their payment histories and events require separate authorized integrations. Even a payment feed needs reliable matching to a club member and eligible products; amount and time alone are insufficient.

Revised payment scope (supersedes the earlier till-only recommendation):

- Individual full-price coffee: customer selects eligible coffee quantity and pays on mobile; a verified successful payment awards that quantity of stamps exactly once. Staff checks and marks the paid order served without awarding again. Existing terminal/cash purchases remain supported by a clearly marked manual stamp action; these are outside our commission base.
- Ten pack: customer pays online through our branded flow with hosted Stripe Checkout; our server issues ten credits after verified payment.
- Redemption: no further payment; authenticated staff deduct a prepaid credit or reward.
- Reconciliation: payment, fee, refund and consumption records share one order/member ledger. Provider-specific till integration is a separate workstream; a payment feed alone cannot establish which member bought eligible coffees.

The live platform design remains café-as-seller with Stripe Connect, direct charges and platform application fee. Each merchant completes payment-provider verification. The current test checkout is directly on the authorized Huerto Secreto test account, not a connected café: it does not prove Connect onboarding, commission splitting or settlement.

Read-only inspection returned no connected accounts. An empty list does not establish whether Connect is enabled or what capabilities are available. No live mode operations or changes to existing account branding/settings were performed.

## Commercial scope

Illustrative 5% fee on VAT-inclusive eligible online receipts, proportionately reversed for refunds, with processing separate and applicable VAT on our services disclosed. Final terms need review. At €27 a pack, 100 sales/month produce €2,700 programme sales and €135 platform revenue before our costs. Higher platform revenue needs more useful sales, additional merchants, or a later optional growth service.

Loyalty is a retention and pack-conversion tool initially. Do not charge a percentage of assumed or manually stamped till revenue. We can later test an optional managed email/growth service, but it is not a launch navigation item or first-build dependency.

Market emails require the chosen café-specific permission policy, withdrawal records and suppression checks. Transactional receipt/recovery messages remain separate. Marketing consent is not a condition of buying or joining the card.

## Build and inspect rather than copy

Borrow established interaction patterns: loyalty member QR plus staff-confirmed stamps; prepaid units plus explicit redemption; guest checkout and recoverable card. Implement our own rules and ledger. Public docs are evidence of advertised behavior, not proof that we have tested vendor apps.

REA and Hopper may be installed on the user's Mac. This chat has no connected session exposing them; this is an access limitation, not an assertion that they need installing. The exact original café/app remains unidentified. Inspect the existing customer flow when the target and tool access are available. Native disassembly is not required for this scope and cannot reconstruct a private server ledger. Use appropriate authorized targets and respect vendor terms; do not copy proprietary implementation or assets.

## Two full-price payment routes — final decision

Customers can earn loyalty stamps whether we process their full-price coffee payment or the café takes it directly. When both routes are enabled, show two choices within Pay for today: “Pay on my phone” and “Pay at the counter”. No extra navigation tab is needed. Neither route turns a prepaid redemption into a stamp-earning purchase.

| Route | Customer journey | Staff journey | Payment and stamp result |
|---|---|---|---|
| Pay on my phone | Scan shop QR, choose eligible quantity, pay through our checkout, show the paid order/card | Scan card, verify paid order, confirm served | Verified Stripe payment awards the qualifying quantity once; platform fee collected automatically |
| Pay at the counter | Pay the café using its terminal or cash, then open/show the loyalty card for stamps | Take payment as usual, scan card, select eligible quantity, confirm payment received and award stamps | Café retains the payment; authenticated staff assertion awards stamps; no platform payment or commission |

The extra customer action for café-handled payments is presenting the loyalty card after paying. New members scan the shop QR and join first; returning members reopen their card. Do not require a receipt upload, customer-entered payment amount or a second payment. A customer's “I have paid” tap is never sufficient to award stamps. Staff performs the paid confirmation, not the customer.

For mobile payments, staff views the verified paid order directly within the scan result; customer screenshots do not prove payment. For counter payments, show “Paid at café — add N stamps” and a clear quantity before confirmation. Keep the two staff actions distinct so that an online order is not stamped twice. Store payment source, café, member, quantity, staff actor, operation ID and timestamp. Where a till receipt ID exists, deduplicate it within the café. Without that reference, manual stamping remains a trusted staff operation with history and an audited correction path, not automatic POS verification.

Stamp reversals follow the original qualifying sale on refunds/corrections. If an earned reward is already consumed, retain the resulting loyalty adjustment against future earnings rather than silently granting the same reward again. Pack refunds apply only to eligible unused entitlement under the café’s published terms; refund processing and consumption must not race. The exact refund policy and eligible drinks/supplements must be visible before purchase and configured before a live pilot.

## Launch scope and product limits

| Included in MVP | Deferred or separate |
|---|---|
| Ten-pack purchase, full-price mobile payment, counter-paid loyalty | Monthly subscriptions and mixed tender baskets |
| Ten paid eligible coffees earn a reward; explicit quantity redemption | Full food ordering, kitchen tickets and inventory |
| Google, Apple and email sign-in/recovery; guest purchase path | Native customer app and optional wallet pass distribution |
| Stripe Connect application fee, payment ledger and refund handling | Native Square/SumUp processing until their individual integration gates pass |
| Three owner tabs, staff counter, small CRM, optional marketing consent | Campaign builder and automated marketing sends |

Pack and reward entitlements are café-specific and non-transferable in v1. A short-lived opaque personal QR is generated from the authenticated card; staff scanning checks current server state and never treats possession of a screenshot as a balance guarantee. Allow a short-lived code-entry fallback. Expired codes refresh on My card. Staff access uses named, revocable accounts/device sessions; owners can revoke a lost device. Staff cannot export the CRM or alter fees/pricing. Define eligible drinks and any supplements in the offer, with no hidden charge at redemption.

## Checkout, identity and consumption contract

First visit: scan shop QR → choose pack or Pay for today → Apple Pay, Google Pay or card where available → payment verification → personal card and receipt. Wallet availability depends on provider, device and configuration; bank authentication can add a step. Never promise universal one-tap payment.

Customers can continue without creating a password. Offer Continue with Google, Continue with Apple and email magic-link recovery in the MVP. Josh confirms he already has an Apple Developer account; use that account for the required web sign-in configuration during execution. Account ownership is confirmed, but connected access, identifiers, redirect configuration and secure credentials still need to be established. Do not ask him to create another developer account. Google Pay and Google sign-in are different capabilities. Do not force social login before checkout. Obtain receipt/recovery email once and reuse verified profile details where permitted. A checkout email alone is not proof of identity for access to an existing customer's card; linking existing identities requires verified authentication. Guest purchase access uses a secure purchase-bound session, with verified email recovery for another device. Marketing permission stays optional and separate.

On return, the shop QR opens My card when the browser session is valid. Otherwise show the short sign-in/recovery screen, then the same card. No public shop QR can identify a person by itself.

Payment and consumption are separate events. Buying a ten pack adds ten credits only after server-side payment verification. It does not consume the first coffee. Staff scans the customer's actual QR in the counter webpage, chooses quantity (default one), sees “Use 2 coffees · 10 → 8”, and confirms once. Customer and staff read the same server balance; neither edits a separate local balance. Return a visible success on both devices and retain an event receipt. No second payment or stamps arise from prepaid consumption. Redeeming a reward also earns no stamps.

Full-price mobile purchases award one stamp per qualifying coffee, not per euro or per checkout. A purchase of two earns two stamps. The tenth stamp creates one reward and progress rolls into the next cycle. The reward is used in a separate explicit redemption, not retroactively against the purchase that earned it. Staff sees an unserved paid order and confirms the quantity handed over. Serving cannot duplicate stamps or charge again. The same sale cannot be manually stamped later. Mixed prepaid/reward/paid baskets are deferred: one clear operation at a time.

The server owns pricing, eligibility, quantities and fee calculation. Positive whole-number quantity is required. Redemption must check café, staff role, available balance and active card in one atomic transaction. Network retries reuse the operation ID; two simultaneous devices cannot overspend. Show pending/failed states truthfully and disable repeated confirmation while pending. Refresh/reconnect reads canonical state. No offline debit in v1. Managers can correct a mistake through an audited reversal, never by deleting history.

## Provider strategy and automatic commission

The café remains the seller. Our fee is taken within each eligible online payment; there is no separate collection task for the owner. Bank payout timing remains the provider's schedule. Processing fees, refunds and disputes are separate from our commission and must appear in reconciliation.

| Provider | Verified capability | Build decision |
|---|---|---|
| Stripe Connect | Direct charges can pay the connected café and collect an application fee | Agreed MVP online payment model; first end-to-end implementation uses the authorised test environment, including merchant onboarding and fee/refund tests |
| Square | OAuth and Payments API application fees are documented; developer and seller country/currency requirements apply | Build a Square adapter and test merchant connection/payment/fee/refund with authorised sandbox credentials; Spanish account readiness is a launch dependency |
| SumUp | OAuth merchant authorization and online checkout exist; affiliate docs mention agreed partner revenue share | Investigate the exact online commission settlement route and partner requirements before promising automatic split payments; not yet verified equivalent to Stripe/Square |

Existing Square or SumUp credentials do not automatically become a Stripe merchant connection. The first complete MVP uses Stripe Connect for online payments; our interface hides provider mechanics after setup. Square and SumUp remain separate integration workstreams and are not required for a café to keep accepting payments on its existing terminal. A SumUp café can retain its terminal and optionally onboard Stripe for online passes, but this is an explicit choice, not an automatic SumUp integration. Do not silently substitute a later commission invoice for the agreed automatic collection model.

Owner setup target: sign in → café name/offer → connect Stripe → readiness check → download shop QR. Settings also lets the owner enable mobile full-price payments, pay-at-counter loyalty, or both. Prepaid packs remain online purchases through Stripe Connect in the MVP. Returning verified merchants may complete it quickly; provider verification or missing capabilities can add steps. Only show Ready when payment collection and the intended fee route are available. Keep reconnect and incomplete-verification instructions in Settings.

Commercial definition: charge the agreed percentage on qualifying sales processed through our service, with fee reversals on refunds. The earlier 5% is an illustrative proposal, not final approval. Do not charge unrelated terminal/cash revenue. Payment records demonstrate programme sales, not incremental sales that would otherwise never have happened. Keep the owner headline “€X sold through our programme this week”; estimate incremental lift separately using pilot baselines. If the commercial promise must literally be incremental-only, agree an attribution method before launch.

## Execution handoff — product scope agreed

This deliverable finalizes the specification as requested. Execution follows this handoff. The current build applies the ten-stamp rule and quantity-based staff actions. Implementation evidence and remaining provider/device gates are recorded in ACCEPTANCE.md. Real-money launch remains outside the test-build scope.

1. Establish the deployment and secure runtime prerequisites: durable database, server secrets, webhook endpoints, customer authentication and transactional email. Confirm whether the chosen public customer hosting supports the required auth independently of ChatGPT. Keep the existing review site private.
2. Use parallel product/backend, payments and verification workstreams with a single integration owner. Implement two customer tabs; three owner tabs (Overview, Customers, Settings); a dedicated staff Counter with quantity selection, actual scanning and code-entry fallback. Apply the ten-stamp rule everywhere. Implement Google and Apple sign-in plus email recovery, configuring Josh’s existing Apple Developer account when access is available. Include both full-price payment routes described below.
3. Complete the Stripe test vertical slice: merchant onboarding → mobile payment → automatic application fee → signed payment event → exactly-once pack/stamp issue → staff consumption → updated customer card → owner reconciliation. Test full-price coffee and pack sales as separate order types. Do not activate real payments.
4. Implement Square against authorised sandbox access and the same ledger contract. Research/validate SumUp's online split route in parallel; record a supported implementation or explicit unresolved dependency. Do not label either provider ready from an OAuth mock alone.
5. Produce the pilot kit: shop QR, staff instructions in Spanish/Catalan, a short pack pitch, manager correction/refund flow, and simple CRM with separate marketing permission. No marketing sends in this phase.
6. Deliver a reviewed test build, evidence of acceptance checks, and a clear list of external dependencies before proposing a real-café pilot.

Acceptance gates: a successful ten-pack payment grants ten credits once; failed/pending payment grants none; replayed events grant nothing extra; consuming two leaves eight on both devices; ten full-price coffees create one reward; prepaid/reward events add zero stamps; repeated staff confirmation does not repeat fulfillment; simultaneous redemptions cannot overspend; roles isolate cafés; new-device recovery restores the right card; refunds adjust remaining entitlement and platform fees consistently; owner totals reconcile with provider records. Also verify counter-paid purchases award the selected stamp quantity without creating a Stripe charge or platform fee; customer self-confirmation cannot award stamps; receipt/event retries cannot duplicate stamps; Google, Apple and email recovery link only verified identities, including Apple private-relay emails. Test device camera permission failure, expired sessions, disconnected network, delayed webhooks and wallet fallback. Aim for no more than scan, quantity and confirm for a returning customer's redemption, with quantity defaulting to one.

Completion means these flows run against a durable test backend on two devices, not merely that interface buttons animate. Secure credentials, social-auth developer setup, merchant verification and provider partner approvals cannot be generated by writing frontend code. ChatGPT's Stripe connection does not supply a deployed server credential or webhook signing secret.

## Current verification boundaries

The current API and interface are integrated with durable storage. Local tests exercise actual SQLite migrations and API handlers, including replay, roles, production membership, signed webhook fulfillment and the customer/staff/owner interface flow. Provider responses are controlled in tests; actual OAuth, email delivery, connected merchant payments and physical camera/device operation still need connected acceptance. Review payments are simulated and labeled. See ACCEPTANCE.md and LAUNCH_HANDOFF.md for evidence and the single setup batch. Native Square/SumUp processing, subscriptions, partial refunds and automated dispute reconciliation are outside this build. Pack refunds are conservative whole-unused-pack refunds; unserved full-price coffee orders support whole-order refunds. Ambiguous provider refunds keep entitlement reserved pending an idempotent retry/reconciliation.

## Sources

- Loopy customer and staff demo: https://docs.loopyloyalty.com/en/articles/2600810-try-stamping-a-digital-loyalty-card
- Loyapp prepaid packs: https://loyapp.es/funcionalidades-aumentar-ventas-recurrentes/bonos-digitales/
- Stripe checkout lifecycle: https://docs.stripe.com/payments/checkout/how-checkout-works
- Stripe Connect: https://docs.stripe.com/connect/integration-recommendations
- Square payment events: https://developer.squareup.com/docs/payments-api/webhooks
- SumUp transaction access: https://developer.sumup.com/api/transactions
- Spain marketing communications: https://www.boe.es/eli/es/l/2002/07/11/34/con

## Additional provider sources checked for revision 3

- Square application fees and country/currency restrictions: https://developer.squareup.com/docs/payments-api/take-payments-and-collect-fees
- SumUp OAuth: https://developer.sumup.com/tools/authorization/oauth
- SumUp affiliate keys and agreed partner terms: https://developer.sumup.com/tools/authorization/affiliate-keys
- Stripe direct charges and application fees: https://docs.stripe.com/connect/direct-charges
