docs: update all documentation for multi-method payments and saved cards

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-05-25 18:04:53 +01:00
co-authored by Sisyphus
parent f553ebad99
commit 97c9d1643f
6 changed files with 122 additions and 46 deletions
+3 -2
View File
@@ -10,7 +10,8 @@ Nail salon booking platform — Go 1.25 backend + SvelteKit 5 frontend + Docker.
- **Service eligibility**: age requirements + patch test validation
- **Deposit system**: 3-strike rule for late cancellations, 24-hour threshold
- **Square payments**: in-person Terminal + online Web Payments SDK (dev mock + prod stub, build-tagged)
- **Payment types**: deposit, full, partial, balance, tip — with saved cards, refunds, and webhook handling
- **Payment methods**: Card (Square Terminal/online), cash, gift card — with saved cards, refunds, and webhook handling
- **Payment types**: deposit, full, partial, balance, tip — admin can override service prices during payment
- **Scheduling**: default hours, holiday overrides, time blockers
- **Loyalty & discounts**: stamp-based loyalty, time-based and milestone campaigns
- **Portfolio gallery**: S3/R2 storage with tag/category filtering
@@ -88,7 +89,7 @@ cd backend && go build -o bin/backend ./main.go
# Frontend
cd frontend && npm ci && npm run build
# Tests (351/351 passing)
# Tests (396/399 passing, 3 skipped)
cd backend && go test -tags "test,dev" ./...
```
+40 -7
View File
@@ -40,20 +40,53 @@ At the very top of the page, you'll see two cards:
**Edit** — Opens a window where you can change which services are included in the appointment. You can add services, remove services, or swap them out. You can also adjust the price or duration of individual services if needed (for example, if a service took longer than expected last time). You can also update the appointment notes here.
**Take Payment** — Opens the Square Terminal payment flow. The admin enters the payment amount (or uses the booking total), optionally adds a tip, and initiates the checkout. The system polls for payment completion and updates the booking status automatically.
**Take Payment** — Opens the payment modal where you can choose between Card (Square Terminal), Cash, or Gift Card payment. See the "Taking Payments" section below for full details.
**Extend** and **Cancel** — These buttons are placeholders and don't do anything yet.
### Taking Payments
The **Take Payment** button on the Current Appointment card opens a payment modal connected to Square Terminal:
The **Take Payment** button on the Current Appointment card opens a multi-method payment modal:
1. **Amount**: Pre-filled with the booking total. Admin can override if needed (e.g., additional services added during the appointment).
2. **Tip**: Optional 10% tip toggle.
3. **Checkout**: Initiates a Square Terminal checkout. The customer taps their card on the Terminal device.
4. **Confirmation**: Payment status polls every 2 seconds. On completion, the booking is updated and a receipt is generated.
#### Step 1: Review Services and Choose Payment Method
For online payments (deposits, early payments), users pay through their `/schedule` modal or the booking confirmation page. Admins can view payment history and process refunds from the booking details.
The modal shows each service on the booking with an **editable price field**. You can adjust individual service prices if needed (for example, if a service cost more or less than usual). Any changes are highlighted with a "was £X.XX" note. The subtotal updates automatically.
Below the services, you'll see three payment method buttons:
- **Card** — Processes payment through the Square Terminal device. The customer taps their card on the Terminal.
- **Cash** — Record a cash payment. You enter the amount received, the system calculates change due, and offers an option to keep the change as a tip.
- **Gift Card** — Record a gift card payment. Enter the 12-digit gift card ID (formatted as XXXX XXXX XXXX as you type).
#### Step 2: Card Payment — Select Tip
If you chose **Card**, you'll be asked whether to add a tip:
- **Preset percentages**: 10%, 15%, or 20% of the booking total
- **Custom amount**: Enter any tip amount manually
- The total with tip is shown before you confirm
Click **Charge Card** to initiate the Square Terminal checkout. The system polls for payment completion and updates the booking status automatically.
#### Step 3: Cash Payment — Enter Amount Received
If you chose **Cash**, enter the amount of cash the customer handed you:
- The system calculates the **change due** automatically
- If the customer gave more than the total, you can check **"Keep [change] as tip"** to record the excess as a tip
- Click **Confirm Cash** to record the payment
#### Step 4: Gift Card Payment — Enter Card ID
If you chose **Gift Card**, enter the 12-digit ID printed on the gift card:
- The ID is automatically formatted with spaces as you type (XXXX XXXX XXXX)
- The field validates that all 12 digits are entered
- Click **Apply Gift Card** to record the payment
#### Payment Confirmation
After any payment method succeeds, a receipt summary is shown with the payment amount, method, and a success indicator.
### Today's Appointments
+14 -13
View File
@@ -1,4 +1,4 @@
**Last Updated:** May 2026 — Square payment integration live, 351/351 tests passing, booking flow redesigned
**Last Updated:** May 2026 — Multi-method payments live (Card/Cash/Gift Card), saved cards management, online payment system expanded, amount precision (pence), tip page redesigned with percentages, 396/399 tests passing (3 skipped)
**Status:** Living backlog — add to this as gaps are discovered
---
@@ -14,7 +14,7 @@ No external dependencies. No paid services. No API keys needed.
| 1 | ~~`DELETE /api/user/account` is a no-op~~ ✅ | S (1-2h) | Backend | Wired to `anonymize_user()` for registered users and `delete_guest_user()` for guests. CardDAV contact deleted best-effort. |
| 2 | ~~**WalkInCreateModal guest booking errors out**~~ ✅ | S (1-2h) | Frontend | Guest creation now fires at submit time in both walk-in and call-in flows. Phone defaults to +447700900000 if left blank. |
| 3 | ~~**ApprovalModal decline/cancel stub**~~ ✅ | S (2-3h) | Frontend | `handleDecline()` now calls `POST /api/admin/bookings/{id}/cancel`. Backend sets status to `we_cancelled`, acknowledges pending notification, creates cancelled_booking notification. |
| 4 | **CurrentAppointment action stubs** | M (1d) | Frontend | `handleEdit()` ✅ — now opens `EditBookingModal` for service management. `handleTakePayment()` ✅ — wired to Square Terminal. `handleExtend()`, `handleCancel()` — dead buttons. |
| 4 | **CurrentAppointment action stubs** | M (1d) | Frontend | `handleEdit()` ✅ — now opens `EditBookingModal` for service management. `handleTakePayment()` ✅ — wired to multi-method PaymentModal (Card/Cash/Gift Card). `handleExtend()`, `handleCancel()` — dead buttons. |
## P1 — High
@@ -83,10 +83,10 @@ Require paid accounts, API approval, or external service credentials. **Do not a
| # | Gap | Effort | Area | Status | Notes |
|---|-----|--------|------|--------|-------|
| ~~E1~~ | ~~**Payment integration (Square SDK)**~~ | ~~XL (3-5d)~~ | ~~Full-stack~~ | ✅ **Complete** | Dev mock (`//go:build dev`) + prod stub (`//go:build !dev`). Terminal + online payments, refunds, tips, saved cards, webhooks. |
| ~~E2~~ | ~~**No deposit payment flow**~~ | ~~M (1-2d)~~ | ~~Full-stack~~ | ✅ **Complete** | Users with `deposits_required > 0` can pay deposits online via Web Payments SDK. One-active-booking limit enforced. |
| ~~E3~~ | ~~**Tip calculation UI**~~ | ~~S (1h)~~ | ~~Frontend~~ | ✅ **Complete** | Tip button on completed bookings in `/account` modal. `POST /api/bookings/{id}/tip` endpoint. |
| ~~E4~~ | ~~**Gift card system**~~ | ~~L (3-5d)~~ | ~~Full-stack~~ | ✅ **Complete** | `giftcard` in `payment_method` enum. Backend handlers wired. UI pending. |
| ~~E1~~ | ~~**Payment integration (Square SDK)**~~ | ~~XL (3-5d)~~ | ~~Full-stack~~ | ✅ **Complete** | Dev mock (`//go:build dev`) + prod stub (`//go:build !dev`). Terminal + online payments, refunds, tips, saved cards, webhooks. **Multi-method:** Card (Terminal/online), Cash (change calc + tip), Gift Card (12-digit ID). **Amount precision:** API uses pence (int64). **Tip page:** Percentage-based (10/15/20%) + custom. |
| ~~E2~~ | ~~**No deposit payment flow**~~ | ~~M (1-2d)~~ | ~~Full-stack~~ | ✅ **Complete** | Users with `deposits_required > 0` can pay deposits online via Web Payments SDK. One-active-booking limit enforced. Supports deposit, full, partial, and balance payment types. Saved cards for faster checkout. |
| ~~E3~~ | ~~**Tip calculation UI**~~ | ~~S (1h)~~ | ~~Frontend~~ | ✅ **Complete** | Tip button on completed bookings via `/pay-tip/[id]`. Percentage-based (10%, 15%, 20%) or custom amount. `POST /api/bookings/{id}/tip` endpoint. Admin can also add tips during card/cash payments in PaymentModal. |
| ~~E4~~ | ~~**Gift card system**~~ | ~~L (3-5d)~~ | ~~Full-stack~~ | ✅ **Complete** | `giftcard` in `payment_method` enum. Backend handlers wired. Admin payment modal supports gift card payments (12-digit ID entry). UI for gift card management (create/redeem) pending. |
## Email/SMS — SMTP Provider (Resend, SendGrid, Twilio, etc.)
@@ -122,12 +122,12 @@ Require paid accounts, API approval, or external service credentials. **Do not a
┌─────────────────────────────────────────────────────────┐
│ EXTERNAL BLOCKERS │
│ │
│ E1 Square API ──┬──→ E2 Deposit payments
│ ├──→ E3 Tips │
│ └──→ E4 Gift cards
│ E1 Square API ──┬──→ E2 Deposit payments
│ ├──→ E3 Tips
│ └──→ E4 Gift cards ✅ (admin UI)
│ │
│ E5 SMTP/API ────┬──→ E6 Deposit reduction notifications│
│ └──→ E7 Waitlist notifications
│ E5 SMTP/API ────┬──→ E6 Deposit reduction notifications
│ └──→ E7 Waitlist notifications (removed)
│ │
│ E8 S3/R2 ───────→ Portfolio images in production │
│ │
@@ -180,7 +180,7 @@ Require paid accounts, API approval, or external service credentials. **Do not a
9. **#2** Wire WalkInCreateModal guest booking (1-2h) ✅
10. **#3** ApprovalModal decline/cancel (2-3h) ✅
11. ~~**#5** Admin notification panel (1-2d)~~
12. **#4** CurrentAppointment Extend + Cancel actions (1d) — skip TakePayment (blocked on E1). **Edit** ✅ — now opens `EditBookingModal` for service management.
12. **#4** CurrentAppointment Extend + Cancel actions (1d) — skip TakePayment (blocked on E1). **Edit** ✅ — now opens `EditBookingModal` for service management. **Take Payment** ✅ — multi-method PaymentModal (Card/Cash/Gift Card) with service price overrides and tip presets.
13. **#12** Booking cancellation from user account (2-3h)
14. **#40** No-show tracking dashboard (2-3h)
15. **#35** Walk-in slot blocking (1-2h) ✅
@@ -226,12 +226,13 @@ Require paid accounts, API approval, or external service credentials. **Do not a
45. ~~**#49**~~ ~~Image optimization~~ ✅ — complete
46. **#42** Dark mode (1-2d)
47. **#43** PWA support (3-5d)
48. **Gift card management UI** — Create/redeem gift cards, track balances (E4 backend + admin payment UI complete, management UI pending)
### ⏳ Waiting on External Access
| Item | Blocked On | Unblocks |
|------|-----------|----------|
| ~~**E1 Square payment**~~ | ✅ **Complete** | ✅ E2, E3, E4 complete |
| ~~**E1 Square payment**~~ | ✅ **Complete** | ✅ E2, E3, E4 complete — multi-method payments (Card/Cash/Gift Card), saved cards, tips |
| **E5 Email/SMS** | SMTP provider (Resend/SendGrid/Twilio) | E6, E7, booking reminders, password reset emails |
| **E8 S3/R2 production** | Cloudflare R2 or AWS S3 credentials | Portfolio images in production builds |
| **E9 Social auth** | OAuth app registrations (Google/Microsoft/Facebook) | Social login flow |
+10 -6
View File
@@ -112,8 +112,9 @@ flowchart TD
- Booking history with cancel/reschedule
- Calendar export (.ics download)
- Portfolio browsing with tag/category filtering
- **Online payments**: pay deposits, pay early, partial payments, tips on completed bookings
- **Saved cards**: store card details for faster checkout (soft-deleted on removal, 7-year retention)
- **Online payments**: pay deposits, pay early, partial payments, balance payments, tips on completed bookings
- **Saved cards**: manage cards in Account → Cards tab — add/remove cards for faster checkout (soft-deleted on removal, 7-year retention)
- **Tip page**: percentage-based tips (10%, 15%, 20%) or custom amount on completed bookings via `/pay-tip/[id]`
### Admin Features
- Today page (/today): current/next appointment, today's grid, pending approvals
@@ -126,7 +127,9 @@ flowchart TD
- Portfolio image upload with tag management
- Discount campaign management (time-based and milestone campaigns)
- Admin notification system (pull-based, acknowledgment)
- **Terminal payments**: Square Terminal integration for in-person card payments
- **Multi-method payments**: Square Terminal (card), cash (with change calculation and "keep change as tip"), gift card (12-digit ID)
- **Service price overrides**: admin can adjust individual service prices directly in the payment modal
- **Tip selection**: 10%, 15%, 20% presets or custom amount during card payments
- **Refunds**: process partial or full refunds on completed payments
- **Financial tracking**: fees column on payments for actual Square deductions, deposit batch tracking for bank reconciliation
@@ -141,15 +144,16 @@ flowchart TD
- Online deposit payments via Square (Web Payments SDK)
### Square Payment Integration
- **Two client implementations**: dev mock (`square_dev.go`, `//go:build dev`) simulates async checkout with polling; prod stub (`square.go`, `//go:build !dev`) connects to live Square API
- **Two client implementations**: dev mock (`square_dev.go`, `//go:build dev`) simulates async checkout with polling for Terminal + online payments; prod stub (`square.go`, `//go:build !dev`) connects to live Square API
- **Payment types**: deposit, full, partial, balance, tip
- **Payment methods**: online_square (Web Payments SDK), in_person_card (Square Terminal), cash, giftcard, discount
- **Saved cards**: `user_saved_cards` table with soft delete (`retained_until` for 7-year UK financial retention)
- **Saved cards**: `user_saved_cards` table with soft delete (`retained_until` for 7-year UK financial retention). Users can add cards manually via Account → Cards tab or save during checkout.
- **Refunds**: `refunds` table tracks partial/full refunds linked to original payments
- **Webhooks**: Square webhook handler at `/api/webhooks/square` for payment status updates
- **Idempotency**: all payments use idempotency keys to prevent duplicates
- **Fees tracking**: `payments.fees` column stores actual Square deductions for tax reporting
- **Deposit batch tracking**: `square_deposits` table for bank reconciliation (matching Square batch deposits to Mettle account)
- **Amount precision**: API responses use pence (int64) for all monetary values to avoid floating-point issues; internal DB storage uses pounds (float)
### Data & Compliance
- GDPR anonymization: guest PII scrubbed 6 months after booking start_time
@@ -191,7 +195,7 @@ All flows integrate with holiday/exceptional hours and time blockers.
## Test Coverage
**351/351 tests passing** across 12+ test packages.
**396/399 tests passing** (3 skipped) across 12+ test packages. Comprehensive coverage of online payments (deposit, full, partial, balance), saved card operations, tip payments, terminal payments, refunds, idempotency, webhook handling, and cash/gift card payments.
| Package | Coverage Area |
|---------|--------------|
+22 -9
View File
@@ -106,6 +106,9 @@ Backend (:8080)
| `/contact` | contact/+page.svelte | Dynamic contact info from first admin user |
| `/manage` | manage/+page.svelte | Booking management |
| `/demo` | demo/+page.svelte | Demo mode |
| `/booking-confirmed/[id]` | booking-confirmed/[id]/+page.svelte | Booking confirmation page with payment summary, deposit info |
| `/pay-tip/[id]` | pay-tip/[id]/+page.svelte | Tip payment page — percentage-based tips (10%, 15%, 20%) or custom amount |
| `/notifications` | notifications/+page.svelte | Admin notifications page with priority sorting, acknowledge flow |
| `/api/[...path]` | api/[...path]/+server.ts | API catch-all proxy (dev) |
### Component Hierarchy
@@ -138,8 +141,8 @@ src/lib/components/
│ ├── StepIndicator.svelte # Progress steps
│ └── TimeSlotPicker.svelte # Time slot grid
├── payments/
│ ├── PaymentModal.svelte # Admin payment modal (Terminal, override, tip)
│ └── UserPaymentModal.svelte # User payment modal (deposit, partial, full, no tip)
│ ├── PaymentModal.svelte # Admin payment modal — multi-method: Card (Terminal), Cash (change calc), Gift Card (12-digit ID), service price overrides, tip presets (10/15/20%)
│ └── UserPaymentModal.svelte # User payment modal (deposit, partial, full, balance — no tip)
├── today/
│ ├── CurrentAppointment.svelte # Active appointment display
│ ├── PendingApprovals.svelte # Pending booking approvals
@@ -211,6 +214,7 @@ src/lib/components/
| GET | `/api/bookings/{id}/payment-summary` | Get payment summary for booking |
| GET | `/api/user/payment-methods` | Get user's saved cards |
| DELETE | `/api/user/payment-methods/{id}` | Soft-delete a saved card |
| POST | `/api/user/payment-methods` | Add a saved card (card number, expiry, CVC) |
### Admin Endpoints
@@ -636,7 +640,7 @@ go test -tags "test,dev" -v -p 1 -count=2 ./... # Run twice for flaky detection
### Test Coverage
**351/351 tests passing** across 12+ packages:
**396/399 tests passing** (3 skipped) across 12+ packages. Comprehensive coverage of online payments (deposit, full, partial, balance), saved card operations, tip payments, terminal payments, refunds, idempotency, webhook handling, and cash/gift card payments.
- `handlers/auth` — Authentication
- `handlers/bookings` — User booking flow, guest bookings, reservations, edit requests, discounts, closing hours validation, active booking limits
- `handlers/payments` — Square payments (terminal, online, refunds, tips, saved cards)
@@ -671,18 +675,23 @@ go test -tags "test,dev" -v -p 1 -count=2 ./... # Run twice for flaky detection
### Square Payment Integration
**Architecture:** `internal/square/` defines a `Client` interface with two implementations:
- **Dev mock** (`square_dev.go`, `//go:build dev`): Simulates Square Terminal checkout asynchronously. Creates a checkout session that transitions from PENDING → COMPLETED after a short delay. Used for local testing without API credentials.
- **Dev mock** (`square_dev.go`, `//go:build dev`): Simulates Square Terminal checkout asynchronously. Creates a checkout session that transitions from PENDING → COMPLETED after a short delay. Also simulates online Web Payments SDK payments. Used for local testing without API credentials.
- **Prod stub** (`square.go`, `//go:build !dev`): Connects to live Square API using `github.com/square/square-go-sdk`. Requires `SQUARE_ACCESS_TOKEN`, `SQUARE_LOCATION_ID`, and `SQUARE_WEB_PAYMENTS_APP_ID` environment variables.
**Initialization:** `main.go` calls `square.NewClient()` (wrapper function in both build-tagged files) to avoid `undefined: square.NewDevClient` during test builds.
**Payment flows:**
1. **Terminal (in-person)**: Admin initiates via `POST /api/admin/bookings/{id}/payment` → creates Square Terminal checkout → polls status → completes booking
2. **Online (Web Payments SDK)**: User initiates via `POST /api/bookings/{id}/payment` → creates online payment → processes card token → completes booking
3. **Tips**: `POST /api/bookings/{id}/tip` — only for completed bookings
4. **Refunds**: `POST /api/admin/payments/{payment_id}/refund` — partial or full refunds
1. **Terminal (in-person)**: Admin initiates via `POST /api/admin/bookings/{id}/payment` → creates Square Terminal checkout → polls status → completes booking. Admin can also record cash or gift card payments through the same endpoint with `payment_method: "cash"` or `payment_method: "giftcard"`.
2. **Online (Web Payments SDK)**: User initiates via `POST /api/bookings/{id}/payment` → creates online payment → processes card token → completes booking. Supports deposit, full, partial, and balance payment types.
3. **Tips**: `POST /api/bookings/{id}/tip` — only for completed bookings. Percentage-based (10%, 15%, 20%) or custom amount.
4. **Refunds**: `POST /api/admin/payments/{payment_id}/refund` — partial or full refunds.
5. **Saved cards**: `POST /api/user/payment-methods` — user adds card manually (card number, expiry, CVC). `DELETE /api/user/payment-methods/{id}` — soft-deletes card.
**Saved cards:** `user_saved_cards` table stores `square_card_id`, `brand`, `last4`, `fingerprint`, `expiry_month`, `expiry_year`. Soft-deleted with `retained_until` set to 7 years from deletion (UK financial data retention law). Users can have multiple saved cards.
**Amount precision:** API responses return monetary values in **pence (int64)** to avoid floating-point precision issues. Internal database storage uses **pounds (float)**. The conversion happens at the handler layer:
- DB → API: `int64(amount * 100)`
- API → DB: `float64(amount) / 100.0`
**Saved cards:** `user_saved_cards` table stores `square_card_id`, `brand`, `last4`, `fingerprint`, `expiry_month`, `expiry_year`. Soft-deleted with `retained_until` set to 7 years from deletion (UK financial data retention law). Users can have multiple saved cards. Cards can be added via Square tokenization during checkout OR manually via the Account → Cards tab frontend.
**Webhooks:** Square sends webhook events to `/api/webhooks/square` for payment status updates. Signature verified via `x-square-signature` header.
@@ -692,6 +701,10 @@ go test -tags "test,dev" -v -p 1 -count=2 ./... # Run twice for flaky detection
**Deposit batch tracking:** `square_deposits` table tracks Square batch deposits for bank reconciliation. Each row represents a batch deposited to the Mettle account.
**Cash payments:** Recorded via `POST /api/admin/bookings/{id}/payment` with `payment_method: "cash"`. Amount is the booking total in pence. Tip can be included via `tip_enabled: true` + `tip_amount`.
**Gift card payments:** Recorded via `POST /api/admin/bookings/{id}/payment` with `payment_method: "giftcard"` and `gift_card_id` (12-digit string). Amount is fixed at 1000 pence (£10.00) in the current implementation.
## Security
+33 -9
View File
@@ -89,9 +89,11 @@ All bookings must be made at least 1 hour before the appointment start time.
After submitting, you'll see a confirmation screen showing:
- Your appointment date and time
- The services you selected
- The services you selected (with any admin-adjusted prices or durations noted)
- The total price
- Payment status — if a deposit is required, you'll see the deposit amount and deadline
- An **Add to Calendar** button — this downloads a calendar file you can import into Google Calendar, Apple Calendar, Outlook, or any other calendar app
- A **View My Bookings** button that takes you to your Schedule page to see all upcoming appointments
---
@@ -181,6 +183,25 @@ Tap any booking to see full details.
The **Schedule** page shows your upcoming appointments in a calendar-style layout. Each appointment has an **Add to Calendar** button that downloads a calendar file (.ics) you can open in any calendar application — Google Calendar, Apple Calendar, Outlook, and others all support this format.
### Saved Cards
If you have a verified account, you'll see a **Cards** tab on your Account page. This lets you manage your saved payment methods for faster checkout.
**Add a Card:**
1. Go to the **Cards** tab
2. Click **Add a Card**
3. Enter your card number (automatically formatted with spaces as you type)
4. Enter the expiry date (MM/YY format)
5. Enter the CVC (the 3- or 4-digit security code on the back of your card)
6. Click **Add Card** — the system validates the card details before saving
**Remove a Card:**
- Each saved card shows the brand (Visa, Mastercard, etc.), the last 4 digits, and the expiry date
- Click **Remove** next to any card to delete it. The card is soft-deleted and retained for 7 years to comply with UK financial regulations.
**Why save a card?**
When you pay for deposits, early payments, or tips online, you can choose a saved card instead of entering your details each time. This makes checkout faster and more convenient.
---
## Cancelling an Appointment
@@ -255,21 +276,24 @@ If you have a deposit outstanding, you can pay it online without waiting for you
2. Click on your upcoming booking
3. Click **Pay Deposit** — this opens the payment modal
4. The deposit amount (20% of the booking total) is shown
5. Choose to pay the deposit or pay the full amount
6. Enter your card details or use a saved card
5. Choose to pay the deposit, pay the full amount, or pay a partial amount
6. Enter your card details, use a saved card, or choose a card token from Square's secure form
7. Confirm payment
If no deposit is owed but you haven't paid the full amount yet, you'll see a **Pay Early** button instead. You can also pay a partial amount using the **Pay Part** option with a custom amount input.
If no deposit is owed but you haven't paid the full amount yet, you'll see a **Pay Early** button instead. You can also pay a partial amount using the **Pay Part** option with a custom amount input. If you've already paid a deposit, you'll see a **Pay Balance** option to settle the remaining amount.
### Leaving a Tip
After your appointment is marked as **completed**, you can leave a tip:
1. Go to **Account** from the menu
2. Find your completed booking and click **View**
3. Click **Leave a Tip**
4. Enter the tip amount or choose a preset percentage
5. Confirm payment
1. Go to the tip page (the salon may send you a link, or you can access it from your booking confirmation)
2. You'll see your appointment details — date, time, and services
3. Choose a tip amount:
- **Preset percentages**: 10%, 15%, or 20% of your booking total (the £ amount is shown for each)
- **Custom amount**: Enter any amount you'd like to tip
4. Confirm payment — your saved card can be used if you have one on file
The tip page is secure and uses Square for payment processing.
### Quick Reference