Subscription & Billing Guide 🟡 BETA

This guide covers General Bots’ subscription management, billing integration, quota systems, and white-label billing configuration.

Overview

General Bots provides a comprehensive billing system that supports:

  • Multiple Plans - Free, Pro, Business, Enterprise tiers
  • Usage-Based Billing - Pay for what you use
  • Quota Management - Enforce limits per organization
  • Stripe Integration - Secure payment processing
  • White-Label Support - Custom branding for resellers

Plan Structure

Default Plans

PlanPriceMembersBotsStorageMessagesAPI Calls
Free$0/mo521 GB1,000/mo10,000/mo
Pro$49/mo502050 GB100,000/mo500,000/mo
Business$99/mo200100200 GBUnlimitedUnlimited
EnterpriseCustomUnlimitedUnlimited1 TB+UnlimitedUnlimited

Plan Configuration

Plans are defined in .product files for white-label deployments:

version: 1
product:
  name: "My SaaS Product"
  company: "My Company"
  
plans:
  - id: starter
    name: Starter
    price_monthly: 29
    price_annual: 290
    features:
      max_members: 10
      max_bots: 5
      storage_gb: 10
      messages_per_month: 10000
      api_calls_per_month: 50000
      support_level: email
      
  - id: professional
    name: Professional
    price_monthly: 79
    price_annual: 790
    features:
      max_members: 50
      max_bots: 25
      storage_gb: 100
      messages_per_month: 100000
      api_calls_per_month: 500000
      support_level: priority
      custom_branding: true
      
  - id: enterprise
    name: Enterprise
    price_monthly: 0
    custom_pricing: true
    features:
      max_members: -1
      max_bots: -1
      storage_gb: 1000
      messages_per_month: -1
      api_calls_per_month: -1
      support_level: dedicated
      custom_branding: true
      sso: true
      audit_logs: true
      sla: "99.9%"

Stripe Integration

Configuration

Add Stripe credentials to your environment:

STRIPE_SECRET_KEY=sk_live_...
STRIPE_PUBLISHABLE_KEY=pk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_ID_PRO_MONTHLY=price_...
STRIPE_PRICE_ID_PRO_ANNUAL=price_...
STRIPE_PRICE_ID_BUSINESS_MONTHLY=price_...
STRIPE_PRICE_ID_BUSINESS_ANNUAL=price_...

Webhook Events

General Bots handles these Stripe webhook events:

EventAction
customer.subscription.createdActivate subscription
customer.subscription.updatedUpdate plan/status
customer.subscription.deletedCancel subscription
invoice.paidRecord payment
invoice.payment_failedHandle failed payment
customer.subscription.trial_will_endSend trial ending notification

Setting Up Webhooks

  1. Go to Stripe Dashboard → Developers → Webhooks
  2. Add endpoint: https://your-domain.com/api/billing/webhooks/stripe
  3. Select events to listen for
  4. Copy webhook secret to STRIPE_WEBHOOK_SECRET

Subscription Lifecycle

Creating a Subscription

POST /api/billing/subscriptions
Authorization: Bearer <token>
Content-Type: application/json

{
  "plan_id": "pro",
  "billing_cycle": "monthly",
  "payment_method_id": "pm_...",
  "trial_days": 14,
  "coupon_code": "LAUNCH20"
}

Response:

{
  "subscription_id": "sub_...",
  "organization_id": "org-uuid",
  "plan_id": "pro",
  "status": "trialing",
  "trial_end": "2025-02-04T00:00:00Z",
  "current_period_end": "2025-03-21T00:00:00Z",
  "cancel_at_period_end": false
}

Upgrading/Downgrading

POST /api/billing/subscriptions/{subscription_id}/change
Authorization: Bearer <token>
Content-Type: application/json

{
  "new_plan_id": "business",
  "prorate": true,
  "immediate": true
}

Proration calculates the difference and adjusts the next invoice.

Cancellation

POST /api/billing/subscriptions/{subscription_id}/cancel
Authorization: Bearer <token>
Content-Type: application/json

{
  "reason": "too_expensive",
  "feedback": "Need more affordable options",
  "cancel_immediately": false,
  "offer_retention": true
}

When offer_retention is true, the system may return retention offers:

{
  "status": "pending_retention",
  "offers": [
    {
      "id": "offer-uuid",
      "type": "discount",
      "discount_percent": 25,
      "duration_months": 3,
      "expires_at": "2025-01-28T00:00:00Z"
    },
    {
      "id": "offer-uuid-2",
      "type": "pause",
      "pause_months": 3
    }
  ]
}

Pausing a Subscription

POST /api/billing/subscriptions/{subscription_id}/pause
Authorization: Bearer <token>
Content-Type: application/json

{
  "pause_months": 3
}

Resuming a Subscription

POST /api/billing/subscriptions/{subscription_id}/resume
Authorization: Bearer <token>

Quota Management

Quota Types

QuotaEnforcementReset
membersHard limitN/A
botsHard limitN/A
storage_bytesHard limitN/A
messagesSoft limitMonthly
api_callsRate limitMonthly

Checking Quotas

GET /api/billing/quotas
Authorization: Bearer <token>

Response:

{
  "organization_id": "org-uuid",
  "plan_id": "pro",
  "quotas": {
    "members": {
      "used": 12,
      "limit": 50,
      "percent": 24
    },
    "bots": {
      "used": 5,
      "limit": 20,
      "percent": 25
    },
    "storage_bytes": {
      "used": 5368709120,
      "limit": 53687091200,
      "percent": 10
    },
    "messages": {
      "used": 45000,
      "limit": 100000,
      "percent": 45,
      "resets_at": "2025-02-01T00:00:00Z"
    },
    "api_calls": {
      "used": 125000,
      "limit": 500000,
      "percent": 25,
      "resets_at": "2025-02-01T00:00:00Z"
    }
  }
}

Usage Alerts

The system sends alerts at these thresholds:

ThresholdAlert TypeNotification
80%WarningEmail, In-app
90%CriticalEmail, In-app, Webhook
100%Limit ReachedEmail, In-app, Webhook

Configuring Alerts

PUT /api/billing/alerts/preferences
Authorization: Bearer <token>
Content-Type: application/json

{
  "email_notifications": true,
  "webhook_url": "https://your-app.com/webhooks/quota",
  "slack_webhook": "https://hooks.slack.com/...",
  "alert_thresholds": [70, 85, 95, 100]
}

Grace Period

When quotas are exceeded, organizations enter a grace period:

  • Default: 7 days
  • During grace: Soft limits become warnings
  • After grace: Hard enforcement applies
GET /api/billing/grace-period
Authorization: Bearer <token>

Response:

{
  "in_grace_period": true,
  "exceeded_quotas": ["messages"],
  "grace_started": "2025-01-21T00:00:00Z",
  "grace_ends": "2025-01-28T00:00:00Z",
  "overage_percent": 15,
  "recommended_action": "upgrade_plan"
}

Usage Metering

Recording Usage

Usage is automatically tracked, but can be manually recorded:

POST /api/billing/usage
Authorization: Bearer <token>
Content-Type: application/json

{
  "metric": "api_calls",
  "quantity": 100,
  "timestamp": "2025-01-21T10:30:00Z",
  "metadata": {
    "endpoint": "/api/chat",
    "bot_id": "bot-uuid"
  }
}

Querying Usage

GET /api/billing/usage/history
Authorization: Bearer <token>

Query parameters:

ParameterDescription
metricFilter by metric type
start_datePeriod start
end_datePeriod end
granularityhour, day, week, month

Response:

{
  "metric": "api_calls",
  "period": {
    "start": "2025-01-01T00:00:00Z",
    "end": "2025-01-31T23:59:59Z"
  },
  "total": 125000,
  "data_points": [
    {"date": "2025-01-01", "value": 4200},
    {"date": "2025-01-02", "value": 3800},
    ...
  ]
}

Invoices

Listing Invoices

GET /api/billing/invoices
Authorization: Bearer <token>

Response:

{
  "invoices": [
    {
      "id": "inv_...",
      "number": "INV-2025-0001",
      "date": "2025-01-21",
      "amount": 4900,
      "currency": "usd",
      "status": "paid",
      "pdf_url": "https://...",
      "items": [
        {
          "description": "Pro Plan (Monthly)",
          "amount": 4900,
          "quantity": 1
        }
      ]
    }
  ],
  "has_more": false
}

Downloading Invoice PDF

GET /api/billing/invoices/{invoice_id}/pdf
Authorization: Bearer <token>

Returns PDF binary with Content-Type: application/pdf.

Payment Methods

Adding a Payment Method

POST /api/billing/payment-methods
Authorization: Bearer <token>
Content-Type: application/json

{
  "payment_method_id": "pm_...",
  "set_as_default": true
}

Listing Payment Methods

GET /api/billing/payment-methods
Authorization: Bearer <token>

Removing a Payment Method

DELETE /api/billing/payment-methods/{payment_method_id}
Authorization: Bearer <token>

White-Label Billing

Custom Branding

Configure billing UI branding in your .product file:

branding:
  billing:
    company_name: "Your Company"
    support_email: "billing@yourcompany.com"
    invoice_logo: "/assets/logo.png"
    invoice_footer: "Thank you for your business!"
    currency: "usd"
    tax_id_label: "VAT Number"

Reseller Mode

Enable reseller billing to manage customer subscriptions:

reseller:
  enabled: true
  commission_percent: 20
  min_markup_percent: 0
  allow_custom_pricing: true
  billing_relationship: "reseller"  # or "direct"

Custom Plan Pricing

Resellers can set custom pricing:

POST /api/billing/reseller/plans/{plan_id}/pricing
Authorization: Bearer <token>
Content-Type: application/json

{
  "customer_id": "customer-uuid",
  "custom_price_monthly": 7900,
  "custom_price_annual": 79000
}

Self-Hosted Mode

For self-hosted installations without SaaS billing:

SAAS_MODE=false
LOCAL_QUOTA_MODE=true

In local quota mode:

  • No payment processing
  • Quotas enforced locally
  • No subscription management
  • Resource limits based on configuration

Configure local quotas:

local_quotas:
  max_members: 100
  max_bots: 50
  max_storage_gb: 500
  max_messages_per_month: 1000000

Events and Webhooks

Subscription Events

{
  "event": "subscription.created",
  "timestamp": "2025-01-21T10:00:00Z",
  "data": {
    "subscription_id": "sub_...",
    "organization_id": "org-uuid",
    "plan_id": "pro",
    "status": "active"
  }
}

Event types:

EventDescription
subscription.createdNew subscription started
subscription.updatedPlan or status changed
subscription.cancelledSubscription cancelled
subscription.renewedSubscription renewed
payment.succeededPayment processed
payment.failedPayment failed
quota.warningQuota threshold reached
quota.exceededQuota limit exceeded

Configuring Webhooks

POST /api/billing/webhooks
Authorization: Bearer <token>
Content-Type: application/json

{
  "url": "https://your-app.com/webhooks/billing",
  "events": ["subscription.*", "payment.*", "quota.*"],
  "secret": "your-webhook-secret"
}

Best Practices

For SaaS Operators

  1. Start with a free tier - Lower barrier to entry
  2. Offer annual discounts - 15-20% savings encourages commitment
  3. Set clear usage limits - Avoid surprise bills
  4. Provide grace periods - Don’t cut off access immediately
  5. Retention offers work - Discounts reduce churn

For Enterprise Deployments

  1. Custom contracts - Negotiate terms for large deals
  2. Usage commitments - Discounts for guaranteed usage
  3. Multi-year deals - Better pricing for longer terms
  4. Success management - Dedicated support reduces churn

For Self-Hosted

  1. Resource planning - Set realistic quotas
  2. Monitor usage - Track before limits are hit
  3. Scale proactively - Add capacity before needed

Troubleshooting

Payment Failed

  1. Check payment method is valid
  2. Verify billing address
  3. Contact card issuer if declined
  4. Add backup payment method

Quota Exceeded

  1. Review usage in dashboard
  2. Identify heavy consumers
  3. Upgrade plan or reduce usage
  4. Request temporary increase (enterprise)

Invoice Issues

  1. Check billing email settings
  2. Verify invoice delivery
  3. Download from dashboard
  4. Contact support for corrections