Stripe webhook not syncing checkout.session.completed to order status #264

Closed
opened 2026-03-30 23:44:44 +00:00 by forgejo_admin · 0 comments
Contributor

Type

Bug

Lineage

Standalone -- discovered during jersey validation 2026-03-30. Zion Odejinmi (player #113) paid $90 via Stripe but order #18 stayed pending.

Repo

forgejo_admin/basketball-api

What Broke

Stripe checkout session cs_live_a1aS... completed with payment_status=paid and payment_intent=succeeded, but Order #18 in our database remained pending. The Stripe webhook handler (checkout.session.completed) either didn't fire, wasn't received, or failed to update the order.

This means Marcus cannot see actual payment status in the CRM -- the system shows pending/opt-out when players have actually paid.

Repro Steps

  1. Player completes Stripe checkout for jersey ($90)
  2. Stripe confirms payment (session.status=complete, payment_status=paid)
  3. Check database: order status still shows pending
  4. Player record still shows old jersey_option (e.g. opt_out from previous order)

Expected Behavior

When Stripe fires checkout.session.completed, the webhook handler should:

  • Update Order status from pending to paid
  • Sync jersey fields to the Player record (jersey_option, jersey_size, jersey_number, jersey_order_status)
  • Handle the case where a player has a previous opt-out order

Environment

  • Cluster/namespace: prod / basketball-api
  • Service version: commit 4cd0e1b5
  • Affected: Order #18 (player #113, Zion Odejinmi) -- manually corrected 2026-03-30
  • Stripe session: cs_live_a1aSpyZL1x7AEt1LMBWitNyY49Wz1pdz06bWC2aJmFZ42Vqk888XySIlrc

Acceptance Criteria

  • Webhook handler correctly processes checkout.session.completed events
  • Order status updates from pending to paid on successful payment
  • Player jersey fields sync from the paid order
  • Webhook logs are visible in structured API logs for debugging
  • project-westside-basketball
  • story:WS-S18
  • basketball-api#263 (opt-out removal)
### Type Bug ### Lineage Standalone -- discovered during jersey validation 2026-03-30. Zion Odejinmi (player #113) paid $90 via Stripe but order #18 stayed pending. ### Repo `forgejo_admin/basketball-api` ### What Broke Stripe checkout session `cs_live_a1aS...` completed with `payment_status=paid` and `payment_intent=succeeded`, but Order #18 in our database remained `pending`. The Stripe webhook handler (`checkout.session.completed`) either didn't fire, wasn't received, or failed to update the order. This means Marcus cannot see actual payment status in the CRM -- the system shows pending/opt-out when players have actually paid. ### Repro Steps 1. Player completes Stripe checkout for jersey ($90) 2. Stripe confirms payment (session.status=complete, payment_status=paid) 3. Check database: order status still shows `pending` 4. Player record still shows old jersey_option (e.g. opt_out from previous order) ### Expected Behavior When Stripe fires `checkout.session.completed`, the webhook handler should: - Update Order status from `pending` to `paid` - Sync jersey fields to the Player record (jersey_option, jersey_size, jersey_number, jersey_order_status) - Handle the case where a player has a previous opt-out order ### Environment - Cluster/namespace: prod / basketball-api - Service version: commit `4cd0e1b5` - Affected: Order #18 (player #113, Zion Odejinmi) -- manually corrected 2026-03-30 - Stripe session: cs_live_a1aSpyZL1x7AEt1LMBWitNyY49Wz1pdz06bWC2aJmFZ42Vqk888XySIlrc ### Acceptance Criteria - [ ] Webhook handler correctly processes checkout.session.completed events - [ ] Order status updates from pending to paid on successful payment - [ ] Player jersey fields sync from the paid order - [ ] Webhook logs are visible in structured API logs for debugging ### Related - `project-westside-basketball` - story:WS-S18 - basketball-api#263 (opt-out removal)
forgejo_admin 2026-03-31 00:16:18 +00:00
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#264
No description provided.