Payments & money
How payments work
A deep dive into the two-step payment flow that powers every request.
Why manual capture
Traditional jukeboxes charge upfront. If the DJ doesn't play the song, the guest is out the money and support has to issue a refund. Manual capture flips this: the guest is only charged when the song actually plays.
The lifecycle
- 1Request created — server function inserts the row with status pending_payment.
- 2PaymentIntent created — Stripe creates a PI with capture_method: manual.
- 3Authorized — guest completes checkout. Stripe returns success; we mark auth_status: authorized and status queued.
- 4Played — DJ marks the song played. We call Stripe capture, update to captured, and set played_at.
- 5OR Voided — DJ declines. We call Stripe cancel on the PI, update to voided, status becomes declined.
- 6OR Refunded — if the PI was already captured (rare edge case), we issue a refund instead.
Webhook resilience
Every Stripe event is idempotently applied. If our server misses one, the next scheduled reconciliation catches it. Every state change is written to the audit log with the PaymentIntent ID.
Guest experience
- During auth: card shows a pending charge.
- On capture: pending charge becomes a real charge, same amount.
- On void: pending charge drops off (bank timing varies, usually within a few days).
Edge cases
Auth expiration
Stripe auth holds expire after 7 days. Requests still queued after that expire and are auto-voided.