Review: Stripe Checkout + webhook
Verdict: READY
Template Completeness
- [x] Type — Feature
- [x] Lineage — Sub-ticket of #7, depends on #8 + #9, parallel with #10, uses #2 spike
- [x] Repo — forgejo_admin/twitch-2k-wager
- [x] User Story — challenger wants tiered pay via Stripe Checkout
- [x] Context — Stripe Checkout with inline price_data, webhook handler, test keys
- [x] File Targets — 3 new files specified
- [x] Acceptance Criteria — 6 criteria
- [x] Test Expectations — Stripe CLI listen + DB verification
- [x] Constraints — test keys, match spike, webhook reachability
- [x] Checklist — PR opened, tests pass, no unrelated changes
- [x] Related — parent #7, spike #2, story note, arch note
Traceability
- [x] story:challenger-pay — "Secure Buy-In Payment" (story-twitch-2k-wager-challenger-pay, id 1158)
- [x] story note verified — challenger-pay entry found in project-twitch-2k-wager user-stories table
- [x] arch:dataflow-twitch-2k-wager — "Data Flow: Twitch 2K Wager" (arch-dataflow-twitch-2k-wager, id 1155)
- [x] arch note verified — arch-dataflow-twitch-2k-wager exists (note_type: architecture, status: active)
- [x] Forgejo issue — forgejo_admin/twitch-2k-wager#11, state: open
File Targets
- [x]
src/routes/api/checkout/+server.ts— NEW file to create. Parent dir src/routes/ exists (scaffold merged via PR #16). Valid SvelteKit server route path. - [x]
src/routes/api/webhooks/stripe/+server.ts— NEW file to create. Valid SvelteKit server route path for webhook handler. - [x]
src/lib/stripe.ts— NEW file to create. src/lib/ exists (contains db.ts, types.ts, schema.sql). Consistent placement.
All file targets are new files to be created. Existing scaffold (PR #16) and DB layer (PR #15) provide the foundation. No existing line references to verify. Targets are specific enough for an agent to act on without guessing.
Repo Placement
OK. Issue filed on forgejo_admin/twitch-2k-wager, all file targets are in the same repo. Single-repo scope. No cross-repo concerns.
Dependencies
- [x] #8 SvelteKit scaffold — satisfied (merged as PR #16)
- [x] #9 Postgres schema + db.ts — satisfied (merged as PR #15)
- [x] #2 Stripe spike — satisfied (merged as PR #6, FINDINGS.md at spike/stripe/FINDINGS.md)
- [x] #10 Keycloak OIDC auth — parallel work, no dependency
All hard dependencies satisfied. Note:
stripe npm package is not yet in package.json — agent must run npm install stripe as part of implementation.Acceptance Criteria
6 criteria, all verifiable by an agent:
- Three tier buttons create Checkout sessions — testable via unit test or API call to the endpoint
- Stripe Checkout (hosted) opens with correct amount — verifiable via session object's amount_total field
- Webhook receives checkout.session.completed — testable via
stripe listen --forward-to - Game + Payment records created in DB — verifiable via SQL query after test payment
- Challenger redirected to game status page — verifiable via Checkout session success_url config
- Webhook signature verified — verifiable via code inspection (constructEvent call) + failing test with bad signature
All criteria are concrete and testable. No ambiguity.
Blast Radius
Low. This is a new application with no downstream consumers yet. The webhook endpoint path (
/api/webhooks/stripe) is standard. No sibling services share this Stripe account (test keys are project-specific). The DB layer (db.ts) is already merged and this ticket consumes it without modifying it. Rollback is straightforward — revert the PR.Informational (does not block this ticket): The spike FINDINGS.md recommends manual payout (CashApp/Venmo) + full refund on challenger win, which diverges from the arch-dataflow diagram showing Stripe Connect Express for payouts. This discrepancy affects ticket #12 (Stripe Connect payout), not #11. Consider updating the arch diagram or revising #12 scope before that ticket reaches review.
Decomposition Assessment
3 file targets in 1 repo. 6 acceptance criteria. Estimated agent time: ~4-5 minutes. All three files are tightly coupled (stripe.ts is consumed by both route handlers). No independent subtasks that would benefit from parallelization. Fits within the three-thing limit (3 files) and five-minute rule. No decomposition needed.
Recommendation
No action needed. Ticket is ready for execution.