Skip to content

Stripe Billing Configuration

This guide explains how to configure Stripe for usage-based billing in the ERP-Unlocked platform.

ERP-Unlocked uses a usage-based billing model with Stripe:

  • Base Subscription: $500/month fixed fee
  • Usage Charges: $0.40 per line item processed, with $2.50 minimum per order
Terminal window
# Stripe API Keys
STRIPE_SECRET_KEY=sk_live_... # Production secret key
STRIPE_PUBLISHABLE_KEY=pk_live_... # Production publishable key
STRIPE_WEBHOOK_SECRET=whsec_... # Webhook signing secret
# Stripe Price IDs
STRIPE_BASE_PRICE_ID=price_... # Base subscription price ID
STRIPE_USAGE_PRICE_ID=price_... # Metered usage price ID
Terminal window
# API Version (defaults to 2026-02-25.clover)
STRIPE_API_VERSION=2026-02-25.clover
# CLI webhook secret for local development
STRIPE_WEBHOOK_SECRET_CLI=whsec_...

In the Stripe Dashboard:

  1. Go to ProductsAdd Product
  2. Set the product name (e.g., “Ordermatic Platform”)
  3. Add a recurring price:
    • Price: $500.00
    • Billing period: Monthly
    • Price ID: Use this as STRIPE_BASE_PRICE_ID
  1. Go to ProductsAdd Product
  2. Set the product name (e.g., “Ordermatic Usage”)
  3. Add a metered price:
    • Pricing model: Metered
    • Usage type: Licensed
    • Price per unit: $0.40 (this is the Stripe unit price, actual rates are in metadata)
    • Price ID: Use this as STRIPE_USAGE_PRICE_ID

Add metadata to your usage price (or product) to configure billing rates:

{
"per_line_item_rate": "0.40",
"minimum_per_order": "2.50"
}
Metadata KeyDescriptionDefault
per_line_item_rateCost per line item processed$0.40
minimum_per_orderMinimum charge per order$2.50

Important: These values are read from Stripe at runtime. Changing them in Stripe Dashboard will update pricing without code deployment. If metadata is not set, the system falls back to DEFAULT_BILLING_CONFIG values.

Add metadata to your base product for feature display:

{
"features": "Unlimited orders,ERP integration,PDF processing,Email support",
"monthly_orders": "unlimited",
"team_members": "10",
"erp_connections": "3",
"support_level": "priority"
}
  1. Go to DevelopersWebhooksAdd endpoint
  2. Set the endpoint URL: https://app.yourdomain.com/api/webhooks/stripe
  3. Select events:
    • checkout.session.completed
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.created
    • invoice.finalized
    • invoice.paid
    • invoice.payment_failed

Use the Stripe CLI for local webhook testing:

Terminal window
# Install Stripe CLI
brew install stripe/stripe-cli/stripe
# Login to Stripe
stripe login
# Forward webhooks to local server
stripe listen --forward-to localhost:4321/api/webhooks/stripe

The CLI will display a webhook signing secret (whsec_...) to use as STRIPE_WEBHOOK_SECRET_CLI.

POST /api/billing/checkout-session

Creates a Stripe Checkout session for new subscriptions. Requires organization admin role.

POST /api/billing/portal

Creates a Stripe Customer Portal session for subscription management.

GET /api/billing/pricing

Returns current pricing information from Stripe.

GET /api/billing/usage/events
POST /api/billing/usage/record

Manage usage event tracking and reporting.

Usage is tracked via the usage_events table:

{
orderId: string; // UUID of the processed order
lineItemCount: number; // Number of line items
calculatedCharge: number; // Charge amount (line items × rate)
freeTrialLineItemsUsed: number; // Free trial usage
status: 'reported' | 'invoiced' | 'failed';
}

Usage is reported to Stripe via the webapp billing flow, and failed usage retries are handled by the Temporal usage_reporting workflow.

Default billing rates:

RateDefault Value
Per Line Item$0.40
Minimum Order Charge$2.50
Free Trial Line Items100

Rates can be overridden per-organization via the admin panel.

Use Stripe test mode keys (sk_test_..., pk_test_...) for development:

Terminal window
# Test credit card numbers
4242 4242 4242 4242 # Successful payment
4000 0000 0000 0002 # Declined payment
4000 0000 0000 3220 # 3D Secure required
Terminal window
# Trigger a test event
stripe trigger checkout.session.completed
# Trigger with specific data
stripe trigger invoice.paid --add invoice:billing_reason=subscription_cycle
  • Ensure STRIPE_WEBHOOK_SECRET matches the endpoint secret in Stripe Dashboard
  • For local development, use the CLI-provided secret
  • Verify STRIPE_BASE_PRICE_ID and STRIPE_USAGE_PRICE_ID are correct
  • Ensure prices are active in Stripe
  • Check usage_events table for failed events
  • Verify subscriptionItemId is set in the subscriptions table
  • Check Temporal workflow history / temporal-worker logs for failed retry runs