Skip to content

Billing Endpoints

Subscription management, usage tracking, and white-label billing for tenants.

Overview

Backflow has two billing systems:

  1. Platform Billing - Backflow charges tenants based on usage (API calls, storage, AI tokens)
  2. Tenant Billing - Tenants can bill their own customers using their own payment provider

Platform Billing

Get Plans

GET /billing/plans

List all available subscription plans with limits.

bash
curl http://localhost:3000/billing/plans \
  -H "Authorization: Bearer <token>"

Response:

json
{
  "plans": [
    {
      "tier": "free",
      "name": "Free",
      "description": "For individual developers",
      "price": { "monthly": 0, "yearly": 0, "currency": "USD" },
      "limits": {
        "websocket": { "maxConnections": 10, "maxEntitiesWatched": 2 },
        "fileStorage": { "maxStorageMB": 200, "maxFileSizeMB": 5 },
        "api": { "requestsPerMinute": 100 },
        "ai": { "llmTokensPerMonth": 100000, "maxCostPerMonth": 5 }
      }
    },
    {
      "tier": "pro",
      "name": "Pro",
      "description": "For small teams",
      "price": { "monthly": 29, "yearly": 290, "currency": "USD" },
      "limits": { ... }
    }
  ]
}

Get Subscription

GET /billing/subscription

Get current tenant subscription status.

bash
curl http://localhost:3000/billing/subscription \
  -H "Authorization: Bearer <token>"

Response:

json
{
  "tenantId": "tenant-123",
  "subscription": {
    "plan": "pro",
    "status": "active",
    "startDate": "2024-01-01T00:00:00Z",
    "renewalDate": "2024-02-01T00:00:00Z",
    "currentPeriodEnd": "2024-02-01T00:00:00Z",
    "cancelAtPeriodEnd": false,
    "paymentMethod": "card"
  }
}

Get Usage

GET /billing/usage

Get current resource usage against plan limits.

bash
curl http://localhost:3000/billing/usage \
  -H "Authorization: Bearer <token>"

Response:

json
{
  "tenantId": "tenant-123",
  "plan": "pro",
  "usage": {
    "websocket": {
      "connections": { "current": 45, "limit": 100, "percentage": 45 },
      "entitiesWatched": { "current": 8, "limit": 10, "percentage": 80 },
      "rooms": { "current": 3, "limit": 10, "percentage": 30 }
    },
    "fileStorage": {
      "storage": {
        "current": 1073741824,
        "limit": 5368709120,
        "percentage": 20,
        "currentFormatted": "1 GB",
        "limitFormatted": "5 GB"
      }
    },
    "tenantConfig": {
      "secrets": { "current": 12, "limit": 50, "percentage": 24 }
    }
  }
}

Upgrade Plan

POST /billing/upgrade

Request upgrade to a higher plan. Returns a checkout URL.

bash
curl -X POST http://localhost:3000/billing/upgrade \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "targetPlan": "pro",
    "billingCycle": "monthly"
  }'

Response:

json
{
  "success": true,
  "checkoutUrl": "https://checkout.polar.sh/...",
  "session": {
    "id": "checkout-123",
    "provider": "polar",
    "plan": "pro",
    "billing_cycle": "monthly",
    "amount": 2900,
    "currency": "USD"
  }
}

Sync Subscription

POST /billing/subscription/sync

Manually sync subscription status from payment provider.

bash
curl -X POST http://localhost:3000/billing/subscription/sync \
  -H "Authorization: Bearer <token>"

Response:

json
{
  "success": true,
  "subscription": {
    "plan": "pro",
    "status": "active"
  }
}

Webhooks

Polar Webhook

POST /billing/webhook/polar

Receives webhook events from Polar for subscription lifecycle.

Configure in Polar Dashboard:

  • Endpoint: https://api.backflow.dev/billing/webhook/polar
  • Events: subscription.created, subscription.updated, subscription.canceled, order.paid

The webhook validates signatures using POLAR_WEBHOOK_SECRET.

Stripe Webhook

POST /webhooks/billing/stripe

Receives webhook events from Stripe (if configured).

Configure in Stripe Dashboard:

  • Endpoint: https://api.backflow.dev/webhooks/billing/stripe
  • Events: checkout.session.completed, customer.subscription.*, invoice.*

Tenant Billing (White-Label)

Tenants can use their own payment provider to bill their customers. This requires storing payment provider credentials in tenant secrets.

Setup

  1. Store your Polar API key in secrets:
bash
curl -X POST http://localhost:3000/tenant/secrets \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "polar_api_key",
    "value": "polar_sk_live_..."
  }'
  1. Optionally store organization ID:
bash
curl -X POST http://localhost:3000/tenant/secrets \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "polar_organization_id",
    "value": "org-123"
  }'

List Products

GET /billing/tenant/products

List products from your Polar organization.

bash
curl http://localhost:3000/billing/tenant/products \
  -H "Authorization: Bearer <token>"

Response:

json
{
  "items": [
    {
      "id": "prod-123",
      "name": "Pro Plan",
      "description": "Access to all features",
      "prices": [
        { "id": "price-123", "amount": 2900, "currency": "usd", "interval": "month" }
      ]
    }
  ]
}

Create Product

POST /billing/tenant/products

Create a product in your Polar organization.

bash
curl -X POST http://localhost:3000/billing/tenant/products \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Enterprise Plan",
    "description": "For large teams",
    "prices": [
      { "amount": 9900, "currency": "usd", "interval": "month" }
    ]
  }'

Create Checkout

POST /billing/tenant/checkout

Create a checkout session for your customer.

bash
curl -X POST http://localhost:3000/billing/tenant/checkout \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "productPriceId": "price-123",
    "customerEmail": "customer@example.com",
    "successUrl": "https://yourapp.com/success",
    "cancelUrl": "https://yourapp.com/cancel"
  }'

Response:

json
{
  "id": "checkout-456",
  "url": "https://checkout.polar.sh/..."
}

List Customers

GET /billing/tenant/customers

List customers from your Polar organization.

bash
curl http://localhost:3000/billing/tenant/customers \
  -H "Authorization: Bearer <token>"

Response:

json
{
  "items": [
    {
      "id": "cust-123",
      "email": "customer@example.com",
      "name": "John Doe",
      "created_at": "2024-01-15T00:00:00Z"
    }
  ]
}

List Subscriptions

GET /billing/tenant/subscriptions

List subscriptions from your Polar organization.

bash
curl http://localhost:3000/billing/tenant/subscriptions \
  -H "Authorization: Bearer <token>"

Response:

json
{
  "items": [
    {
      "id": "sub-123",
      "customer_id": "cust-123",
      "status": "active",
      "current_period_end": "2024-02-15T00:00:00Z",
      "product": { "name": "Pro Plan" }
    }
  ]
}

Cancel Subscription

DELETE /billing/tenant/subscriptions/:id

Cancel a customer's subscription.

bash
curl -X DELETE http://localhost:3000/billing/tenant/subscriptions/sub-123 \
  -H "Authorization: Bearer <token>"

Get Customer State

GET /billing/tenant/customers/:id/state

Get subscription state for a specific customer.

bash
curl http://localhost:3000/billing/tenant/customers/cust-123/state \
  -H "Authorization: Bearer <token>"

Response:

json
{
  "customerId": "cust-123",
  "hasActiveSubscription": true,
  "subscriptions": [
    {
      "id": "sub-123",
      "status": "active",
      "product": "Pro Plan"
    }
  ]
}

Plan Tiers

TierMonthlyWebSocket ConnectionsStorageAPI RateAI Tokens/Month
Free$010200 MB100/min100K
Pro$291005 GB1,000/min10M
Team$9950025 GB3,000/min50M
Scale$2992,000100 GB6,000/min75M
EnterpriseCustom10,000+Unlimited10,000/minUnlimited

Tier Enforcement

Usage is tracked in real-time and enforced before operations. When limits are exceeded:

json
{
  "error": "Usage limit exceeded",
  "message": "WebSocket connection limit reached (10)",
  "allowed": false,
  "upgrade": {
    "plan": "pro",
    "limit": 100
  }
}

Status: 402 Payment Required

Environment Variables

bash
# Payment Provider
PAYMENT_PROVIDER=polar

# Polar Configuration
POLAR_API_KEY=polar_sk_...
POLAR_ORGANIZATION_ID=org-123
POLAR_WEBHOOK_SECRET=polar_whs_...

# Product Mappings (reverse mapping product->tier is derived automatically)
POLAR_PRODUCT_MAP={"pro_monthly":"price-123","pro_yearly":"price-456",...}

# App URL (for checkout redirects)
APP_URL=https://app.backflow.dev

Backflow - Configuration-driven API framework