Refunds & Notifications ยท Article 6.3
SEPA / out-of-band refund: when automation can't help
When the original deposit was paid via SEPA bank transfer (or any non-Stripe channel), Clozo can't refund automatically โ Stripe API has nothing to refund. You issue the SEPA transfer manually from your bank, then click `Mark refunded` to update the credit note and notify the client.
SEPA bank transfers are common in the EU, particularly Germany, the Netherlands, and Austria where bank-account-to-bank-account payment is routine for B2B. Clozo supports SEPA on the original deposit via the EPC QR code on the deposit invoice โ but Stripe has no role in that transaction, so when a refund is needed on a SEPA-paid deposit, Stripe can't do anything. The flow falls back to manual: you transfer the funds, then record the transfer in Clozo so the credit note reflects reality and the client gets confirmation.
Step by step
Receive the post-sign trigger.
After the client signs the ฮ_REFUND amendment, the credit note appears with status
pendingand reason "Manual freelancer payout required."Look up the client's IBAN.
Either from your records (if you stored it during the original SEPA deposit), from the deposit-invoice email (the client sent you the funds; their IBAN is on the bank statement), or by emailing the client to confirm the destination IBAN is the same one they used to pay.
Issue the SEPA transfer from your bank.
Use the credit note number as the reference (e.g., "Refund CRN-2026-0007"). Most EU banks process SEPA same-day or next business day; cross-border SEPA Instant is often within seconds.
Click
Mark refundedon the credit note.From the proposal page's Refund banner, the credit notes page (
/credit-notes), or the Documents dropdown's credit note row.Provide a reason.
Minimum 1 character; typical: bank reference number ("Sparkasse ref 9XK7-2026-0511") or a short note. This is stored permanently on the credit note row.
Confirm โ credit note moves to
manual.Email goes out to client; proposal closes to
Paidif applicable.
The Refund banner shows "Manual refund initiated" with credit note details, your bank account masked, and a Confirm Refund Completed button. After clicking and providing a reason, the banner switches to "Refund completed via manual transfer on [date]" with the reason text inline.
Why this works this way
The handoff happens inside _trigger_stripe_refund (amendment_postsign.py:472):
``
if not payment:
credit_note.refund_status = REFUND_PENDING
credit_note.refund_failure_reason = (
"No Stripe PaymentIntent found โ likely SEPA flow. "
"Manual freelancer payout required."
)
``
This sets up the credit note to display the manual-refund UI. The proposal banner reads "Manual refund initiated โ confirm bank transfer" with the credit note details and a CTA to mark the refund completed.
The freelancer-side action (CreditNoteMarkRefundedView in amendment_views.py:686):
1. Validate the credit note isn't already succeeded (idempotent โ return 409 if it is).
2. Require a reason field in the body (1โ500 chars) โ typically a bank reference number, payout date, or short note. Stored as manual_refund_reason for audit.
3. Set refund_status=manual, refund_completed_at=now, save.
4. Call close_proposal_if_settled to flip the proposal to Paid if no other obligations remain.
5. Enqueue send_credit_note_refund_completed_email โ same email template as the Stripe-refund-completed path; the client's experience is identical.
The manual status (vs succeeded) preserves the audit distinction: succeeded means Stripe webhook confirmed; manual means the freelancer attests the refund was issued out-of-band. Both close the credit note for accounting purposes; only the audit trail tracks the difference.
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
Mark refunded manually โ for SEPA and out-of-band proof
When a refund is issued outside Stripe โ SEPA bank transfer, cash, PayPal, mailed cheque โ `Mark refunded` is how you record it in Clozo. Reason field is mandatory (typically a bank reference). The credit note moves to `manual` status and the client receives a confirmation email.
Refunds & Notifications
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.
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.