Issue refunds
Walk through the refund dialog, overrides, and captain blocks.
Issue refunds
The quick version is in Handle refunds. This article covers the admin mechanics in more detail.
Opening the dialog
From Registrants, click a row. On the detail page, click the Refund button in the top-right action bar. The dialog pops and computes:
- The policy tier that applies today (e.g. "30 days before: 75%")
- The refund amount in dollars based on what the player actually paid
- The Stripe payment intent that will be refunded
- Any free spot credit that returns to the team
Review before confirming
Always sanity-check:
- Does the policy tier match what you expected?
- Is the amount reasonable?
- Is this the right Stripe payment (match against the ID in the Stripe dashboard if you're unsure)?
Click Confirm refund to send to Stripe. The button is disabled if something is wrong (e.g. captain without a transfer queued).
Captain refund block
If the registration is a captain, the dialog shows a block: "Cannot refund captain. Transfer captaincy first." There's a link to the team page where you can promote another paid player to captain. Once the transfer completes, come back and retry the refund.
Manual override
Click Override amount to enter an arbitrary dollar amount, up to the original payment. Use this for:
- Weather cancellations (full refund regardless of date)
- Medical emergencies (judgment call)
- Partial compensation (e.g. 50% credit because the player's bracket was cut)
Overrides are logged with your admin ID and a required reason text field. You'll be asked for the reason before you can confirm.
Failure modes
- Stripe rejects the refund — usually because the original charge was disputed. The dialog shows Stripe's error message. Follow the disputed-charge flow in the Stripe dashboard.
- Webhook didn't update — rare. Open Finance -> Transactions and look for the refund. If it's missing, check your Stripe webhook signing secret.
- Partial refund not honored — Stripe only allows partial refunds before the original charge is fully captured. After payout, you can still refund; double-check the dashboard if the amount doesn't match.
Audit
Every refund appends to the registration's audit history and creates a new transactions row with type = 'refund'. The registration status flips to refunded or partial_refund depending on the amount.
Was this helpful?
