Overview

Pandabase handles the full subscription lifecycle — billing, retries, 3D Secure authentication, invoices, and cancellation. You create a product with type: SUBSCRIPTION, and the platform takes care of everything else.

stateDiagram-v2
    [*] --> TRIALING: Customer starts trial
    [*] --> ACTIVE: First payment collected
    TRIALING --> ACTIVE: Trial ends, payment collected
    ACTIVE --> PAUSED: Merchant pauses
    PAUSED --> ACTIVE: Merchant resumes
    ACTIVE --> PAST_DUE: Payment fails
    PAST_DUE --> ACTIVE: Retry succeeds or 3DS completed
    PAST_DUE --> CANCELLED: Max retries exhausted
    ACTIVE --> CANCELLED: Merchant or customer cancels
    TRIALING --> CANCELLED: Cancelled during trial

How it works

  1. Create a subscription product with a billing interval (weekly, monthly, or yearly)
  2. Customer checks out — pays the first charge (or starts a free trial)
  3. Card is saved — Pandabase stores the payment method securely for future charges
  4. Automatic renewals — the platform charges the customer on each billing cycle
  5. Invoices sent — customers receive a PDF invoice email on every charge
  6. Lifecycle events — webhooks fire on every state change

Creating a subscription product

Set type to SUBSCRIPTION and configure the billing interval:

curl -X POST https://api.pandabase.io/v2/core/stores/{storeId}/products \  -H "Authorization: Bearer {token}" \  -H "Content-Type: application/json" \  -d '{    "title": "Pro Plan",    "price": 1999,    "type": "SUBSCRIPTION",    "billingInterval": "MONTHLY",    "status": "ACTIVE",    "fulfillmentMode": "MANUAL"  }'
Field Options Description
billingInterval WEEKLY, MONTHLY, YEARLY How often the customer is charged
trialDays 0365 Free trial period before first charge (optional)

Checkout flow

Create a checkout session with a subscription product — the checkout UI automatically adapts:

  • Shows the billing interval (e.g. “$19.99 / month”)
  • Shows trial info if applicable (e.g. “7-day free trial, then $19.99/month”)
  • Restricts payment to card and Link (required for recurring billing)
  • Shows a consent checkbox before payment
  • Button text changes to “Subscribe” or “Start subscription”
curl -X POST https://api.pandabase.io/v2/stores/{storeId}/checkouts \  -H "Content-Type: application/json" \  -d '{    "items": [{ "product_id": "prd_xxx", "quantity": 1 }],    "customer": {      "name": "Jane Doe",      "email": "jane@example.com",      "billing": {        "line1": "123 Main St",        "city": "San Francisco",        "state": "CA",        "postal_code": "94105",        "country": "US"      }    }  }'

Subscription statuses

Status Description
TRIALING Customer is in a free trial — no charges until trial ends
ACTIVE Billing is active, customer is being charged on schedule
PAST_DUE Payment failed — retrying automatically or awaiting 3DS verification
PAUSED Billing paused by merchant — no charges until resumed
CANCELLED Subscription ended — no further charges

Free trials

Set trial_days on the product to offer a free trial:

{  "title": "Pro Plan",  "price": 1999,  "type": "SUBSCRIPTION",  "billingInterval": "MONTHLY",  "trialDays": 7,  "status": "ACTIVE"}

During checkout, the customer saves their card without being charged. The subscription starts in TRIALING status and the first charge happens automatically when the trial ends.

Failed payments and retries

When a renewal payment fails, Pandabase:

  1. Moves the subscription to PAST_DUE
  2. Fires a SUBSCRIPTION_PAST_DUE webhook
  3. Emails the customer about the failed payment
  4. Retries automatically with backoff:
    • Retry 1: 24 hours later
    • Retry 2: 48 hours later
    • Retry 3: 72 hours later
  5. If all retries fail, the subscription is cancelled

3D Secure on renewals

Some banks require 3D Secure authentication for recurring charges. When this happens:

  1. The subscription moves to PAST_DUE
  2. The customer receives an email with a secure verification link
  3. The customer clicks the link and completes the bank’s authentication
  4. The payment is processed and the subscription returns to ACTIVE

No action is needed from you — Pandabase handles the authentication flow automatically.

Managing subscriptions

Via API

Use SUBSCRIPTIONS_READ and SUBSCRIPTIONS_WRITE permissions on your API token:

# list subscriptionsGET /v2/core/stores/{storeId}/subscriptions# get subscription detailGET /v2/core/stores/{storeId}/subscriptions/{subscriptionId}# cancel (at period end by default)POST /v2/core/stores/{storeId}/subscriptions/{subscriptionId}/cancel# cancel immediatelyPOST /v2/core/stores/{storeId}/subscriptions/{subscriptionId}/cancel  -d '{ "immediate": true }'# pause billingPOST /v2/core/stores/{storeId}/subscriptions/{subscriptionId}/pause# resume billingPOST /v2/core/stores/{storeId}/subscriptions/{subscriptionId}/resume

Via Customer Portal

Customers can view and cancel their subscriptions at mypandabase.com. Cancellation is always at period end — customers retain access until the current billing period expires.

Cancellation behavior

Who cancels Behavior
Merchant (default) Cancels at end of current billing period
Merchant (immediate) Cancels immediately, revokes access, revokes licenses if revoke_on_refund is enabled
Customer Always cancels at end of current billing period
System (max retries) Cancels after 4 failed payment attempts

Webhook events

Six events are available for subscription state changes:

Event When
SUBSCRIPTION_CREATED First payment or trial setup succeeds
SUBSCRIPTION_RENEWED Renewal payment succeeds
SUBSCRIPTION_PAST_DUE Renewal failed or needs 3DS
SUBSCRIPTION_CANCELLED Cancelled by merchant, customer, or max retries
SUBSCRIPTION_PAUSED Merchant paused billing
SUBSCRIPTION_RESUMED Merchant resumed billing

See Webhook Events for payload details and integration examples.

Invoices

Customers automatically receive a PDF invoice via email on:

  • The first subscription payment
  • Every renewal payment

Invoices include the product name, amount, billing period, tax breakdown, and next charge date.

Usage-based billing

If you need to charge per request, per token, per seat, or any other metric where the bill is not known in advance, configure the product with pricingModel: USAGE_BASED and attach meters. The lifecycle, retries, invoices, and webhook events described on this page apply unchanged. See Usage-based billing for the meter model, event ingestion, and renewal math.

Limitations

  • Only one subscription item per checkout (no mixing with one-time items)
  • Billing is in USD only (multicurrency renewals are a future enhancement)
  • Price is locked at creation — changing the product price does not affect existing subscriptions
  • Subscription upgrades/downgrades are not yet supported — cancel and re-subscribe