Refunds & Notifications · Article 6.2
Stripe automatic refund (Direct Charges via Connect)
When the original deposit was paid via Stripe, the refund is automatic. Clozo issues a Refund on the freelancer's connected account, watches for the `refund.updated` webhook, and flips the credit note to `succeeded` once Stripe confirms — typically within 3–5 business days for the cash to reach the client.
Stripe Connect Direct Charges mean the original deposit money was charged on the freelancer's connected account (acct_xxx), not the Clozo platform. Refunds therefore must be issued on that same account — Clozo passes stripe_account=connected_account_id on the Refund.create call so Stripe routes it correctly. The refund is then tracked by stripe_refund_id on the credit note row, and a webhook listener on the connected account flips the status to its terminal state when Stripe finishes processing.
Step by step
Client signs the Δ_REFUND amendment.
Post-sign pipeline runs;
_trigger_stripe_refundis called.Credit note moves to
requestedwithin ~2 seconds.The proposal banner reads "Refund in progress" with the credit note number and "Expected in 3–5 business days."
Stripe processes the refund.
Card refunds typically settle in 3–5 business days for the cardholder; bank-account refunds (SEPA Direct Debit) can take 5–7 business days. The connected-account dashboard on Stripe shows the refund in real-time.
Webhook lands.
refund.updatedevent fires when Stripe finalises. Status flips tosucceeded; "refund completed" email goes out to client; proposal closes toPaidif no other obligations.(If proposal was the only outstanding) status returns to
Paid.Otherwise stays in its current state with the refund recorded.
A live "Refund in progress" banner with credit note number + expected window. A Refresh status button (article 8.7) is visible if you want to pull the current state from Stripe instead of waiting for the webhook. Once the refund settles (webhook or pull), the banner switches to a green "Refund completed on [date]" with a link to the credit note PDF. The Documents dropdown's Credit Note row shows status succeeded and a downloadable link.
Why this works this way
Why pull-based sync as a backstop? Webhooks are best-effort. Stripe retries a failing webhook with exponential backoff over 3 days, but if your endpoint is down for that whole window the event is dropped. Worse, sometimes webhook delivery is silently delayed by minutes — the freelancer sees a "Refund in progress" banner that doesn't update, panics, and contacts support. The Refresh status button (article 8.7) lets the freelancer pull the refund state directly from the Stripe API on demand, applying the same apply_refund_state_from_stripe transition logic. This was added per BUG-PROD-009 [D-115] — both push and pull now share a single state machine, eliminating the class of bugs where the UI and reality diverged.
Troubleshooting
Keep reading
Refunds & Notifications
When refunds happen: the Δ_REFUND amendment branches
A refund in Clozo is always tied to a Δ_REFUND amendment branch — partial (revised total smaller than deposit paid) or full (revised total at zero). The amendment is the legal trigger; the refund is the cash consequence.
Refunds & Notifications
Refund stages: issued → requested → succeeded (or manual)
The credit note moves through up to four states from creation to settled. Each state corresponds to a specific point in the refund lifecycle, with predictable UI badges and email triggers.
Refunds & Notifications
Refresh status — pull-based sync when the Stripe webhook didn't land
Webhooks aren't perfect. When a credit note appears stuck in `requested` despite Stripe having processed the refund, click `Refresh status` to pull the current state from Stripe directly. Same transition logic as the webhook; no risk of double-firing side-effects.
Refunds & Notifications
Retry Stripe refund — when transient failures clear
A failed Stripe refund can usually be retried — most failures are transient (rate limits, brief Stripe outages, or deposit-paid webhook arriving after the post-sign pipeline ran). The Retry button calls `_trigger_stripe_refund` afresh on the credit note.
Refunds & Notifications
Failed refunds & recovery — common Stripe failure reasons
A `failed` credit note has a `refund_failure_reason` string from Stripe. Most reasons fall into a small set; here's what each means and the recommended recovery.