Beslutningsguide
Næsten hver SaaS-discovery vi kører ender med det samme spørgsmål: hvordan får vi folk til at betale, og hvordan ved produktet hvem der må hvad? Det lyder som to features. I praksis er det én sammenhængende model — og fejl her koster mere end de fleste UI-beslutninger.
Vi bygger ikke betalinger fra bunden. Vi kobler Stripe, auth og jeres datamodel sammen på en måde I kan eje, debugge og udvide — uden at I vågner op med dobbeltkonteringer, hængende trials eller brugere der ser hinandens data.
TL;DR
De vigtigste pointer
- Stripe håndterer kort, fakturaer og selvbetjening — jeres job er at spejle subscription-status i produktet pålideligt.
- Organisation (workspace/team) skal være kernen i auth fra dag ét, ikke et tillæg når kunde nummer to kommer.
- Webhooks med idempotens er ikke valgfrit. Genleveringer fra Stripe sker — planlæg for dem.
- Customer Portal sparer support-tid: kort, fakturaer og plan-skift hører hjemme hos Stripe, indlejret i jeres UI.
- SSO og avancerede roller kan vente — men org-id på alle rækker kan ikke.
Hvorfor billing og auth hænger sammen
En betalende kunde er sjældent én bruger. Det er en organisation med en admin der købte, en kollega der skal inviteres, og måske en revisor der skal hente fakturaer. Hvis auth-modellen kun kender "bruger", og billing kun kender "Stripe customer", ender I med manuelle fixes hver gang nogen skifter job eller tilføjer et team.
Den model vi anbefaler er enkel at beskrive og svær at retrofitte: hver forretningsentitet tilhører en organisation. Brugere tilhører organisationer via membership med roller. Stripe Customer (eller Subscription) peger på organisationen — ikke på en enkelt bruger, medmindre I bevidst sælger B2C uden teams.
Produktet læser adgang fra jeres database, ikke direkte fra Stripe ved hvert request. Stripe er source of truth for betaling; jeres app er source of truth for hvad brugeren må se og gøre. Synkroniseringen sker via webhooks og en lille, testbar state machine — ikke ad hoc-kald i checkout-flowet alene.
Stripe-mønstre vs. at bygge selv
Proven Stripe-stack
Subscriptions, Customer Portal, webhooks og test-mode — det Stripe har finpudset i årevis.
- PCI: kortdata rører aldrig jeres servere
- Trials, opgraderinger og pro-rata håndteres af Stripe Billing
- Customer Portal til kort, fakturaer og annullering
- Test-mode og fixtures til CI uden rigtige kort
- I ejer forretningslogikken — Stripe ejer betalingsinfrastrukturen
Roll-your-own billing
Egen invoice-motor, manuel kort-håndtering eller hjemmebyggede abonnementer.
- Lang tid før første rigtige betaling går igennem
- Compliance og edge cases (chargebacks, failed payments) bliver jeres problem
- Selvbetjening skal bygges og vedligeholdes
- Svært at skifte pricing-model uden migration
- Typisk kun forsvarligt hvis betaling er kernedifferentiering — det er det sjældent
Den rækkefølge vi anbefaler
Gør det i den her rækkefølge. Spring ikke checkout UI over webhook-håndtering.
- 01
Organisation og membership først
Modellér org, bruger, invitation og roller. Sessionen kender aktiv org. Alt forretningsdata har org-id — også mens I kun har én testkunde.
- 02
Stripe-produkter og priser i dashboard
Opret produkter, priser og evt. trials i Stripe. Hold IDs i config — hardcode ikke beløb i appen. Pricing-ændringer skal kunne ske uden deploy.
- 03
Checkout eller Payment Link til første salg
Få én vej til betaling i produktion tidligt. Checkout Session med client_reference_id eller metadata der binder til org-id. Verificér at success-URL og webhook er enige om state.
- 04
Webhook-endpoint med idempotens
Modtag events, gem event-id, opdatér subscription-status på org. Håndtér invoice.paid, customer.subscription.updated og deleted. Log fejl og dead-letter — genleveringer sker.
- 05
Customer Portal indlejret
Giv admins et sted at opdatere kort og hente fakturaer uden support-ticket. Portal-session oprettes server-side; return URL peger tilbage i produktet.
- 06
Feature gates ud fra plan
Map Stripe price/product til entitlements i jeres DB. Appen tjekker entitlements — ikke Stripe API — på hvert beskyttet kald. Det gør tests og offline-flows enkle.
Auth-leverandør: Auth.js, Clerk eller WorkOS
Valget handler mindre om logoer og mere om hvor I skal hen. Auth.js giver fuld kontrol og lave licensomkostninger — I betaler i implementeringstid og vedligehold. Clerk er hurtigt at komme i gang med for B2C og simple teams. WorkOS er rettet mod B2B med SAML, SCIM og audit — godt når enterprise-kontrakter er på roadmap, ikke når de allerede er signeret.
Uanset leverandør: org og membership skal være jeres domænemodel, ikke kun et felt i auth-provideren. Provideren autentificerer identitet; jeres app autoriserer hvad identiteten må i hvilken org. Bland ikke "logged in" med "må redigere denne tenant".
SSO kan vente til den første kunde kræver det i kontrakten — hvis org-modellen allerede findes. Det der ikke kan vente, er at alle tabeller har org-scope og at I kan forklare i en due diligence hvordan data isoleres.
Spørgsmål vi får igen og igen
Skal vi bruge Stripe Billing eller Stripe Payments alene?
Til SaaS med abonnementer: Billing. Payments alene passer til engangskøb. Billing håndterer trials, fornyelser, failed payments og plan-skift. At bygge subscription-logik oven på engangsbetalinger er den slags projekt der ser simpelt ud i uge én og bliver vedligeholdelsesmareridt i uge tyve.
Hvordan tester vi webhooks lokalt?
Stripe CLI forwarder events til localhost. I kører test-mode keys, simulerer checkout, og assert'er at org-status opdateres idempotent. Tilføj CI-tests der genafspiller gemte event-payloads — ikke kun manuel klik-test i dashboard.
Hvad med usage-based pricing?
Stripe Metered Billing dækker mange modeller. I skal stadig rapportere forbrug pålideligt og mappe det til org. Start ofte med simple planer (flat eller per-seat) og introducér metered når I ved hvad kunderne faktisk forbruger. Kompleks pricing tidligt bremser salg og kode.
Kan én bruger tilhøre flere organisationer?
Ja — og I bør planlægge det, selv hvis v1 kun har én org pr. bruger. Membership som join-tabel med aktiv org i session gør senere konsulenthuse og agentur-scenarier mulige uden auth-rewrite.
Hvornår skal vi have et admin-panel til billing?
Stripe Dashboard er jeres admin-panel i starten. Byg interne værktøjer når support gentagne gange skal gøre det samme manuelt — typisk refund, plan-override eller "denne org skal have trial forlænget". Automatisér det der sker ofte; lad resten være i Stripe.
Skal I have betalinger i produktion?
Lad os tegne billing og auth før I tager imod kort.
Vi gennemgår jeres pricing-model, org-struktur og Stripe-setup — og siger hvad der skal med i v1, og hvad der trygt kan vente.
