Friendlier response when already-paid player clicks checkout link #483

Open
opened 2026-04-14 03:17:27 +00:00 by forgejo_admin · 0 comments
Contributor

Type

Feature

Lineage

Discovered Apr 13. Querenne (paid Order #25) would see "Player already has an active order (order #25)" if she clicks the new email. Technical wording, poor UX.

Repo

forgejo_admin/basketball-api

User Story

As a parent who has already paid
I want a clear confirmation when I click a payment link again
So that I'm reassured I'm paid up instead of seeing a raw technical error

Context

GET /checkout/first-payment raises HTTPException(409, detail="Player already has an active order for this product (order #N)") for paid players. Browser shows raw JSON. Should be: redirect to a branded confirmation page that says the amount paid and next charge date.

File Targets

  • src/basketball_api/routes/checkout.py — paid-order branch in first_payment_checkout() (~line 360). Replace raise HTTPException(409, ...) with a 307 redirect to a friendly URL (e.g., /checkout/already-paid?player=X).
  • westside-app/src/routes/(app)/checkout/already-paid/+page.svelte — new route showing branded confirmation.

Acceptance Criteria

  • Clicking a first-payment link for a paid player shows a branded confirmation page (not raw JSON)
  • Page states: already paid, amount, next charge date
  • Tests updated to reflect new behavior

Test Expectations

  • Update test_first_payment_paid_still_blocked for redirect response
  • Run: pytest tests/test_first_payment.py -v

Constraints

  • Behavior change — audit integrations for 409 dependency
  • Stripe-session and webhook flows unchanged
  • Match westside-app branding

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • westside-app route created and deployed
  • westside-basketball — project this affects
  • basketball-api#479 — related fix
  • Companion ticket: exclude already-paid players from blast audience
### Type Feature ### Lineage Discovered Apr 13. Querenne (paid Order #25) would see "Player already has an active order (order #25)" if she clicks the new email. Technical wording, poor UX. ### Repo `forgejo_admin/basketball-api` ### User Story As a parent who has already paid I want a clear confirmation when I click a payment link again So that I'm reassured I'm paid up instead of seeing a raw technical error ### Context `GET /checkout/first-payment` raises `HTTPException(409, detail="Player already has an active order for this product (order #N)")` for paid players. Browser shows raw JSON. Should be: redirect to a branded confirmation page that says the amount paid and next charge date. ### File Targets - `src/basketball_api/routes/checkout.py` — paid-order branch in `first_payment_checkout()` (~line 360). Replace `raise HTTPException(409, ...)` with a 307 redirect to a friendly URL (e.g., `/checkout/already-paid?player=X`). - `westside-app/src/routes/(app)/checkout/already-paid/+page.svelte` — new route showing branded confirmation. ### Acceptance Criteria - [ ] Clicking a first-payment link for a paid player shows a branded confirmation page (not raw JSON) - [ ] Page states: already paid, amount, next charge date - [ ] Tests updated to reflect new behavior ### Test Expectations - Update `test_first_payment_paid_still_blocked` for redirect response - Run: `pytest tests/test_first_payment.py -v` ### Constraints - Behavior change — audit integrations for 409 dependency - Stripe-session and webhook flows unchanged - Match westside-app branding ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes - [ ] westside-app route created and deployed ### Related - `westside-basketball` — project this affects - `basketball-api#479` — related fix - Companion ticket: exclude already-paid players from blast audience
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/basketball-api#483
No description provided.