Abonnementen met Stripe toevoegen: plannen, proefperiodes, webhooks en mislukte betalingen
Om abonnementen met Stripe toe te voegen, maak je een product met een terugkerende prijs in het Stripe-dashboard, stuur je klanten vanaf je server naar Stripe Checkout in abonnementsmodus, en laat je een webhook je app vertellen wanneer elke betaling slaagt, mislukt, verandert of eindigt. Sla de abonnementsstatus op bij de gebruiker en geef toegang op basis daarvan, niet op basis van de succespagina. Voeg een knop Facturatie beheren toe die het gehoste klantenportaal van Stripe opent, zodat mensen hun kaart kunnen wijzigen, van plan kunnen wisselen en kunnen opzeggen zonder dat jij die schermen bouwt.
Deze gids bouwt voort op hoe voeg je betalingen toe aan je app, dat eenmalige Checkout, testmodus en live gaan behandelt. Hier richten we ons op wat anders is aan terugkerende facturering. De Stripe-details komen uit de documentatie van Stripe, stand september 2026.
Waarom abonnementen moeilijker zijn dan eenmalige betalingen
Een eenmalige betaling gebeurt terwijl de klant in je app zit. Een abonnement gaat door nadat hij is vertrokken: maandelijkse verlengingen, verlopen kaarten, upgrades halverwege de periode, en opzeggingen die pas aan het einde van de periode ingaan. Je app hoort daar alleen via webhooks van. De meeste bugs in abonnementen ontstaan doordat de eerste betaling als het hele verhaal wordt gezien.
Je opties
| Aanpak | Wat je bouwt | Geschikt voor |
|---|---|---|
| Payment Link met een terugkerende prijs | Alleen een link | Vraag testen; toegang met de hand regelen |
| Checkout (abonnementsmodus) + klantenportaal | Een serverroute, een webhook, een factureringsknop | De meeste SaaS-apps en lidmaatschappen |
| Abonnements-API met je eigen betaalformulier | Veel meer: betaal-UI, authenticatie, nieuwe pogingen | Apps met ongewone factureringsstromen |
| Merchant-of-record-provider | Vergelijkbaar met Checkout | Verkopers die willen dat de provider de btw regelt |
Voor de meeste apps is Checkout plus het portaal de juiste afweging. Vergelijk providers in Stripe vs Paddle vs Lemon Squeezy als belastingafhandeling je zorgen baart.
Plan eerst je prijzen in Stripe
In Stripe is een product wat je verkoopt ("Pro-plan") en een prijs is hoe je het in rekening brengt ("$20 per maand", "$200 per jaar"). Eén product kan meerdere prijzen hebben. Bepaal:
- Welke niveaus je aanbiedt en wat elk niveau in je app ontgrendelt
- Maandelijks, jaarlijks, of beide
- Of je een proefperiode aanbiedt, en of die vooraf een kaart nodig heeft
Maak de producten en prijzen aan in de testmodus en bewaar de prijs-ID's; je app verwijst ernaar. Als je prijzen nog niet vaststaan, lees dan hoe prijs je een SaaS-product en freemium versus gratis proefperiode.
De abonnementslevenscyclus waar je mee moet omgaan
De abonnementsoverzicht van Stripe somt de statussen op die een abonnement kan hebben. De belangrijkste voor toegang:
| Status | Betekenis | Toegang geven? |
|---|---|---|
trialing | In een proefperiode | Ja |
active | In orde | Ja |
incomplete | Eerste betaling nog niet afgerond; Stripe geeft de klant 23 uur | Nee |
incomplete_expired | Eerste betaling is nooit gelukt | Nee |
past_due | Laatste betaling mislukt of niet geprobeerd; nieuwe pogingen kunnen volgen | Aan jou; veel apps geven een korte coulanceperiode |
unpaid | Nieuwe pogingen zijn op, facturen blijven open, er volgen geen pogingen meer | Nee; volgens de documentatie van Stripe moet je toegang intrekken |
canceled | Beëindigd; kan niet worden hervat | Nee |
paused | Een proefperiode is zonder betaalmethode geëindigd en op pauze gezet | Nee |
Sla de status op bij je gebruiker- of accountrecord en baseer de toegang daarop. Werk hem bij telkens wanneer een relevante webhook binnenkomt.
De webhook-gebeurtenissen die je moet afhandelen
| Gebeurtenis | Wat je app doet |
|---|---|
checkout.session.completed | Koppel de nieuwe Stripe-klant- en abonnements-ID's aan je gebruiker |
invoice.paid | Markeer het abonnement als actief en sla het nieuwe periode-einde op |
invoice.payment_failed | Vertel de gebruiker dat de kaart is geweigerd en link naar het portaal |
invoice.payment_action_required | Vraag de gebruiker de kaartauthenticatie af te ronden |
customer.subscription.updated | Werk plan, status en eventuele geplande opzegging bij |
customer.subscription.deleted | Verwijder betaalde toegang |
customer.subscription.trial_will_end | Herinner de gebruiker voordat de proefperiode eindigt; Stripe stuurt dit drie dagen van tevoren |
De regels voor handlers uit de webhookdocumentatie van Stripe gelden nog steeds: controleer de handtekening met de ruwe body, geef snel een 2xx-antwoord, behandel duplicaten en gebeurtenissen die in de verkeerde volgorde komen, en reken op herhalingen. De gids wat is een webhook legt het idee uit, en de betalingsgids zet de regels uitgebreid op een rij.
Stap voor stap
- Maak producten en prijzen aan in de testmodus van Stripe.
- Voeg geheimen toe: de geheime sleutel, de prijs-ID's en later het ondertekeningsgeheim van de webhook. Zet ze nooit in frontendcode.
- Prijspagina: elke knop van een plan roept je server aan, die een Checkout-sessie in abonnementsmodus maakt voor de ingelogde gebruiker. Geef je gebruikers-ID mee, zodat de webhook de betaling aan het account kan koppelen.
- Webhook-endpoint: controleer handtekeningen en verwerk de gebeurtenissen hierboven, en werk per gebruiker één abonnementsrecord bij.
- Bepaal toegang tot functies op basis van de opgeslagen status en het plan, op de server gecontroleerd bij elke beschermde actie, niet alleen met verborgen knoppen.
- Klantenportaal: stel het in het Stripe-dashboard in (naar welke plannen mensen kunnen wisselen, of ze kunnen opzeggen), en voeg een knop Facturatie beheren toe die een portaalsessie op de server maakt en de klant ernaartoe stuurt.
- Mislukte betalingen: kies in de factureringsinstellingen van Stripe het gedrag bij nieuwe pogingen en wat er gebeurt na de laatste poging. Toon een banner in de app zolang de status
past_dueis. - Test de hele levenscyclus, publiceer daarna en registreer de live webhook.
Prompts voor je AI-builder
Voeg abonnementsfacturering met Stripe toe. Plannen: Starter (prijs-ID in STRIPE_PRICE_STARTER) en Pro (STRIPE_PRICE_PRO). De prijspagina maakt op de server een Checkout-sessie in abonnementsmodus aan met STRIPE_SECRET_KEY, met de ID van de ingelogde gebruiker erbij. Sla de Stripe-klant-ID, het abonnements-ID, het plan en de status op bij de gebruiker. Stel de geheime sleutel nooit bloot aan de browser.
Voeg POST /api/stripe/webhook toe. Controleer de handtekening met STRIPE_WEBHOOK_SECRET op basis van de ruwe requestbody. Verwerk checkout.session.completed, invoice.paid, invoice.payment_failed, customer.subscription.updated, customer.subscription.deleted en customer.subscription.trial_will_end. Sla verwerkte gebeurtenis-ID's op zodat duplicaten worden genegeerd. Werk de status van de gebruiker bij op basis van het abonnementsobject, niet op basis van de volgorde waarin gebeurtenissen binnenkomen.
Bepaal toegang tot Pro-functies op de server: sta ze alleen toe als de status active of trialing is en het plan Pro is. Toon een banner "betaling mislukt, werk je kaart bij" als de status past_due is. Voeg een knop Facturatie beheren toe die het Stripe-klantenportaal voor deze gebruiker opent.
Upgrades, downgrades en pro-rata
Als een klant van plan wisselt, maakt die wijziging volgens de documentatie van Stripe vaak een pro-rata-verrekening: de nieuwe prijs wordt toegepast op het rest van de huidige factureringsperiode. Je kunt prorata vooraf bekijken of uitzetten. Als de plannen hetzelfde interval hebben, blijven de factureringsdata gelijk; overstappen van maandelijks naar jaarlijks verplaatst de factureringsdatum naar de dag van de wissel. Als klanten plannen in het portaal kunnen wijzigen, bespaar je het schrijven van deze logica. Bepaal dan wel in de portaalinstellingen welke wisselingen zijn toegestaan.
Testchecklist
Gebruik de testmodus van Stripe en testkaarten, en doorloop elke status:
- Een nieuw abonnement geeft het juiste plan aan de juiste gebruiker
- Het tabblad direct na betalen sluiten geeft nog steeds toegang (dit bewijst dat de webhook werkt)
- Een geweigerde kaart bij aanmelding geeft geen toegang
- Een mislukte verlenging zet het account op past_due en toont de banner
- De kaart bijwerken in het portaal zet de status weer op active
- Upgraden en downgraden wijzigt functies correct
- Opzeggen aan het einde van de periode houdt de toegang tot de einddatum en verwijdert die daarna
- Proefgebruikers krijgen toegang, ontvangen de herinnering en worden correct klant of verliezen de toegang
- Dezelfde webhook-gebeurtenis twee keer versturen verandert niets
De testklokken van Stripe laten je tijd simuleren, zodat je verlengingen kunt testen zonder een maand te wachten. Bekijk de actuele testdocumentatie van Stripe voor hoe je die gebruikt.
Veelgemaakte fouten
- Toegang geven op de succespagina. Klanten kunnen betalen en die pagina nooit bereiken. Gebruik de webhook.
- Alleen de eerste betaling afhandelen. Verlengingen, mislukkingen en opzeggingen komen later binnen als gebeurtenissen.
- Plan-status alleen in de frontend controleren. Iedereen kan je API rechtstreeks aanroepen.
- Per ongeluk meerdere abonnementen voor één gebruiker. Controleer of er al een abonnement is voordat je een nieuwe Checkout-sessie maakt, of stuur bestaande klanten naar het portaal.
- Toegang intrekken bij de eerste mislukte verlenging. Kaarten falen om saaie redenen. Een korte coulanceperiode met een duidelijke banner houdt klanten vast.
- De live webhook vergeten. Test- en live-endpoints hebben verschillende ondertekeningsgeheimen.
- Belasting en terugbetalingen negeren. Bepaal je restitutiebeleid en controleer je belastingverplichtingen met een accountant voordat je lanceert.
Abonnementen in Mythex
Apps die je op Mythex bouwt gebruiken je eigen Stripe-account en sleutels; er is geen one-click Stripe-koppeling voor je app. Voeg je testsleutels en prijs-ID's toe als projectgeheimen, gebruik prompts zoals hierboven, en test met de testkaarten van Stripe in Preview. Webhooks hebben de publieke URL van je app nodig, dus publiceer voordat je het endpoint in Stripe registreert, en publiceer opnieuw nadat je naar live sleutels bent overgestapt, zodat de live-app ze oppikt. Zie betalingen ontvangen met Stripe en webhooks afhandelen in je backend. Voor de rest van het product behandelt hoe bouw je een SaaS-MVP wat je rond facturering moet bouwen.
Veelgestelde vragen
Wat is de eenvoudigste manier om abonnementen met Stripe toe te voegen?
Maak een product met een terugkerende prijs in het Stripe-dashboard, stuur klanten naar Stripe Checkout in abonnementsmodus, verwerk abonnementsgebeurtenissen met een webhook, en koppel een knop Facturatie beheren aan het gehoste klantenportaal van Stripe. Zo bouw je zelf geen kaartformulieren en schermen voor plan-wijzigingen.
Welke Stripe-webhookgebeurtenissen heb ik nodig voor abonnementen?
Minimaal checkout.session.completed om het nieuwe abonnement aan je gebruiker te koppelen, invoice.paid om elke geslaagde betaling te bevestigen, invoice.payment_failed om te waarschuwen bij mislukte verlengingen, en customer.subscription.updated en customer.subscription.deleted om plan-wijzigingen en opzeggingen bij te houden.
Wat gebeurt er als een abonnementsbetaling mislukt?
Volgens de documentatie van Stripe (stand september 2026) wordt het abonnement meestal past_due, en kan Stripe de betaling opnieuw proberen op basis van je instellingen. Na de laatste poging bepalen je dashboardinstellingen of het abonnement wordt opgezegd, als unpaid wordt gemarkeerd of past_due blijft.
Kan ik een gratis proefperiode aanbieden zonder om een kaart te vragen?
Ja. Stripe ondersteunt gratis proefperiodes. In de documentatie staat een paused-status voor proefperiodes die eindigen zonder betaalmethode, als je dat zo instelt. Een kaart vooraf vragen betekent meestal minder aanmeldingen maar meer betalende klanten. Test wat bij je product past.