DX
Deployment

SaaS Billing Setup with Stripe

Configure Stripe Checkout, Customer Portal, and webhooks for DataXPipe SaaS plans including Free, Team, and Business tiers with org-scoped entitlements.

DataXPipe Team
  • stripe
  • billing
  • saas

DataXPipe SaaS uses Stripe for subscription billing across Free, Team, and Business plans. The FastAPI backend handles Checkout sessions, Customer Portal access, and webhook-driven plan synchronization. This guide covers end-to-end Stripe setup for production.

Plan structure

PlanPricePipelinesConnectionsSupport
Free$032Community
Team$49/mo2510Email
Business$199/moUnlimitedUnlimitedPriority

Plan limits enforce at the API layer when organizations register pipelines or connections beyond their tier.

Stripe Dashboard setup

1. Create products and prices

In Stripe Dashboard → Products:

  1. Create DataXPipe Team — recurring monthly price (e.g. $49/month)
  2. Create DataXPipe Business — recurring monthly price (e.g. $199/month)

Copy price IDs (price_...) for environment configuration.

2. Configure environment variables

On the API deployment (DigitalOcean App Platform or DOKS):

STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_TEAM=price_xxxxxxxx
STRIPE_PRICE_BUSINESS=price_yyyyyyyy

On Vercel frontends (marketing/ and product-ui/):

NEXT_PUBLIC_STRIPE_PRICE_TEAM=price_xxxxxxxx
NEXT_PUBLIC_STRIPE_PRICE_BUSINESS=price_yyyyyyyy

Frontend price IDs power upgrade buttons; backend price IDs validate Checkout session creation.

3. Register webhook endpoint

Stripe Dashboard → Webhooks → Add endpoint:

https://api.dataxpipe.com/webhooks/stripe

Subscribe to events:

  • checkout.session.completed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted

Copy the signing secret to STRIPE_WEBHOOK_SECRET.

API billing endpoints

Authenticated org members call:

# Create Checkout session for upgrade
curl -X POST https://api.dataxpipe.com/api/v1/billing/checkout `
  -H "Authorization: Bearer <jwt>" `
  -H "Content-Type: application/json" `
  -d '{"price_id":"price_xxxxxxxx"}'

# Open Customer Portal for payment management
curl -X POST https://api.dataxpipe.com/api/v1/billing/portal `
  -H "Authorization: Bearer <jwt>"

Checkout redirects users to Stripe-hosted payment pages. On success, webhooks update the organization’s plan in Postgres.

Webhook processing flow

Stripe event → POST /webhooks/stripe
  → verify signature (STRIPE_WEBHOOK_SECRET)
  → map stripe_customer_id → organization
  → update plan, stripe_subscription_id, stripe_price_id

Key handler logic in app/billing/stripe_service.py:

  • Subscription created/updated — set org plan to team or business based on price ID
  • Subscription deleted — downgrade org to free
  • Checkout completed — link Stripe customer ID to organization

Webhook failures return non-2xx so Stripe retries delivery. Monitor webhook logs in Stripe Dashboard.

Database schema

Migration 0002_saas adds billing columns to organizations:

ColumnPurpose
stripe_customer_idLinks org to Stripe customer
stripe_subscription_idActive subscription reference
stripe_price_idCurrent price tier
planfree, team, or business

Plan changes from webhooks update plan atomically—API handlers read this column for limit enforcement.

Testing in development

Use Stripe test mode keys (sk_test_...) locally:

$env:STRIPE_SECRET_KEY = "sk_test_..."
$env:STRIPE_WEBHOOK_SECRET = "whsec_test_..."

Forward webhooks to localhost with Stripe CLI:

stripe listen --forward-to localhost:8000/webhooks/stripe
stripe trigger checkout.session.completed

Unit tests in tests/test_billing_unit.py mock Stripe SDK calls.

Security

  • Never expose STRIPE_SECRET_KEY to frontends
  • Verify webhook signatures on every request—reject unsigned payloads
  • Use HTTPS only for webhook endpoints
  • Restrict billing API endpoints to authenticated org admins via OIDC roles

For multi-tenant isolation details, see multi-tenant pipeline catalogs. For full SaaS deployment, see Deploy DataXPipe on DigitalOcean.