Skip to content

Billing & Subscriptions

OWNER: aimee ALSO_USED_BY: anna (implementation), eric (contract terms), faye, sytske

Billing architecture must be flexible from day one. Changing pricing models after launch is expensive (80-120 hours). Build the metering and plan infrastructure to support model changes without rewriting the billing layer.


Pricing Model Selection

SCOPE_ITEM: pricing_model_selection

Seat-Based (Per-User)

INCLUDES: Fixed price per user per month/year INCLUDES: Seat count updated when users added/removed INCLUDES: Simple for buyers to understand and budget INCLUDES: Revenue scales linearly with team size

Best for: Collaboration tools, project management, CRM, team communication Market trend: 67% of SaaS uses seat components, but pure per-seat is declining CHECK: AI agents reduce seat count — if product automates work, seats may shrink

Usage-Based (Consumption)

INCLUDES: Pay per unit consumed (API calls, storage, messages, records, compute) INCLUDES: Requires real-time metering infrastructure INCLUDES: Fair — customers pay for what they use INCLUDES: Revenue scales with product value delivered

Best for: API products, AI tools, infrastructure services, data platforms Market trend: 38% adoption and growing fast. ~8% faster revenue growth. CHECK: Usage-based requires metering pipeline — budget 40-80 hours CHECK: Customers need usage dashboards and alerts — not just a surprise invoice

Tiered (Feature-Based)

INCLUDES: Fixed plans with different feature sets (Free, Starter, Pro, Enterprise) INCLUDES: Clear upgrade path as customer needs grow INCLUDES: Predictable revenue per tier INCLUDES: Feature flags control tier access

Best for: Products with clear feature progression (basic → advanced) CHECK: Tier boundaries must feel fair — never gate critical features behind expensive tiers

Hybrid (Subscription + Usage)

INCLUDES: Base subscription fee (per-seat or flat) + usage-based component INCLUDES: Predictable base revenue + upside from heavy users INCLUDES: Example: $20/seat/month + $0.01 per API call over 10k INCLUDES: Most successful SaaS model in 2026

Best for: Most B2B SaaS products Market trend: 43-61% adoption, ~21% median revenue growth (vs. 13% pure subscription) CHECK: Hybrid is the recommended default — confirm with client during scoping

Decision Matrix

IF: Product value tied to team size (everyone uses it daily) THEN: Seat-based or hybrid (seats + usage) IF: Product value tied to throughput (API calls, data processed, jobs run) THEN: Usage-based or hybrid (base + usage) IF: Product has clear feature tiers with natural upgrade triggers THEN: Tiered with optional usage component IF: Client uncertain about pricing THEN: Build hybrid infrastructure, launch with simplest model, iterate


Subscription Lifecycle

SCOPE_ITEM: subscription_lifecycle

State Machine

trialing → active → past_due → cancelled → expired
                  → cancelled (voluntary)
trialing → expired (no conversion)
State Description User Access Billing
trialing Free trial period (14 or 30 days) Full access to trial features No charge
active Paying customer Full access per plan Recurring charge
past_due Payment failed, retry in progress Full access (grace period) Retry 3x over 14 days
cancelled Customer cancelled, period not yet ended Full access until period end No future charges
expired Trial ended without conversion or final period ended Read-only or locked No charges

INCLUDES: State transitions trigger webhook events to application INCLUDES: Past_due → automatic dunning emails (day 1, 7, 14) INCLUDES: Cancelled → "we're sorry to see you go" email with feedback survey INCLUDES: Expired → "your data is safe for 90 days" email with reactivation link CHECK: Grace periods and retry schedules are configurable per payment provider CHECK: Never delete data immediately on cancellation — 90-day retention minimum

Proration

SCOPE_ITEM: subscription_proration INCLUDES: Upgrade mid-cycle: charge prorated difference immediately INCLUDES: Downgrade mid-cycle: credit applied to next invoice INCLUDES: Seat addition mid-cycle: prorated charge for remaining days INCLUDES: Seat removal mid-cycle: credit on next invoice (no immediate refund) CHECK: Both Mollie and Stripe handle proration — Stripe automatically, Mollie requires more custom handling CHECK: Always show the customer the prorated amount before confirming change


Payment Provider Selection

SCOPE_ITEM: payment_provider

Mollie (EU/NL Default — PRIMARY)

INCLUDES: iDEAL (dominant NL payment method — 70%+ of NL online payments) INCLUDES: SEPA Direct Debit INCLUDES: Credit card (Visa, Mastercard) INCLUDES: Bancontact (Belgium), Sofort (Germany), EPS (Austria) INCLUDES: Recurring payments via SEPA mandate INCLUDES: Invoicing integration INCLUDES: Webhook events INCLUDES: PCI DSS Level 1 compliance

Fees: iDEAL EUR 0.29 flat, CC 1.8% + EUR 0.25 (EU) CHECK: Mollie is the PRIMARY payment provider for all NL/EU products (NL-headquartered) CHECK: Mollie's subscription management is less mature than Stripe — more custom code needed for complex billing

Stripe (International Secondary)

NOTE: US-based service. Use only if client explicitly requires international coverage beyond EU. EU data sovereignty risk.

INCLUDES: Subscription management (plans, prices, coupons) INCLUDES: Usage metering (Stripe Meters + Meter Events API) INCLUDES: Invoicing (automatic + manual) INCLUDES: Customer Portal (self-service billing management) INCLUDES: Stripe Tax (automated tax calculation) INCLUDES: Stripe Connect (marketplace payments, if needed) INCLUDES: Webhook events for all billing state changes INCLUDES: PCI DSS Level 1 compliance (no raw card data touches our servers)

Fees: 1.5% + EUR 0.25 (EU cards), 3.25% + EUR 0.25 (non-EU cards) CHECK: Stripe only as secondary for global products with significant non-EU customer base

Mollie vs Stripe — When to Choose

Mollie is always the starting point for EU/NL products. Stripe is only added when the product has a significant global footprint.

Decision

IF: Product targets NL/EU market (default) THEN: Mollie (PRIMARY — NL-headquartered, EU data sovereignty) IF: Product targets global market with significant non-EU customers THEN: Mollie primary + Stripe secondary (NOTE: Stripe is US-based — EU data sovereignty risk) IF: Product is exclusively non-EU THEN: Stripe (with sovereignty warning to client)


Implementation Patterns

Payment Provider Integration (GE Stack)

SCOPE_ITEM: payment_provider_integration NOTE: Examples below use Stripe API conventions. Mollie integration follows similar patterns with Mollie-specific API calls. Choose provider per the decision matrix above.

INCLUDES: stripe npm package (server-side only — never expose secret key to client)
INCLUDES: Stripe Customer created on org creation (1:1 mapping, tenant_id in metadata)
INCLUDES: Stripe Subscription created on plan selection
INCLUDES: Stripe Price objects for each plan variant (monthly, annual)
INCLUDES: Stripe Webhook endpoint (/api/webhooks/stripe) for event processing
INCLUDES: Webhook signature verification (stripe.webhooks.constructEvent)
INCLUDES: Idempotent webhook processing (deduplicate by event ID)

Webhook Events to Handle

SCOPE_ITEM: stripe_webhook_events
INCLUDES: customer.subscription.created — activate org subscription
INCLUDES: customer.subscription.updated — plan change, seat change
INCLUDES: customer.subscription.deleted — mark as cancelled
INCLUDES: invoice.payment_succeeded — record payment, send receipt
INCLUDES: invoice.payment_failed — mark as past_due, trigger dunning
INCLUDES: customer.subscription.trial_will_end — send trial ending email (3 days before)
INCLUDES: checkout.session.completed — initial signup payment completed

CHECK: Always verify webhook signatures — unsigned webhooks are a billing fraud vector CHECK: Process webhooks idempotently — Stripe retries, so you may receive duplicates CHECK: Webhook endpoint must return 200 within 10 seconds — do heavy processing async

Usage Metering (Stripe)

SCOPE_ITEM: stripe_usage_metering

INCLUDES: Define Stripe Meter for each usage metric (API calls, storage, messages)
INCLUDES: Report usage via Stripe Meter Events API (real-time or batched)
INCLUDES: Stripe aggregates usage and includes on next invoice
INCLUDES: Usage dashboard reads from Stripe reporting API (or local metering DB)
INCLUDES: Usage alerts: application tracks thresholds and sends notifications

CHECK: Stripe metering has ~5 minute delay — show local meter for real-time UX CHECK: Batch usage reports hourly to reduce API calls (Stripe rate limits apply)


Invoicing

SCOPE_ITEM: invoicing INCLUDES: Automatic invoice generation on each billing cycle INCLUDES: Invoice includes: line items, taxes, total, payment status, org details INCLUDES: Invoice PDF generation (Stripe auto-generates or custom template) INCLUDES: Invoice sent via email automatically INCLUDES: Invoice history accessible in billing portal INCLUDES: Credit notes for refunds and adjustments OPTIONAL: Custom invoicing for enterprise (manual approval, PO numbers, NET-30 terms) COMPLIANCE: Invoice must include VAT number (if EU B2B), company registration, address CHECK: EU B2B invoicing requires reverse charge mechanism for cross-border transactions


Tax Handling

SCOPE_ITEM: tax_handling INCLUDES: VAT calculation for EU customers (standard rate per country) INCLUDES: Reverse charge for EU B2B customers (0% VAT with valid VAT ID) INCLUDES: VAT ID validation (EU VIES system) INCLUDES: Tax-exempt handling for non-EU customers INCLUDES: Tax included or excluded (configurable, EU shows inclusive, US shows exclusive) OPTIONAL: Stripe Tax for automated multi-jurisdiction tax calculation COMPLIANCE: VAT registration required if selling to EU consumers above threshold CHECK: Tax compliance is the client's legal responsibility — GE builds the infrastructure CHECK: Budget 20-40 hours for tax implementation if multi-country sales expected


Revenue Recognition

SCOPE_ITEM: revenue_recognition INCLUDES: Deferred revenue tracking (annual plans recognized monthly) INCLUDES: MRR calculation (Monthly Recurring Revenue) INCLUDES: ARR calculation (Annual Recurring Revenue) INCLUDES: Expansion revenue tracking (upgrades, seat additions) INCLUDES: Contraction revenue tracking (downgrades, seat removals) INCLUDES: Churn tracking (logo churn + revenue churn) OPTIONAL: Integration with accounting software (Exact Online (NL), Moneybird (NL) preferred. QuickBooks (US) only if client explicitly requires — US-based, EU data sovereignty risk.) CHECK: Revenue recognition is an accounting requirement — not optional for funded startups CHECK: Stripe Revenue Recognition add-on handles ASC 606 compliance


Plan Configuration

SCOPE_ITEM: plan_configuration

Plan Structure

INCLUDES: Table `plans` — id, name, slug, description, stripe_product_id, features (JSONB)
INCLUDES: Table `plan_prices` — id, plan_id, interval (month/year), amount_cents, currency, stripe_price_id
INCLUDES: Table `plan_limits` — id, plan_id, feature_key, limit_value (e.g., max_users: 10)
INCLUDES: Table `tenant_subscriptions` — tenant_id, plan_id, stripe_subscription_id, status, current_period_start, current_period_end

Feature Gating

SCOPE_ITEM: feature_gating
INCLUDES: Feature flags per plan (plan.features JSONB)
INCLUDES: Middleware: requireFeature('advanced_reporting')
INCLUDES: UI: conditionally render features based on plan
INCLUDES: Upgrade prompts when user hits plan limit
INCLUDES: Soft limits (warn at 80%, block at 100%) vs. hard limits (block immediately)

CHECK: Feature gating must be server-enforced — never client-side only CHECK: Upgrade prompts are conversion opportunities — design them well


Free Tier / Freemium

SCOPE_ITEM: free_tier INCLUDES: Permanent free plan with limited features INCLUDES: No credit card required for free plan INCLUDES: Free plan limits clearly communicated (X users, Y records, Z storage) INCLUDES: Upgrade prompts at limit boundaries INCLUDES: Free plan users still create Stripe Customer (for seamless upgrade) OPTIONAL: Free trial of paid plan features (14-day, credit card optional) CHECK: Free tier is a growth strategy — not all B2B SaaS needs it CHECK: If no free tier, use time-limited trial instead (14 or 30 days)


Billing Portal

SCOPE_ITEM: billing_portal

Self-Service (Stripe Customer Portal)

INCLUDES: Plan management (view current plan, upgrade, downgrade) INCLUDES: Payment method management (add, remove, set default) INCLUDES: Invoice history and PDF download INCLUDES: Cancel subscription (with feedback survey) INCLUDES: Update billing contact information

CHECK: Stripe Customer Portal covers 80% of needs — use it as default CHECK: Customize portal appearance to match client's brand

Custom Billing UI (Only If Needed)

IF: Client needs custom billing experience beyond Stripe Portal THEN: Budget 60-100 hours for custom billing pages

INCLUDES: Custom plan comparison page with upgrade/downgrade CTAs
INCLUDES: Custom payment method management
INCLUDES: Custom usage dashboard with charts
INCLUDES: Custom invoice list with filtering and search
INCLUDES: Custom cancellation flow with retention offers

Dunning (Failed Payment Recovery)

SCOPE_ITEM: dunning INCLUDES: Automatic payment retry schedule (day 1, 3, 5, 7, 14) INCLUDES: Email notifications on each failed attempt INCLUDES: In-app banner: "Payment failed — update your payment method" INCLUDES: Grace period: full access for 14 days after first failure INCLUDES: After grace period: downgrade to free tier or read-only access INCLUDES: After 30 days past_due: cancel subscription, notify org admin OPTIONAL: Smart retry timing (Stripe Smart Retries — AI-optimized retry schedule) CHECK: Dunning recovers 15-30% of failed payments — never skip it CHECK: Dunning emails must be polite, clear, and include direct link to update payment


Coupons and Credits

SCOPE_ITEM: coupons_and_credits INCLUDES: Coupon codes (percentage off or fixed amount, duration: once/repeating/forever) INCLUDES: Coupon redemption at checkout INCLUDES: Account credits (applied before charge on next invoice) INCLUDES: Referral credits (give $X to referrer and referee) OPTIONAL: Volume discounts (automatic pricing tiers based on usage) CHECK: Coupons in Stripe are immutable once created — plan coupon strategy carefully