Context
offplan.online is a self-serve B2B subscription SaaS productising property sales-presentation software. Stage 1 launch targets ~100 live projects across rendering studios (UAE/EU/US) + real estate agents/agencies. Payment provider choice impacts: tax compliance complexity, vendor lock-in, fee structure, UX (Checkout flow), webhook/API surface, multi-currency capability.
Stripe was de-facto chosen across multiple ADRs without explicit ratification:
- ADR 0006 (chargeback auto-freeze) references Stripe webhook
charge.dispute.created. - ADR 0013 (proration policy) uses Stripe primitives
SubscriptionSchedule+proration_behavior: create_prorations. - Sub-plan 2 (
plans/onboarding-trial-mode.md) Pick #14 references Stripe Checkout + Customer Portal. launch-plan-v3.md:798-815still has «Stripe vs Paddle TBD» as open question — this ADR closes that.
CONV-35 user confirmation: «Yes — draft ADR 0017».
Decision
Stripe = Stage 1 payment provider for offplan.online.
Operational stance:
- All payment processing, subscription management, tax calculation, invoice generation routed через Stripe.
- Stripe Tax enabled (
automatic_tax: { enabled: true }on Checkout) — Stripe handles VAT / sales tax / FTA computation based on Customer address + tax IDs. - Stripe Customer Portal = primary self-serve UI для card updates, invoice history, subscription cancellation (Stage 1 minimum scope; expand Stage 2).
- Stripe Checkout Session = primary upgrade flow surface (vs. embedded components — Stage 1 prefers redirect simplicity).
- 8-event webhook subscription для tier state machine (per
plans/onboarding-trial-mode.mdPart 2 Step 3):customer.subscription.created/updated/trial_will_end/deleted·invoice.paid·invoice.payment_action_required·charge.failed·checkout.session.completed. - Multi-currency через single
PriceID сcurrency_options(USD/EUR/AED Stage 1). - API version pin:
2026-01-28.previewдля Customer Portal config endpoint; main API on stable.
Alternatives Considered
- (A) Paddle (Merchant of Record). Defers tax compliance burden to Paddle (Paddle is contractual seller; handles all VAT / sales tax / e-invoicing globally). Trade-off: 5-10% higher platform fees + vendor lock-in (subscription data tied to Paddle account; migration complexity). Rejected Stage 1: financial inflection point ~$250k–$500k ARR — below that, Stripe + manual tax handling cheaper. Revisit при ARR threshold OR jurisdiction-specific compliance ops cost spike.
- (B) Stripe + Paddle hybrid. Stripe for some regions, Paddle for others. Rejected: complexity tax (2× integration + 2× webhook surfaces + 2× reconciliation logic) outweighs benefit at Stage 1 scale.
- (C) Custom billing infrastructure (no provider). Build invoice generation + payment intent + tax calculation in-house. Rejected: 6-12 month engineering investment с substantial compliance + audit risk. Inappropriate Stage 1.
- (D) Chargebee / Recurly / other billing platform. Adds abstraction layer over Stripe. Rejected: unnecessary Stage 1 (Stripe API surface sufficient); cost premium (~$300-1000/mo) not justified; Stripe direct = simplicity.
Consequences
- Phase 1.2 implementation (Sub-plan
plans/onboarding-trial-mode.md) — Stripe API integration во всех subscription flows. Specifics: Checkout Session redirect upgrade · Customer Portal self-serve mgmt · SubscriptionSchedule downgrade ·create_previewendpoint для preview UI. - Phase 1.7.10 (Custom domain self-serve flow + DKIM Tier 2+) — Stripe Tax enables proper invoice content для custom-domain customers. DKIM email sending handled by Phase 1.8 stack (per ADR 0011); Stripe не interferes.
- Phase 1.7.11 (Free tier billing tracking) —
tier: free_guest | trial | tier_1 | tier_2 | tier_3_enterpriseenum в billing schema. Stripe Customer record exists для tier_1+ only (deferred creation per Sub-plan 2 Step 1.1). - ADR 0006 (chargeback auto-freeze) — confirmed Stripe webhook
charge.dispute.createdintegration pattern. - ADR 0008 (tier model) — Stripe Price IDs map к tier slugs (stable IDs). Numbers parked pending Roman input.
- ADR 0013 (proration policy) — confirmed Stripe
proration_behavior: create_prorationsupgrade pattern +SubscriptionScheduledowngrade pattern. v1.1 amendment fixes deprecatedupcoming_invoice→create_previewendpoint. - MoR revisit trigger — ARR > $250k–$500k OR jurisdiction-specific tax compliance ops cost spike (e.g. UAE FTA filing complexity post-jurisdiction lock).
- Closes
launch-plan-v3.md:798-815open question «Stripe vs Paddle TBD». - Jurisdiction-agnostic: ADR works для любой legal entity choice (Cyprus / Abu Dhabi / etc.) — Stripe Tax supports both jurisdictions per 2026 GA. Tax/VAT specifics resolved on jurisdiction lock per memory directive.
Revisit trigger
- ARR threshold $250k–$500k → MoR (Paddle) cost-benefit recalculation.
- Cyprus / UAE / jurisdiction-specific tax compliance ops cost spike (manual filing exceeds Paddle fee premium).
- Competitor analysis shows MoR as meaningful market signal (e.g. category-leading SaaS shift к Paddle for global SaaS sales).
- Stripe outage / reliability concerns sustained > 1 month (multi-provider failover discussion).
Cross-references
- Sub-plan 2 —
plans/onboarding-trial-mode.md(Part 1 + Part 1B + Part 2 implementation steps) - ADR 0006 — Chargeback auto-freeze (Stripe webhook integration)
- ADR 0008 — Tier model (Stripe Price IDs map к tier slugs)
- ADR 0009 — Tenancy & Permission (Organisation = subscription unit)
- ADR 0011 — Email sender architecture (separate from payment provider; can use Resend/SendGrid/etc. independent of Stripe choice)
- ADR 0013 — Tier change proration policy (Stripe SubscriptionSchedule + create_prorations)
- Phase 1.7.10 — Custom domain DKIM Tier 2+ feature
- Phase 1.7.11 — Free tier billing tracking
- Research artefact —
docs/research/stripe-billing-onboarding-stage1-2026-05-11.md(Perplexity Sonar Deep Research findings backing this decision) launch-plan-v3.md:798-815— closes «Stripe vs Paddle TBD»- Learning «PaymentProvider abstraction для кипрской компании» (2026-04-29) — superseded by this ADR (Cyprus-specific framing obsolete per CONV-35 jurisdiction shift к Abu Dhabi candidate)