Skip to main content

Refunds & Notifications · Article 6.10

Mislukte terugbetalingen & herstel — veelvoorkomende Stripe-mislukkingsredenen

Een `mislukte` creditnota heeft een `refund_failure_reason`-tekenreeks van Stripe. De meeste redenen vallen in een kleine set; hier leest u wat elke reden betekent en de aanbevolen herstelactie.

Mislukte terugbetalingen zijn zeldzaam maar zeer stressvol — de klant verwacht zijn geld, u heeft een addendum ondertekend dat het belooft, en de Stripe-API zei zojuist nee. De meeste mislukkingen passen in een kleine catalogus met bekende herstelacties. Dit artikel bespreekt elke reden op volgorde van frequentie, met de praktische stap om het op te lossen.

Step by step

  1. Lees de mislukkingsreden in de terugbetalingsbanner.

    Deze wordt letterlijk opgeslagen vanuit Stripe; de catalogus hierboven dekt ~90% van wat u zult zien.

  2. Koppel aan de herstelactie.

    Tijdelijk → Opnieuw proberen. Betwist → wachten. Alles anders → overschakelen naar handmatige SEPA.

  3. Voer de terugbetaling buiten het systeem uit indien nodig.

    Mail de klant om IBAN te bevestigen, maak de overboeking, klik op Handmatig als terugbetaald markeren met de bankreferentie.

  4. Bevestig dat de creditnota in handmatig staat (of geslaagd als opnieuw proberen werkte).

    Beide zijn definitief; beide sluiten de creditnota voor boekhoudkundige doeleinden.

  5. Bevestig dat de offerte is gesloten indien van toepassing.

    Wanneer de creditnota wordt vereffend EN geen andere facturen hebben openstaande amount_due, schakelt close_proposal_if_settled de offerte naar Betaald. Als de offerte de enige is met de creditnota, wordt dit automatisch geactiveerd.

Een rode Terugbetaling mislukt-banner met de geciteerde mislukkingsreden, plus de knoppen Opnieuw proberen en Handmatig als terugbetaald markeren. Na herstel schakelt de banner groen ("Terugbetaling voltooid via Stripe" of "Terugbetaling voltooid via handmatige overboeking").

Why this works this way

Stripe geeft mislukkingsredenen weer via het failure_reason-veld van het Refund-object. We leggen het vast op CreditNote.refund_failure_reason (afgekapt tot 500 tekens) wanneer _trigger_stripe_refund een uitzondering genereert of wanneer de webhook status: "failed" rapporteert. De redentekenreeks wordt letterlijk weergegeven in de terugbetalingsbanner zodat u erop kunt handelen zonder Stripe-logs te doorzoeken.

### Mislukkingscatalogus

#### charge_disputed

Wat het betekent: de oorspronkelijke voorschotcharge heeft een openstaand geschil (de bank van de kaarthouder heeft een terugboeking aangevraagd). Stripe blokkeert terugbetalingen op betwiste charges om dubbele betaling te voorkomen.

Herstel: wacht tot het geschil is opgelost (doorgaans 30–90 dagen). Als u het geschil wint, blijft de charge verrekend en kunt u de terugbetaling opnieuw proberen. Als u verliest, heeft de kaarthouder het geld al ontvangen via de terugboeking — de Stripe-terugbetaling is niet meer nodig; markeer de creditnota handmatig als terugbetaald met reden "Terugboeking gewonnen door kaarthouder — geld teruggestort via geschil" zodat uw audittraject klopt.

#### balance_insufficient

Wat het betekent: het saldo van uw Stripe-account (of het saldo van het verbonden account, bij Direct Charges) is lager dan het terugbetalingsbedrag. Gebruikelijk wanneer u de meeste platformmiddelen naar uw bank heeft overgeboekt.

Herstel: top het verbonden account bij door in het Stripe-dashboard lopende uitbetalingen te verminderen, OF voer de terugbetaling buiten het systeem via SEPA uit (sneller) en markeer handmatig als terugbetaald. Stripe herprobeert niet automatisch wanneer uw saldo herstelt; de terugbetaling is permanent mislukt totdat u het opnieuw probeert vanuit Clozo.

#### card_account_closed / expired_or_invalid_card

Wat het betekent: de kaart van de kaarthouder is niet meer geldig (gesloten account, verlopen kaart, vervangen kaart met hetzelfde nummer maar ander CVV). Stripe plaatst de terugbetaling in de wachtrij en kan uiteindelijk slagen als de bank van de kaarthouder kaartupdate-services heeft, maar de timing is onvoorspelbaar (dagen tot nooit).

Herstel: niet wachten. Mail de klant, vraag om een SEPA-ontvangend bankrekening, voer de terugbetaling via SEPA uit, markeer handmatig als terugbetaald met reden "Originele kaart gesloten — terugbetaald via SEPA naar IBAN XXXX." Dit is veruit de meest voorkomende niet-tijdelijke mislukking en het handmatige pad is de schoonste herstelactie.

#### lost_or_stolen_card

Wat het betekent: de kaarthouder heeft de kaart gemeld als verloren of gestolen nadat hij u betaalde. Stripe blokkeert terugbetalingen om te voorkomen dat geld naar een gecompromitteerd account gaat.

Herstel: hetzelfde als bij gesloten kaart — schakel over naar SEPA, vraag de klant om een doel-IBAN. Documenteer dit expliciet in de creditnotreden ("Originele kaart gemeld als verloren/gestolen — terugbetaald via SEPA naar geverifieerd IBAN").

#### Generiek failed zonder specifieke reden / Stripe API-storing

Wat het betekent: tijdelijk of ongedocumenteerd. Kan een tijdelijk Stripe-probleem zijn, een netwerkstoring aan onze kant of een subtiel accountconfiguratieprobleem.

Herstel: probeer eenmalig opnieuw na 30 seconden (artikel 8.8). Als het opnieuw mislukken op dezelfde manier, schakel dan over naar handmatige SEPA + markeer als terugbetaald. Schakel ondersteuning in als dit u blokkeert — we duiken in de logs van Stripe om de onderliggende oorzaak te identificeren.

Troubleshooting

Keep reading

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

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

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.

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

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.