Payments
Saved Payment Methods (Card on File)
Last updated 19 May 2026
Saved Payment Methods (Card on File)
Customers save a card during deposit checkout or via a self-manage link. The card persists on the customer profile so you can run walk-out checkout, late cancellation fees, and no-show fees — all with consent enforced server-side.
Where to find it — Web: Customer profile → card-on-file badge near the contact info. Booking detail: card status surfaces near cancellation/no-show fee banners. Mobile: same surfaces.
TL;DR
- Customer saves a card via deposit checkout, self-manage link, or staff-assisted.
- OpenChair stores brand + last 4 + expiry + consent record; Stripe stores the actual card.
- Operator can charge against the saved card for walk-out checkout, late cancellation fees, no-show fees.
- Owner-only removal (security).
- Available on every plan with Stripe Connect active.
How a customer saves a card
During deposit checkout
When a customer pays a deposit at storefront booking, the payment intent is created with a parallel SetupIntent so Stripe can persist the card on your Connect account. The customer doesn't see a separate "save card" step — Stripe handles it inline. If they have Stripe Link enabled, the experience is one-tap on future Stripe-powered checkouts.
Via the self-manage portal
Every booking confirmation email includes a manage your booking link. The customer can:
- Click the link
- Navigate to the Manage payment panel
- Add or update their card via Stripe's embedded payment form
The link is signed and scoped per-booking — they don't need a login. Useful when you need a customer to update their card after a payment fails.
Staff-assisted
From the customer profile, you can:
- Tap Send card-update link — emails the customer a fresh signed link to add/update their card
- The customer completes via their email; no further operator action needed
- The card-on-file badge updates automatically once the customer completes
Useful when a customer's card needs updating and you don't have them in person.
What OpenChair stores
| Field | What it is |
|---|---|
| Card brand | Visa, Mastercard, Amex, etc. |
| Last 4 digits | For display only |
| Expiry month/year | For UI display and expiry checks |
| Consent status | consented / revoked / not_consented |
| Consent timestamp | When the customer agreed |
| Consent source | booking_flow / manage_portal / in_venue / staff_assisted |
| Consent version | The terms version they agreed to |
| Last used at | When you last charged against this card |
Full card numbers and CVVs are stored by Stripe, never by OpenChair. When you charge, the request goes to Stripe with our reference token; Stripe handles the actual card data.
Card status
| Status | What it means |
|---|---|
| Active | Card is on file, consented, ready to use |
| Needs update | Card is on file but expired or payment-method validation failed; customer should update |
| Removed | Card has been detached |
| Disputed | A charge against this card was disputed; charging is paused pending resolution |
What you can do with a saved card
| Action | Where it surfaces | Doc |
|---|---|---|
| Walk-out checkout (one-tap charge after appointment) | Checkout view when booking is ready | Walk-Out Checkout |
| Late cancellation fee | Booking detail banner when status = cancelled | Cancellation & No-Show Fees |
| No-show fee | Booking detail banner when status = no_show | Cancellation & No-Show Fees |
All three require:
- Card on file with status Active
- Consent status Consented
- Card not expired (month/year vs current)
- Customer's email or phone matches the booking
Server-side checks all four before the charge fires. Missing any one returns a friendly error message ("Customer card is not active", "Customer has not consented to card-on-file charges", "Card has expired", "No card on file").
Customer consent
Consent is captured per-card per-customer when they add the card. The customer explicitly agrees to off-session charging at one of:
| Source | Where they agreed |
|---|---|
booking_flow |
Storefront checkout (deposit step) |
manage_portal |
Self-manage link they clicked from an email |
in_venue |
Staff-assisted in-person enrolment |
staff_assisted |
Staff sent them a link they completed on their own device |
Consent versioning means if you change your terms, future charges check the latest version. Customers with older consent need to re-consent (rare, only when terms change materially).
Removing a card
Two paths:
Customer-initiated
The customer visits their manage link and taps Remove card. The card is detached from Stripe and OpenChair clears the denormalised fields on their profile. Card-on-file status flips to Removed.
Operator-initiated (owner only)
From the customer profile, the owner can tap Remove card on file. Confirmation dialog. Same effect as customer removal.
Why owner-only: a compromised staff account shouldn't be able to remove cards on file — that's the rail for no-show fee recovery. Security posture SEC-027.
Sending a card-update link
If a customer's card is expired or needs replacing:
- Open the customer profile
- Tap Send card-update link
- Customer receives an email with a signed link to their most recent booking's manage page
- They tap Manage payment and add/update their card
- Card-on-file status updates automatically
No reply needed from the customer; the system detects the update via Stripe webhook.
Tier
All plans. Requires Stripe Connect active on your venue.
Mobile parity
Mobile booking detail shows the card-on-file badge and supports the cancellation/no-show fee charging flow. Customer profile shows the card-on-file status. Removing a card and sending an update link is web-only (owner-only actions).
Charging mechanics
When you trigger a charge against the saved card, OpenChair calls Stripe with:
off_session: true(the customer isn't actively present)confirm: true(charge immediately, don't wait for authorisation)- The venue's Stripe Connect account
- An idempotency key so retries don't double-charge
- An application fee for OpenChair's platform fee
Failures (declined, insufficient funds, network) are logged with full audit context in paymentChargeAudit so you can trace what happened.
Common mistakes
| Problem | What to check |
|---|---|
| Card on file says "Needs update" | Card expired or Stripe webhook flagged a validation failure. Send the customer a card-update link. |
| "Customer has not consented" error | Consent record is missing or revoked. Customer needs to re-add the card via the manage portal. |
| Can't see Remove Card button | Only owners can remove. Manager and stylist accounts see status but can't detach. |
| Customer says they saved a card but it's not showing | Confirm the customer's email matches the booking they used. The card-on-file lookup uses the venue customer record; mismatched email creates two records. |
| Want to migrate cards from another system | Card data can't be migrated by us — Stripe doesn't accept raw card data from third parties. Customers need to re-enter. |
FAQ
How does a customer save a card on file?
Three paths: during deposit checkout (often via Stripe Link one-tap), via their booking manage link (a 'Manage payment' panel where they add or update a card), or staff-assisted (you trigger the saved-card flow from the customer profile and they complete on their device).
What does 'card on file' let me do?
Charge against the saved card for walk-out checkout (one-tap charge after the appointment), late cancellation fees, and no-show fees. All charges require the customer to have explicitly consented to off-session card use.
Why can't I see the customer's full card number?
Card details (full number, CVV) are stored by Stripe, not by OpenChair. We only see and display brand + last 4 + expiry. The customer can update or remove their card any time via their self-manage link.
Who can remove a saved card?
Only the venue owner — manager and stylist accounts can see the card-on-file status but can't detach. This is a security measure (SEC-027) so a compromised staff account can't disable the no-show fee revenue stream.
Does saving a card cost the customer anything?
No. Saving a card has no fee. They only pay when you actually charge — for the appointment, the deposit, or a no-show/cancellation fee.
What if the customer disputes a charge?
The card-on-file status flips to Disputed and further charging is paused until you resolve the dispute via Stripe Dashboard. Standard chargeback flow applies.