Een abonnement is geen incasso. Het is een reeks statusovergangen: een contract geeft recht op een entitlement, een renewal maakt een factuur, een betaalpoging verandert de incassostatus, een payout bundelt geldstromen en een refund of chargeback kan weken later nog teruggrijpen op dezelfde verkoop.
Als je alleen kijkt of de maandelijkse incasso is gelukt, kun je tegelijk toegang verlenen zonder betaalde factuur, omzet boeken zonder geld, of een payout als bewijs gebruiken terwijl er nog een chargeback openstaat. Deze gids bouwt de volledige keten voor een abonnementenbedrijf dat contract, betaling, boekhouding en klanttoegang aantoonbaar op elkaar wil laten aansluiten.
Ik heb de genoemde API-documentatie, productdetails en prijskaarten gecontroleerd op 29 september 2026. Waar een productversie of prijs staat, is die datum het controlemoment.
Abonnementsreconciliatie is het gecontroleerd vergelijken van de levenscyclus van een abonnement met de financiële en operationele gevolgen ervan. Je koppelt contract, entitlement, renewal, proratie, factuur, betaalpoging, refund, chargeback en payout via duurzame sleutels, bronhouders en statussen. Een regel is pas klaar wanneer het geld, de boeking en het gebruiksrecht naar hetzelfde bewijs verwijzen.
Een goede inrichting maakt dus niet één statusveld groen. Ze laat zien welk onderdeel groen is, welk onderdeel nog wacht en waar een mens moet beslissen.
Wat heb je nodig om abonnementen te reconciliëren?
Begin met eigenaarschap, niet met een webhook. Stripe Billing kan abonnementen, facturen, betaalpogingen en entitlements beheren, maar het boekhoudpakket blijft de bron van de boeking en je eigen systeem moet de relatie tussen die objecten bewaren. Gebruik Stripe als concreet referentieplatform in deze gids. Dezelfde ontwerpkeuzes gelden voor Mollie, Adyen of een eigen incassolaag.
Leg dit klaar:
- Een betaal- en abonnementsplatform. Stripe Billing levert onder meer de objecten
Subscription,Invoice,PaymentIntent,Charge,Refund,DisputeenPayout. Voor Mollie zijncustomer,mandate, recurring payment en settlement report de vergelijkbare bouwstenen. Kies één platform als bron voor de feitelijke geldactie. - Een entitlementbron. Dat kan Stripe Entitlements zijn of een eigen tabel. Bewaar per klant of account welke functie actief is, vanaf wanneer, tot wanneer, door welk product en welk abonnement die toegang is ontstaan. Een betaalde factuur en een actief gebruiksrecht zijn verwant, maar niet hetzelfde record.
- Een boekhoudpakket met API. Moneybird heeft in zijn actuele API verkoopfacturen, betalingen, creditfacturen en een
subscription_idop het factuurrecord. Exact Online heeft vergelijkbare verkoopfactuur- en financiële routes, maar de juiste endpointkeuze hangt af van je administratie en tenant. Laat de boekhouder het dagboek, btw-model en de tussenrekening voor de betaalprovider vastleggen. - Een duurzame verwerkingslaag. Een eigen service, een database achter n8n of een zorgvuldig begrensde Make-flow is bruikbaar voor de orkestratie. Workflowgeschiedenis alleen is geen audit trail. Bewaar snapshots, event-ID’s, sleutels, foutmeldingen, beslissingen en versies in een opslag die je kunt teruglezen.
- Een uitzonderingsqueue. Iedere onduidelijke status, dubbele gebeurtenis, afwijkend bedrag, ontbrekende factuur, refund zonder parent charge en chargeback met een lopende refund krijgt een kaart met reden, eigenaar, bewijs, deadline en volgende actie.
- Toegang en mandaat. Je hebt API-sleutels, webhook signing secrets, boekhoudrechten, een geheimenkluis en minimaal één medewerker nodig die een refund, creditnota, afboeking of vrijgave mag goedkeuren. De persoon die een regel invoert, mag niet stilzwijgend zijn eigen financiële correctie goedkeuren.
- Een testperiode. Neem minstens één volledige maand aan proefdata mee met nieuwe abonnementen, verlengingen, een upgrade halverwege de periode, een mislukte betaalpoging, een deelrefund, een chargeback, een payout met kosten en een dubbele webhook.
- Een sluitingsafspraak. Noteer wie op welke dag de maand afsluit, welke statussen nog open mogen staan en wie een afwijking accepteert. Zonder stopregel blijft de queue groeien en wordt reconciliatie een maandelijkse speurtocht.
De minimale bronhouderkaart ziet er zo uit:
| Veld | System of record | Verantwoordelijke |
|---|---|---|
| Contract, product, prijs-ID en abonnementsperiode | Stripe Billing | Billing owner |
| Entitlement en toegangsperiode | Eigen entitlementregister | Product owner |
| Factuurregels: omschrijving, hoeveelheid, prijs en periode | Stripe Billing | Billing owner |
| Btw-basis, btw-bedrag en tax jurisdiction | Stripe Tax | Tax owner/accountant |
| Btw-code- en grootboekmapping | Moneybird-administratie | Accountant |
| Verkoopfactuur, creditnota en boekingsstatus | Moneybird | Finance owner |
| Betaalstatus, PaymentIntent en Charge | Stripe Payments | Payments owner |
| Refund en Dispute | Stripe Payments | Support-/risk owner |
| Payout, fee en Balance Transactions | Stripe Balance/Payouts | Finance owner |
| Reconciliatiestatus en uitzonderingsbewijs | Reconciliatie-database | Reconciliation owner |
Dezelfde scheiding tussen bron, geldactie en boeking voorkomt fouten bij deelrefunds waarbij orderregel, creditnota, betaling en match apart blijven. Bij abonnementen komt daar nog de entitlement bij, omdat toegang een operationeel gevolg is en geen bewijs dat de factuur betaald is.
Stripe Billing rekent op de actuele prijspagina voor pay-as-you-go 0,7% van het Billing-volume, exclusief losse eenmalige facturen. n8n Cloud Starter staat op 20 euro per maand bij jaarlijkse betaling voor 2.500 workflowuitvoeringen, en Pro op 50 euro voor 10.000 uitvoeringen. Make toont op de actuele prijspagina een gratis plan met 1.000 credits per maand, Core voor 12 dollar per maand met 10.000 credits, Pro voor 21 dollar en Teams voor 38 dollar. Deze bedragen zijn gecontroleerd op 29 september 2026. Ze zeggen niets over je boekhoudlicentie, bouwtijd, hosting of beheer.
Concrete stappen: van contract naar vrijgegeven geldstroom
Met ketenreconciliatie verbind je contract, entitlement, renewal, incasso, boeking en payout met duurzame sleutels. Je kunt daardoor per euro zien welke periode is verkocht, wanneer toegang mocht starten, welke refund of chargeback volgde en waarom de maandafsluiting wel of niet vrijgegeven wordt. De stappen hieronder maken dat bewijs operationeel.
Volg deze negen stappen in deze volgorde:
1. Modelleer de statussen en sleutels vóór je een koppeling maakt
Modelleer statussen en sleutels. Maak geen tabel met alleen subscription_status. Die status zegt bijvoorbeeld dat een abonnement active is, maar niet of de laatste factuur betaald is, of toegang al is vrijgegeven, of een payout de bijbehorende fee bevat. Maak minimaal deze afzonderlijke statuskolommen:
| Onderdeel | Voorbeeldstatussen | Belangrijke sleutel |
|---|---|---|
| Contract | trialing, active, past_due, unpaid, canceled | subscription_id |
| Entitlement | pending, active, suspended, ended | account_id plus feature_id plus periode |
| Renewal | upcoming, created, finalized, paid, failed | invoice_id en periode |
| Proratie | previewed, applied, credited, not_refunded | invoice_line_item_id |
| Incasso | requires_action, processing, succeeded, failed | payment_intent_id of charge-ID |
| Boekhouding | draft, posted, matched, exception | boekhoud-ID plus factuurnummer |
| Payout | open, reconciled, exception | payout_id |
| Refund | requested, pending, succeeded, failed | refund_id plus parent payment-ID |
| Chargeback | created, under_review, won, lost, funds_reinstated | dispute_id plus parent charge-ID |
Bewaar ook event_id, occurred_at, received_at, processed_at, source_system, correlation_id, valuta, bedrag in de kleinste valuta-eenheid en de gebruikte API-versie. Gebruik nooit een e-mailadres, bedrag of factuurdatum als enige sleutel. Twee klanten kunnen op dezelfde dag hetzelfde bedrag betalen.
Controlepunt: een medewerker kan vanuit een factuurnummer teruggaan naar de subscription, het entitlement, de PaymentIntent, de payout en eventuele refund of dispute zonder in vijf systemen te moeten gokken.
2. Leg contract en entitlement apart vast
Leg contract en entitlement apart vast. Bij de eerste verkoop leg je het contract vast: klant of account, product, price-ID, hoeveelheid, valuta, billing cycle anchor, start- en einddatum, tax context, opzegging en mandate. Leg ook de entitlement vast: account, feature, bronproduct, starttijd, eindtijd en huidige status.
Stripe beschrijft een subscription als een levenscyclus met onder meer trialing, active, incomplete, past_due, unpaid, paused en canceled. Een eerste betaling kan de subscription pas naar active brengen nadat de eerste invoice is betaald. Bij een mislukte eerste betaling kan de subscription na 23 uur incomplete_expired worden en de factuur naar void gaan. Deze statusovergangen zijn gecontroleerd op 29 september 2026.
Verleen toegang niet op basis van een succesvolle checkout-redirect. Gebruik invoice.paid en controleer de actuele subscription- en entitlementstatus. Stripe waarschuwt dat active niet betekent dat iedere openstaande factuur uit de volledige subscriptionhistorie betaald is. Neem dus een expliciete regel op voor de vraag welke openstaande factuur het entitlement blokkeert.
Een bruikbare regel voor een SaaS-product is: nieuwe toegang vereist een betaalde eerste factuur; een bestaande gebruiker houdt toegang tijdens een korte retryperiode; bij unpaid of een verlopen betaaltermijn gaat de entitlement naar suspended; bij een chargeback bepaalt een menselijke risicobeslissing of toegang direct stopt. Zet die regel in code en in het interne beleid. Laat een statusnaam niet de beslissing verbergen.
Controlepunt: je kunt voor één klant aantonen waarom toegang wel of niet actief is, zonder een betaling opnieuw te interpreteren als contractbesluit.
3. Verwerk renewal en proratie als twee verschillende dingen
Scheid renewal en proratie. Een renewal maakt een nieuwe periode en een nieuwe factuur. Een wijziging midden in die periode kan een proratie maken. Leg de oorspronkelijke periode, gewijzigde periode, prijs, korting en berekening vast voordat je het bedrag naar de boekhouding stuurt.
Stripe noemt proratie het naar rato verrekenen van ongebruikte en nieuwe abonnementswaarde. Bij een upgrade van 10 dollar naar 20 dollar halverwege een maand ontstaat in het voorbeeld van Stripe een credit van 5 dollar en een debit van 10 dollar, dus een netto bedrag van 5 dollar. Een negatieve proratie wordt niet automatisch teruggestort en een positieve proratie wordt niet automatisch direct geïnd. Stripe rekent standaard tot op de seconde en laat een proration vooraf bekijken. Deze details zijn gecontroleerd op 29 september 2026.
Sla daarom per proratieregel op:
- oude price-ID, nieuwe price-ID en hoeveelheid;
- begin en einde van de ongebruikte periode;
- proration date en billing cycle anchor;
- toegepaste korting en tax code;
- credit- of debitbedrag;
- invoice line item waarop de berekening terechtkomt;
- beslissing: meenemen op de volgende factuur, direct factureren, apart terugbetalen of blokkeren.
Gebruik een preview voor iedere wijziging die de klant direct geld kost. Als je buiten Stripe rekent, zet de berekening als versieerbare functie vast en bewaar de input. Een maandmodel kan in een offerte begrijpelijk zijn, maar Stripe rekent standaard met seconden. Vermeng die twee rekenregels niet in dezelfde administratie.
Let extra op een onbetaalde vorige factuur. Stripe waarschuwt dat een creditproratie kan worden berekend alsof de eerdere periode nog wordt betaald, terwijl die factuur openstaat. Kies dan bewust voor geen proratie, een directe betaling of het ongeldig maken van de oude factuur. Het systeem mag geen onbetaalde tijd als automatisch klanttegoed behandelen.
Controlepunt: iedere proratie is terug te rekenen naar de oude en nieuwe prijs, de periode, de korting, de btw en de keuze over uitbetaling.
4. Bouw invoice en incasso als een volgorde met tussenstappen
Orden invoice en incasso. Maak de lifecycle zichtbaar in je verwerkingslaag. Voor een automatisch geïnde Stripe-factuur is dit een werkbare volgorde:
invoice.upcomingmaakt ruimte voor een preview, melding of correctie.invoice.createdmaakt het interne renewalrecord aan.invoice.finalizedmaakt de factuur boekbaar, maar nog niet betaald.- De PaymentIntent gaat naar
processing,succeeded,requires_actionofrequires_payment_method. invoice.paidbevestigt dat de factuur betaald is.entitlements.active_entitlement_summary.updatedbevestigt een wijziging in featuretoegang.invoice.payment_failedopent dunning, retry of de uitzonderingsqueue.
Stripe geeft voor subscription-integraties precies dit soort webhookevents omdat de meeste activiteit asynchroon plaatsvindt. invoice.created kan het finaliseren van automatische facturen tot 72 uur vertragen als je endpoint geen succesvolle respons geeft. De subscription-events invoice.created, invoice.finalized, invoice.paid en invoice.payment_failed zijn gecontroleerd op 29 september 2026.
Boek dus nooit omzet of een betaling op basis van invoice.created. Laat een factuur pas na invoice.finalized naar Moneybird of Exact Online gaan, en markeer de openstaande post pas betaald na invoice.paid of een aantoonbaar equivalent van je betaalprovider. De boekingsstatus en de entitlementstatus blijven afzonderlijk.
Bij een mislukte renewal gebruik je invoice.payment_failed voor de communicatie en de queue. Stripe kan Smart Retries of eigen retryregels gebruiken. past_due betekent dat de laatste definitieve factuur niet is betaald of niet kon worden geïnd. unpaid vraagt een expliciete toegangsregel. Eén automatische retry is geen bewijs dat de klant inmiddels heeft betaald.
Controlepunt: in een rapport zie je per renewal precies vier tijden: factuur aangemaakt, factuur gefinaliseerd, betaalpoging afgerond en boeking of entitlement vrijgegeven.
5. Maak webhookontvangst en replay idempotent
Maak ontvangst en replay idempotent. De webhookhandler doet zo weinig mogelijk. Controleer de Stripe-signature op de onbewerkte request body, sla event_id en een hash van de payload op, zet de gebeurtenis op received, antwoord snel met een 2xx en laat een worker het zakelijke effect uitvoeren. Stripe verlangt controle van de signature op de onbewerkte body en een snelle 2xx-respons vóór complexe verwerking, gecontroleerd op 29 september 2026.
Maak daarna twee soorten idempotentie:
- Event-idempotentie: één Stripe-event mag één keer worden verwerkt. Een dubbele levering wordt
duplicate_deliveryen veroorzaakt geen tweede boeking. - Domein-idempotentie: één renewal, refund, creditnota of entitlementmutatie krijgt één eigen sleutel. Een ander event over dezelfde factuur kan een status bijwerken, maar geen tweede financieel object maken.
Voor iedere POST die een object maakt of wijzigt, gebruik je de idempotency key van de provider waar die beschikbaar is. Stripe bewaart het eerste resultaat en geeft bij dezelfde sleutel hetzelfde resultaat terug, ook bij een verbindingsfout. De sleutel mag maximaal 255 tekens zijn en wordt volgens de actuele API-uitleg na ten minste 24 uur automatisch verwijderd, gecontroleerd op 29 september 2026.
Een replay moet dezelfde handler gebruiken als live verkeer. Stripe kan undelivered events automatisch tot drie dagen opnieuw aanbieden en mislukte afleveringen uit de laatste 30 dagen opvragen. Gebruik daarvoor delivery_success=false. Markeer vóór verwerking processing en daarna processed, zodat een handmatige replay en een automatische retry elkaar niet dubbel uitvoeren. Deze procedure is gecontroleerd op 29 september 2026.
De herstelgedachte is dezelfde als bij een SaaS-herstelrunbook waarin providerherstel pas eindigt na backfill, reconciliatie en menselijke vrijgave. Een groene statuspagina is ook hier geen financiële eindstatus.
Controlepunt: dezelfde eventbatch vijf keer uitvoeren verandert tellingen, facturen, entitlements en geldacties niet. Alleen logregels en een replayteller mogen toenemen.
6. Schrijf naar de boekhouding en houd de vrijgave menselijk
Wijs de boekingsverantwoordelijkheid toe. Kies eerst welk systeem welke factuur maakt. Als Stripe Billing de factuurregels, periode en btw-context bezit, laat Moneybird of Exact Online die gegevens verwerken. Laat een losse PSP-connector niet nog eens een verkoopfactuur maken op basis van alleen een geslaagde betaling.
Moneybird beschrijft in zijn actuele API een verkoopfactuur met onder meer subscription_id, state, original_sales_invoice_id, details, payments en btw-totalen. De API biedt een PATCH-route om een verkoopfactuur naar een creditfactuur te dupliceren en routes om betalingen te registreren, gecontroleerd op 29 september 2026.
Maak de boekingsstroom zo:
- Zoek of maak de klant op een stabiele externe klant-ID.
- Maak de verkoopfactuur uit de gefinaliseerde invoice en bewaar invoice-ID plus boekhoud-ID.
- Boek de betaling pas wanneer de PSP bevestigt dat de invoice is betaald.
- Boek proratie als aparte regel met dezelfde periode- en btw-logica.
- Maak bij een refund een creditnota met een expliciete verwijzing naar de oorspronkelijke factuur.
- Laat een menselijke vrijgever afboekingen, afwijkende btw, onbekende betalingen en uitzonderlijk hoge refunds beoordelen.
De Europese Commissie verlangt bij een creditnota een ondubbelzinnige verwijzing naar de oorspronkelijke factuur en de gewijzigde details. De Belastingdienst laat een prijsvermindering, kwijtschelding of ontbinding verwerken in het tijdvak waarin die gebeurtenis plaatsvindt. Laat je accountant de concrete Nederlandse en buitenlandse behandeling bepalen, vooral bij OSS, reverse charge en een vergoeding die door een andere partij wordt betaald. Beide regels zijn gecontroleerd op 29 september 2026.
Controlepunt: een creditnota heeft altijd een oorspronkelijke invoice-ID, een reden, het vrijgegeven bedrag, de btw-code, de refund- of disputecontext en de naam van de vrijgever.
7. Reconcileer payout op transactieniveau, niet op bankbedrag
Reconcileer de payout op transactieniveau. Een payout is een bundel. Hij kan meerdere charges, refunds, chargebacks, fees en andere balance movements bevatten. Het bankbedrag vertelt alleen hoeveel geld naar je rekening ging. Het vertelt niet welke abonnementen betaald zijn.
Gebruik per payout deze sleutelset:
payout_id, valuta, payoutstatus en payoutdatum;- alle
balance_transaction_id-regels; - het bronobject van iedere regel, zoals charge, refund, dispute of fee;
- bruto bedrag, fee, nettopositie en eventuele valutaconversie;
- gekoppelde invoice-ID, customer-ID of dispute-ID;
- matchstatus en reden van een verschil.
Stripe laat je een payout-ID gebruiken om de onderliggende Balance Transactions te filteren en charge, refund, fee en payout uit elkaar te houden, gecontroleerd op 29 september 2026.
Voor Mollie doet het Settlement Report hetzelfde. Het toont in één settlement de inkomsten, refunds, chargebacks, kosten en correcties en kan als CSV, PDF, MT940 of CODA worden geëxporteerd, gecontroleerd op 29 september 2026.
Bereken per payout:
netto payout = charges + positieve correcties - refunds - chargebacks - fees - negatieve correcties
Gebruik de bankregel pas als eindcontrole. Als het saldo afwijkt, zet je de payout op exception en laat je de individuele regels staan. Een afrondingsverschil van één cent kan een bekende oorzaak hebben. Een onbekende refund of chargeback mag nooit onder een algemene tolerantie verdwijnen.
Controlepunt: je kunt elk bedrag op de bankregel terugvinden in een payoutrapport, en elk bedrag in het payoutrapport terugbrengen naar een factuur, refund, chargeback, fee of expliciete correctie.
8. Verwerk refund en chargeback als twee aparte takken
Splits refund en chargeback. Een refund is jouw actie op een geslaagde betaling. Stripe laat volledige en gedeeltelijke refunds toe, meerdere refunds zolang het totaal niet boven de oorspronkelijke charge uitkomt. De refund gebruikt je beschikbare Stripe-saldo en kan bij onvoldoende saldo de status pending krijgen. Een refund kan ook mislukken, bijvoorbeeld wanneer de oorspronkelijke kaart of bankrekening niet meer werkt. Deze details zijn gecontroleerd op 29 september 2026.
Bewaar minimaal payment- of charge-ID, invoice-ID, refund-ID, bedrag, valuta, reden, actiessleutel, vrijgever en status. Boek de creditnota niet als betaald geld. refund.created betekent dat de actie bestaat; refund.succeeded of het provider-equivalent betekent dat het gelddeel verder is gekomen. Voor kaartrefunds kan de klant een ARN, STAN of RRN nodig hebben om de terugbetaling bij de bank te volgen.
Een chargeback is iets anders. De kaarthouder betwist de betaling bij de kaartuitgever, waarna een dispute de betaling en een of meer dispute fees direct uit je Stripe-saldo kan halen. Je moet beslissen of je de dispute accepteert of bewijs indient, gecontroleerd op 29 september 2026.
Bij een fysiek product loopt dezelfde logica door naar ontvangst, conditie, restock en creditnota. Een Shopify-retour die per orderregel wordt geïnspecteerd vóór refund en boeking laat zien waarom een orderstatus alleen te grof is.
Bouw een blokkade tegen dubbel compenseren. Als charge.dispute.created binnenkomt voor een charge waarvoor een refund in pending staat, pauzeer de refund en leg vast wie beslist. Stripe noemt dit expliciet als een situatie waarin een pending refund en een dispute tot dubbele vergoeding kunnen leiden. Een dispute bevat ook bewijsdeadlines en een andere workflow dan een klantrefund.
Controlepunt: één charge kan in je dossier zichtbaar zijn als volledig betaald, gedeeltelijk terugbetaald, betwist of hersteld, maar nooit als twee losse verkopen met twee losse correcties.
9. Voer een koperstest uit en maak de maandafsluiting meetbaar
Voer een koperstest uit. Een technische test zegt dat je events kunt verwerken. Een koperstest zegt of de keten voor finance, support en product begrijpelijk is. Neem dertig opeenvolgende abonnementen uit een testmaand of een geanonimiseerde proefbatch. Laat een tweede persoon zonder hulp uitzoeken:
- welk contract de klant had;
- welke entitlement actief was en waarom;
- welke invoice de renewal vertegenwoordigt;
- welke betaalpoging en welk bedrag daarbij horen;
- welke payout de betaling bevat;
- of er een refund, chargeback of fee was;
- wie een resterend verschil heeft vrijgegeven.
Stel vooraf meetpunten vast:
| Meetpunt | Groene uitkomst | Stopregel |
|---|---|---|
| Records met contract, invoice, payment en boekhoud-ID | 100% | Eén record zonder parent gaat naar de queue |
| Effect van vijf identieke replay-runs | 0 dubbele side effects | Elke duplicatie stopt de livegang |
| Payoutregels verklaard | 100% of expliciet gecorrigeerd | Onbekende regel blokkeert afsluiting |
| Open uitzonderingen ouder dan één werkdag | 0 in de proefbatch | Eigenaar en deadline verplicht |
| Refund of chargeback zonder vrijgave | 0 | Schrijfactie blokkeren |
| Verschil tussen bron- en doelbedrag | 0,00 of benoemde afrondingsreden | Geen tolerantie zonder reden |
De koperstest is geslaagd wanneer alle dertig records in maximaal twee minuten per record uitlegbaar zijn en de tweede persoon dezelfde uitkomst vindt als de eerste. Dat is geen universele norm. Het is een praktische grens om te bewijzen dat je datamodel meer doet dan events verzamelen.
Meet na livegang minstens het percentage automatische matches, de queue-ouderdom, het aantal dubbele events, tijd van invoice.paid tot boeking, tijd van refund tot reconciliatie, aantal payouts met verschil en het aantal entitlements dat actief was zonder betaalde eerste factuur. Geef iedere KPI een eigenaar en een stopregel.
Controlepunt: de maandafsluiting eindigt met een lijst van verklaarde uitzonderingen en een naam onder de vrijgave, niet met een dashboard dat toevallig groen kleurt.
Valkuilen die je cijfers en toegang laten ontsporen
Je gebruikt active als bewijs van betaling
Wat er misgaat: de klant krijgt toegang omdat de subscription actief is, terwijl de laatste invoice openstaat of de betaalmethode nog processing is.
Mitigatie: maak toegang afhankelijk van een expliciete entitlementregel. Gebruik invoice.paid, de subscriptionstatus en het productbeleid samen. Test ook een vertraagde bankbetaling en een past_due-verlenging.
Je behandelt renewal en incasso als één gebeurtenis
Wat er misgaat: een factuur is aangemaakt, maar niet gefinaliseerd of betaald. De boekhouding toont omzet en support zegt dat het abonnement actief is.
Mitigatie: houd created, finalized, paid, failed en requires_action apart. Laat ieder downstream-effect één bronstatus gebruiken.
Je betaalt een negatieve proratie direct terug
Wat er misgaat: een downgrade maakt klanttegoed op de volgende factuur, maar je systeem stuurt ook nog een refund. De klant krijgt dubbel krediet.
Mitigatie: modelleer de keuze credit_on_next_invoice, refund_now of block_for_review als een aparte beslissing. Een negatieve proratie is geen automatische refund.
Je rekent proratie opnieuw met de actuele prijs
Wat er misgaat: een oude korting of prijswijziging verdwijnt, waardoor creditnota en Stripe-factuur niet meer gelijk zijn.
Mitigatie: bewaar price-ID, periode, korting, tax context en de exacte input van de preview. Gebruik dezelfde rekenregel voor factuur, boeking en klantuitleg.
Je verwerkt events in aankomstvolgorde
Wat er misgaat: invoice.paid wordt verwerkt voordat de factuur lokaal bestaat, of een oude customer.subscription.updated overschrijft een nieuwere status.
Mitigatie: gebruik een queue, haal het actuele object op bij ontbrekende context en vergelijk occurred_at of de actuele bronversie. Een event is een trigger, niet automatisch de volledige waarheid.
Je retry maakt een tweede financiële actie
Wat er misgaat: een time-out na de refund-POST lijkt een fout, waarna een nieuwe sleutel een tweede refund aanmaakt.
Mitigatie: schrijf de domeinsleutel vóór de POST weg, hergebruik dezelfde provider-idempotency key en zoek eerst naar het bestaande object. Verschillende sleutels betekenen voor de provider verschillende opdrachten.
Je matcht de payout op alleen het bankbedrag
Wat er misgaat: fees, chargebacks en refunds worden als verschil of omzet geboekt. De maandtotalen lijken te kloppen terwijl een individuele klantcorrectie ontbreekt.
Mitigatie: haal per payout de onderliggende balance transactions of settlementregels op. Match charge, refund, dispute, fee en correctie afzonderlijk.
Je verwart refund met chargeback
Wat er misgaat: een klant ontvangt een refund terwijl de bank dezelfde charge al heeft teruggedraaid, of een dispute wordt als normale klantvraag behandeld.
Mitigatie: stop bij charge.dispute.created alle openstaande refundacties op dezelfde charge. Geef disputes een evidence-eigenaar en deadline. Bewaar de uitkomst los van de factuurcorrectie.
Je maakt de queue tot een afvalbak
Wat er misgaat: iedere onbekende regel krijgt de status handmatig, maar niemand weet welke actie nodig is. De maandafsluiting wordt een spreadsheet.
Mitigatie: gebruik vaste redenen zoals invoice_missing, duplicate_event, proration_mismatch, payout_unexplained, refund_pending en chargeback_open. Voeg eigenaar, deadline, bewijs en stopreden toe.
Je laat de PSP twee keer factureren
Wat er misgaat: Stripe maakt de invoice, terwijl de betaalconnector op payment_succeeded nog een tweede verkoopfactuur maakt.
Mitigatie: wijs de bron aan. Billing bezit de contractuele factuurregels, de PSP bezit betaling en payout, het boekhoudpakket bezit de boeking. Een payment event mag een bestaande factuur betalen, niet vanzelf een nieuwe verkoop creëren.
Je verliest het btw-anker bij een creditnota
Wat er misgaat: een refund wordt als losse negatieve omzet geboekt zonder verwijzing naar de originele factuur of tax context.
Mitigatie: neem oorspronkelijke invoice-ID, gewijzigde regel, btw-code, landcontext en reden over. Laat grensoverschrijdende correcties vooraf controleren door een accountant.
Beslis-kader: connector, orkestratielaag of maatwerk?
Kies op de zwaarste uitzondering, niet op het gemiddelde aantal renewals. Vijfhonderd identieke maandabonnementen zijn eenvoudiger dan twintig contracten met proratie, meerdere entiteiten, verschillende btw-regels en verplichte vrijgave.
Kies een kant-en-klare koppeling als je één billingplatform, één boekhouding, één betaalprovider en een voorspelbaar factuurmodel hebt. De meeste wijzigingen zijn volledige renewals, refunds zijn zeldzaam en je kunt een uitzondering met één eigenaar handmatig afronden. Controleer vóór aanschaf of de koppeling entitlements, proration line items, meerdere refunds, chargebacks en payout-fees kan bewaren. De knop sync is geen bewijs van die dekking.
Kies Make als dunne orkestratielaag als je vooral meldingen, statusupdates en eenvoudige routes nodig hebt. De actuele Make-prijskaart werkt met credits per moduleactie. Dat is bruikbaar voor een kleine stroom, maar financieel bewijs, idempotentiesleutels en de queue horen in een duurzame datastore buiten één scenario-run.
Kies n8n als je een technische eigenaar hebt, zelf je secrets en opslag wilt beheren en de standaardroute via webhooks, HTTP-requests en een database kunt orkestreren. n8n Cloud rekent op volledige workflowuitvoeringen en niet op elke stap. De actuele Starter-prijs is 20 euro per maand bij jaarlijkse betaling voor 2.500 uitvoeringen; Pro is 50 euro voor 10.000. De Community Edition is self-hosted beschikbaar, maar hosting, back-ups, monitoring en updates blijven jouw verantwoordelijkheid.
Kies een maatwerk-reconciliatieservice als contract, entitlement, factuur, betaling en payout uit verschillende bronnen komen, proratie klantgeld kan verplaatsen, chargebacks een tweede geldactie moeten blokkeren, of een menselijke vrijgave onderdeel van de normale route is. Dan bouw je geen doorgeefluik. Je bouwt een klein transactiesysteem met versieerbare regels, auditspoor, replay en afsluiting.
Mijn beslisregel: als je een afwijking niet kunt beschrijven als bron, sleutel, bedrag, eigenaar en uitkomst, is de automatische route te groot voor de gekozen tool. Breng eerst één maand uitzonderingen in kaart. Een eerlijk handmatig proces is beter dan een automatische route die onbekende geldbewegingen verbergt.
Komen contract, entitlement, betaling en boeking uit één gecontroleerde standaardroute?
Uitgewerkt voorbeeld: één upgrade, één refund en één chargeback
Dit is een fictief rekenvoorbeeld met twee strikt gescheiden klanttrajecten. De eerste aankoop van Atlas is Basic voor €49,00 exclusief btw; €119,00 is uitsluitend de latere Pro-prijs. Zo ontstaat geen sprong van een eerste aankoop van €119 naar Basic. Borea is een tweede klant met een eigen Pro-renewal en eigen chargebackdossier.
Contract, eerste aankoop en btw-basis
Atlas (cus_atlas_2041) kiest op 1 september 2026 de Stripe Price price_atlas_basic_monthly_eur49: €49,00 per maand exclusief btw. De subscription is sub_atlas_2041, de eerste invoice in_atlas_0901, de PaymentIntent pi_atlas_0901 en de Charge ch_atlas_0901. Stripe Billing is de bron van de regel; Stripe Tax berekent 21% Nederlandse btw over €49,00.
| Object | ID | Bedrag | Status |
|---|---|---|---|
| Price | price_atlas_basic_monthly_eur49 | €49,00 excl. btw | gekozen |
| Invoice | in_atlas_0901 | €49,00 basis + €10,29 btw = €59,29 | paid |
| PaymentIntent | pi_atlas_0901 | €59,29 | succeeded |
| Charge | ch_atlas_0901 | €59,29 | succeeded |
| Entitlement | atlas-basic op cus_atlas_2041 | 1–30 september | active |
De Basic-charge is dus €59,29 inclusief btw. Het bedrag van €119,00 hoort nog niet bij Atlas' eerste aankoop.
Upgrade en renewal
Op 16 september wijzigt Atlas binnen dezelfde subscription van price_atlas_basic_monthly_eur49 naar price_atlas_pro_monthly_eur119, een maandprijs van €119,00 exclusief btw. Voor deze leesbare halve-maandberekening rondt de factuur iedere regel af op centen:
| Proratieregel op in_atlas_0916 | Btw-basis | Btw 21% | Incl. btw |
|---|---|---|---|
| resterende Basic-periode: credit | -€24,50 | -€5,15 | -€29,65 |
| resterende Pro-periode: debit | +€59,50 | +€12,50 | +€72,00 |
| Netto upgrade | €35,00 | €7,35 | €42,35 |
De upgrade maakt invoice in_atlas_0916, PaymentIntent pi_atlas_0916 en Charge ch_atlas_0916, alle drie voor €42,35 inclusief btw. Het entitlement wijzigt op 16 september van atlas-basic naar atlas-pro. De nieuwe terugkerende Price-ID is expliciet price_atlas_pro_monthly_eur119; de productie-preview kan bij seconde-precisie enkele centen anders uitkomen, maar die preview wordt dan de vastgelegde bron.
Op 1 oktober maakt de Pro-renewal invoice in_atlas_1001, PaymentIntent pi_atlas_1001 en Charge ch_atlas_1001: €119,00 btw-basis + €24,99 btw = €143,99 inclusief btw. De entitlement blijft actief. De tweede klant, Borea (cus_borea_7712), heeft een eigen Pro-subscription sub_borea_7712, invoice in_borea_1001, PaymentIntent pi_borea_1001 en Charge ch_borea_1001, eveneens €143,99 inclusief btw op dezelfde price_atlas_pro_monthly_eur119. Dit is geen Atlas-record.
Refund en chargeback met eigen parent-ID's
Op 4 oktober meldt Atlas een dubbel berekende upgrade. De medewerker maakt alleen voor Atlas refund re_atlas_1004 aan: €42,35, parent PaymentIntent pi_atlas_0916, parent Charge ch_atlas_0916, invoice in_atlas_0916, status succeeded. De creditnota 2026-00422 corrigeert €35,00 btw-basis en €7,35 btw. Er is dus geen refund op Atlas' Basic-charge of op de Pro-renewal.
Borea betwist juist zijn eigen Pro-renewal: dispute dp_borea_1004 verwijst naar customer cus_borea_7712, invoice in_borea_1001, PaymentIntent pi_borea_1001 en Charge ch_borea_1001, bedrag €143,99. Een eerder verzoek op diezelfde Borea-charge staat als refund re_borea_1004 op pending; het is geen Atlas-refund en heeft nog geen payoutregel. Zodra dp_borea_1004 binnenkomt, zet de reconciliatielaag re_borea_1004 op hold en verstuurt geen tweede refund. De queue bewaart dispute reason, evidence-deadline en eigenaar. De term ‘oorspronkelijke payment’ betekent in dit dossier dus altijd pi_borea_1001 met parent ch_borea_1001.
Payout op transactieniveau
Payout po_atlas_1005 bevat de vier geslaagde charges, Atlas' geslaagde refund, Borea's chargeback en de providerfees. De onderliggende Balance Transactions sluiten als volgt:
| Balance Transaction | Bron | Bedrag | Fee | Netto-effect |
|---|---|---|---|---|
| bt_ch_atlas_0901 | ch_atlas_0901 | +€59,29 | -€1,14 | +€58,15 |
| bt_ch_atlas_0916 | ch_atlas_0916 | +€42,35 | -€0,89 | +€41,46 |
| bt_ch_atlas_1001 | ch_atlas_1001 | +€143,99 | -€2,41 | +€141,58 |
| bt_ch_borea_1001 | ch_borea_1001 | +€143,99 | -€2,41 | +€141,58 |
| bt_re_atlas_1004 | re_atlas_1004 | -€42,35 | €0,00 | -€42,35 |
| bt_dp_borea_1004 | dp_borea_1004 | -€143,99 | €0,00 | -€143,99 |
| bt_fee_borea_dispute_1004 | dispute fee | €0,00 | -€15,00 | -€15,00 |
| Totaal payout | po_atlas_1005 | €389,62 charges | -€21,85 fees | €181,43 |
De sluitende controle is: €59,29 + €42,35 + €143,99 + €143,99 - €42,35 - €143,99 - €1,14 - €0,89 - €2,41 - €2,41 - €15,00 = €181,43. De pending refund re_borea_1004 staat bewust niet in deze som; er is nog geen bt_re_borea_1004. De payout wordt pas reconciled wanneer iedere opgenomen regel naar precies één invoice, charge, refund, dispute of fee terugwijst.
Koperstest
Geef de tweede medewerker beide customer-ID's, de invoices in_atlas_0916 en in_borea_1001, payout po_atlas_1005 en de twee queuekaarten. Die moet kunnen aanwijzen:
- dat Atlas Basic kocht voor €49,00 exclusief btw en pas daarna naar Pro voor €119,00 ging;
- dat Atlas' upgrade-charge ch_atlas_0916 exact €42,35 was en refund re_atlas_1004 daarop ziet;
- dat Borea's chargeback dp_borea_1004 alleen bij ch_borea_1001 en pi_borea_1001 hoort;
- dat de payout €181,43 is en de pending Borea-refund niet is meegeteld;
- wie de creditnota en de dispute heeft vrijgegeven.
Als één antwoord alleen uit een zoekactie in Slack of een spreadsheet komt, ontbreekt nog een duurzame relatie in het datamodel.
Vergelijkingstabel: welke route past bij jouw schaal?
De actuele product- en prijsdetails hieronder zijn gecontroleerd op 29 september 2026. Abonnementen, betaalverwerking, btw-advies, boekhoudlicentie, hosting en bouwtijd kunnen bovenop deze bedragen komen.
| Route | Actuele productbasis en kostenorde | Past bij | Breekpunt |
|---|---|---|---|
| Kant-en-klare koppeling | Stripe Billing pay-as-you-go 0,7% van Billing-volume; boekhoudconnector apart | Eén billingplatform, één administratie, standaardrenewals en weinig uitzonderingen | Proratie, entitlements, meerdere refunds, chargebacks of payoutregels verdwijnen uit beeld |
| Make als dunne orkestratie | Free 1.000 credits per maand; Core 12 dollar per maand voor 10.000 credits; Pro 21 dollar; Teams 38 dollar | Meldingen, statusupdates en eenvoudige route naar een externe queue | Financiële logica, replay en auditspoor worden te groot voor losse moduleacties |
| n8n Cloud of self-hosted | Starter 20 euro per maand jaarlijks voor 2.500 uitvoeringen; Pro 50 euro voor 10.000; Community Edition self-hosted beschikbaar | Technische eigenaar, eigen opslag, HTTP/API-stappen, retries en foutflows | Hosting, back-ups, secrets, versiebeheer en datamodel worden niemand zijn verantwoordelijkheid |
| Maatwerk data-sync | Geen vaste catalogusprijs; service, database, test- en beheerwerk bepalen de kosten | Meerdere bronhouders, geld- en toegangsbesluiten, chargebackblokkade en maandafsluiting | Geen producteigenaar of boekhoudkundige eigenaar voor regels en wijzigingen |
Kant-en-klaar wint wanneer de route echt standaard is. n8n of Make wint wanneer de domeinregels klein blijven en het bewijs buiten de workflow wordt bewaard. Maatwerk wint zodra een refund of chargeback een besluit wordt met gevolgen voor entitlement, factuur, payout en btw.
Een abonnement is uiteindelijk geen rij geslaagde incasso’s. Het is een dossier dat moet kunnen uitleggen waarom iemand toegang had, welke periode is gefactureerd, welk bedrag werkelijk is ontvangen, waarom een correctie is gemaakt en welke payout dat geld bevatte. Als die keten na een replay nog hetzelfde antwoord geeft, heb je geen losse koppelingen meer, maar een controleerbare financiële waarheid.
Veelgestelde vragen
Abonnementenketen laten bouwen?
Ik breng met je in kaart welke bron welk veld bezit, ontwerp de route van contract en entitlement tot payout en bouw de reconciliatie met replay, uitzonderingsqueue en menselijke vrijgave in jouw eigen stack.
Dit artikel is geproduceerd samen met het Agent Team. Meer over de redactie.

