Fix review findings: BuyGiftCard concurrency lock, amount guards, NULL scan, mock dedup, docs
N1 (HIGH) — BuyGiftCard concurrent same-key retry could double-issue gift cards (2× value for 1 charge). Added pg_advisory_lock on the idempotency key (mirroring the tip pattern) acquired before the idempotency check, so concurrent same-key retries serialize and only one executes gift-card creation. N2 — Amount-equality guards in both reuse branches (CreateTipPayment and BuyGiftCard). A same-key retry with a different amount now returns 400 instead of silently mutating the pending record's books/VAT/refund caps. N3 — test coverage: - TestBuyGiftCard_RetryPending_ReattemptsCharge: pending record + same-key retry re-attempts, reuses the record (count=1), completes, and issues the gift card exactly once. - TestCreateCheckoutHTTP_DeviceOptionsWireShape: httptest.Server asserts device_id is under checkout.device_options (not top-level). Extracted createCheckoutHTTPWithClient for injectable base URL. - MockClient.CreatePayment now dedups on idempotency key (paymentByKey map), matching real Square behaviour. N4 — Corrected the savepoint comments in handlers.go and giftcards.go: the savepoint only exists in the test harness; in production db.Conn.Begin is a plain tx and the status UPDATE runs on a separate pooled connection. Commit is a harmless no-op in prod but required in tests. Bonus bug fixed: CheckIdempotencyByKey scanned NULL booking_id/gift_card_id (gift-card purchases) into plain string, failing with 'cannot scan NULL'. Now uses sql.NullString. Docs: Technical Manual.md:53 and Feature Catalog.md (2.1, 2.5) corrected — no longer claim Web Payments SDK is live; new-card entry is documented as pending P11, saved-card flow works via ccof tokens, dev mock rejects raw PANs.
This commit is contained in:
@@ -162,8 +162,8 @@ Multi-method payment system accepting Square (card terminal & online), cash, gif
|
||||
|
||||
**Related:** [[Booking System|1. Booking System]] (deposits), [[Gift Cards|4. Gift Cards]] (pay by gift card), [[Admin Dashboard|5. Admin Dashboard]] (till purchases)
|
||||
|
||||
### 2.1 Online Card Payment (Square Web Payments SDK)
|
||||
**What it does:** Customers pay online using a credit/debit card via Square's Web Payments SDK. Used for deposits, full payments, balance payments, and tips.
|
||||
### 2.1 Online Card Payment (Square — saved cards; new-card entry pending P11)
|
||||
**What it does:** Customers pay online with a card. Saved-card payments work end-to-end via Square tokenized card IDs (`ccof:`). New-card entry (raw PAN entry in the UI) is a documented dead end until Square Web Payments SDK nonces land — see `plans/p11-square-web-payments-sdk.md`. The dev mock rejects raw PANs to mirror production. Used for deposits, full payments, balance payments, and tips.
|
||||
|
||||
**Layman summary:** "Pay online with your card — just like any online shop."
|
||||
|
||||
@@ -191,7 +191,7 @@ Multi-method payment system accepting Square (card terminal & online), cash, gif
|
||||
**Related:** [[Gift Cards|4. Gift Cards]], [[VAT Calculation|2.10 VAT Calculation]]
|
||||
|
||||
### 2.5 Saved Cards
|
||||
**What it does:** Customers can save their card details for faster checkout next time. Cards are tokenized via Square (raw card numbers never touch the server). Soft-deleted with 7-year UK retention.
|
||||
**What it does:** Customers can save their card details for faster checkout next time. Cards are tokenized via Square (`ccof:` card IDs; the full PAN exists only in Square's vault — our DB stores only the reference + brand/last4/fingerprint). The dev mock mirrors this (raw PANs rejected). Soft-deleted with 7-year UK retention. Note: the "Add Card" UI currently sends raw PAN and is a dead end until P11 (Web Payments SDK nonces) — see `plans/p11-square-web-payments-sdk.md`.
|
||||
|
||||
**Layman summary:** "Save your card for next time — one-click payment."
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ Backend (:8080)
|
||||
|---------|--------|---------|
|
||||
| SabreDAV (CardDAV/CalDAV) | Active | Contact sync (profile photos), calendar events |
|
||||
| S3/R2 | Active (dev) | Portfolio images (AVIF), profile pictures (WebP) |
|
||||
| Square | **Active** | Payment processing — in-person Terminal + online Web Payments SDK. Dev mock (`//go:build dev`) simulates async checkout; prod stub (`//go:build !dev`) connects to live API. |
|
||||
| Square | **Active** | Payment processing — in-person Terminal (`CreateTerminalCheckout`) + online card payments (saved cards working; new-card entry pending Web Payments SDK nonces — backlog P11, see `plans/p11-square-web-payments-sdk.md`). Dev mock (`//go:build dev`) mirrors production PCI-DSS behaviour (rejects raw PANs; accepts `cnon:`/`ccof:` tokens); prod client (`!dev`) connects to live API. |
|
||||
| SMTP | Not implemented | Email/SMS notifications — backend not wired |
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user