Refactor: extract shared Payment Link helper from monthly + tournament checkout services #502
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/basketball-api#502
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Feature
Lineage
Standalone — discovered 2026-04-18 during QA review of PR #499 (monthly-fee Payment Links migration). Reviewer flagged
src/basketball_api/services/monthly_checkout.pyandsrc/basketball_api/services/tournament_checkout.pyas ~95% structurally identical.Repo
forgejo_admin/basketball-apiUser Story
As a developer adding a third Payment Link flow (jersey, tryout, generic — any future migration from Sessions), I want one shared helper that takes the per-flow deltas as parameters, not two near-duplicate implementations I have to keep in sync by hand.
Context
PR #499 shipped
services/monthly_checkout.py::create_monthly_order_payment_linkas a direct analog ofservices/tournament_checkout.py::create_tournament_order_payment_linkfrom PR #494. QA noted ~95% overlap. The two differ on:setup_future_usage: "off_session"is set (monthly yes, tournament no)Order.amount_cents(monthly, prorated) vsproduct.price_cents(tournament, flat)/checkout/first-payment?token=...redirect)All three are parameterizable. A shared
create_order_payment_link(order, *, setup_future_usage=False, amount_source="order")helper would replace both with thinner call-site wrappers. Lowers the cost of the next migration (jersey/tryout/generic if those ever need to inherit indefinite-lived URLs).File Targets
Dev agent's decision — grep the two existing helpers and factor the commonality. Likely targets:
src/basketball_api/services/payment_links.py(shared helper)src/basketball_api/services/monthly_checkout.py(thin wrapper, ≤20 lines)src/basketball_api/services/tournament_checkout.py(thin wrapper, ≤20 lines)tests/test_payment_links_helper.py(unit coverage for kwarg branches)src/basketball_api/routes/webhooks.py(gate logic is already a single function; no refactor there)Scope
Acceptance Criteria
services/payment_links.py(or equivalent) houses the shared helperservices/monthly_checkout.pyandservices/tournament_checkout.pyeach thin out to a wrapper (≤20 lines each)tests/test_monthly_payment_link_real_stripe.pyandtests/test_payment_link_real_stripe.py)Test Expectations
setup_future_usage: "off_session"still asserted on the monthly pathConstraints
create_payment_link(**kwargs)that accepts arbitrary Stripe params — keep the helper opinionated, with exactly the three named deltas as kwargs.webhooks.pyis already a single function with a category gate; no refactor needed there.Checklist
Related
forgejo_admin/basketball-api #494— tournament Payment Link migrationforgejo_admin/basketball-api #498— monthly Payment Link migration (PR #499)