Skip to content

Subscriptions

Create and manage recurring billing subscriptions for SaaS, memberships, and recurring services.

Subscription Lifecycle

Created → Trialing → Active → Paused → Canceled
                   ↘ Past Due → Canceled
StatusDescription
trialingIn trial period, no charges yet
activeSubscription is active and billing
past_duePayment failed, retrying
pausedTemporarily paused
canceledSubscription ended

Create a Subscription

First, save a card using Hosted Checkout with mode: 'setup', then create the subscription:

JavaScript

javascript
const subscription = await fyber.subscriptions.create({
  customerId: 'cus_123',
  tokenId: 'tok_123', // Saved card
  amount: 999, // $9.99/month
  currency: 'JMD',
  interval: 'month',
  trialDays: 14, // Optional trial
  metadata: {
    plan: 'pro',
  },
});

PHP

php
$subscription = $fyber->subscriptions->create([
    'customerId' => 'cus_123',
    'tokenId' => 'tok_123',
    'amount' => 999,
    'currency' => 'JMD',
    'interval' => 'month',
    'trialDays' => 14,
]);

C#

csharp
var subscription = await fyber.Subscriptions.CreateAsync(new CreateSubscriptionRequest
{
    CustomerId = "cus_123",
    TokenId = "tok_123",
    Amount = 999,
    Currency = "JMD",
    Interval = "month",
    TrialDays = 14
});

Subscription Parameters

ParameterTypeRequiredDescription
customerIdstringYesCustomer ID
tokenIdstringYesSaved card token
amountintegerYesAmount in cents per interval
currencystringYesThree-letter currency code
intervalstringYesBilling interval
intervalCountintegerNoNumber of intervals (default: 1)
trialDaysintegerNoTrial period in days
metadataobjectNoCustom key-value data

Intervals

IntervalExample
dayDaily billing
weekWeekly billing
monthMonthly billing
yearAnnual billing
javascript
// Bill every 3 months
{ interval: 'month', intervalCount: 3 }

Retrieve a Subscription

javascript
const subscription = await fyber.subscriptions.get('sub_123');

console.log(subscription.status);
console.log(subscription.currentPeriodEnd);

List Subscriptions

javascript
const subscriptions = await fyber.subscriptions.list({
  customerId: 'cus_123',
  status: 'active',
  limit: 20,
});

Pause a Subscription

Temporarily stop billing:

javascript
await fyber.subscriptions.pause('sub_123');

Resume a Subscription

Resume a paused subscription:

javascript
await fyber.subscriptions.resume('sub_123');

Cancel a Subscription

Cancel at Period End

Let the subscription run until the current period ends:

javascript
await fyber.subscriptions.cancel('sub_123', {
  cancelAtPeriodEnd: true,
  reason: 'Customer requested',
});

Cancel Immediately

End the subscription immediately:

javascript
await fyber.subscriptions.cancel('sub_123', {
  cancelAtPeriodEnd: false,
});

Subscription Stats

Get aggregate statistics:

javascript
const stats = await fyber.subscriptions.stats();

console.log(`Active: ${stats.activeCount}`);
console.log(`Trialing: ${stats.trialingCount}`);
console.log(`MRR: $${stats.mrr / 100} ${stats.mrrCurrency}`);

Subscription Object

json
{
  "id": "sub_abc123",
  "object": "subscription",
  "status": "active",
  "customerId": "cus_123",
  "tokenId": "tok_456",
  "amount": 999,
  "currency": "JMD",
  "interval": "month",
  "intervalCount": 1,
  "currentPeriodStart": "2024-01-15T00:00:00Z",
  "currentPeriodEnd": "2024-02-15T00:00:00Z",
  "trialEnd": null,
  "canceledAt": null,
  "cancelAtPeriodEnd": false,
  "metadata": {
    "plan": "pro"
  },
  "createdAt": "2024-01-01T10:30:00Z"
}

Webhooks

Listen for subscription events:

javascript
switch (event.type) {
  case 'subscription.created':
    // New subscription started
    break;
  case 'subscription.payment_succeeded':
    // Recurring payment successful
    grantAccess(event.data.object.customerId);
    break;
  case 'subscription.payment_failed':
    // Payment failed, may retry
    notifyCustomer(event.data.object.customerId);
    break;
  case 'subscription.trial_ending':
    // Trial ends in 3 days
    sendTrialEndingEmail(event.data.object.customerId);
    break;
  case 'subscription.canceled':
    // Subscription ended
    revokeAccess(event.data.object.customerId);
    break;
}

Handling Failed Payments

When a subscription payment fails:

  1. Fyber retries the payment automatically (up to 4 times over 2 weeks)
  2. You receive subscription.payment_failed webhook
  3. If all retries fail, subscription moves to canceled
  4. You receive subscription.canceled webhook

Notify customers about failed payments so they can update their card.

Fyber Payment API