Spring til indhold
SaaSIndsigter

Stripe, billing og org-auth — hvad I skal have på plads før første betalende kunde

Betalinger og login hører sammen — behandl dem som én arkitekturbeslutning.

Billing og auth er det første sted et SaaS-produkt bliver dyrt at rette op på bagefter. Her er hvordan vi tænker Stripe, organisationer og selvbetjening sammen — uden at genopfinde det Stripe allerede har løst.

5 minutters læsning
Diagram over et SaaS-billing-flow: bruger, organisation, Stripe subscription og webhook der synkroniserer adgang i produktet.

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

Hvorfor vi skrev den her

Det er sådan vi tænker — og det er det vi bygger.

Vores indsigter handler om det vi rent faktisk leverer. Hvis det her ramte noget du arbejder med, så er der en konkret service der ligger tæt på.