Skip to main content

Subscriptions

Subscriptions let you charge customers on a recurring basis — monthly, annually, or on any custom interval. Meridian handles invoicing, payment retries, dunning, and cancellations automatically.

How subscriptions work​

A subscription ties three objects together:

  1. Product — what you're selling (e.g., "Pro Plan")
  2. Price — the cost, currency, and billing interval (e.g., $49/month)
  3. Customer — who you're charging

When a subscription is active, Meridian automatically generates an Invoice at the start of each billing period and attempts to collect payment.

Create a subscription​

Step 1 — Create a Product​

curl https://api.meridian.dev/v1/products \
-u sk_test_4eC39HqL...: \
-d name="Pro Plan" \
-d description="Unlimited projects and priority support"

Step 2 — Create a Price​

curl https://api.meridian.dev/v1/prices \
-u sk_test_4eC39HqL...: \
-d product=prod_Abc123 \
-d unit_amount=4900 \
-d currency=usd \
-d "recurring[interval]"=month

Step 3 — Subscribe the customer​

const subscription = await meridian.subscriptions.create({
customer: 'cus_Nk3mHXq7ViGwMz',
items: [{ price: 'price_XyzAbc456' }],
});

console.log(subscription.status); // 'active'

Subscription statuses​

StatusDescription
incompleteInitial payment pending.
incomplete_expiredInitial payment failed; subscription expired.
trialingIn a free trial period.
activePaid and up to date.
past_dueLatest invoice payment failed; retrying.
canceledSubscription was canceled.
unpaidAll retries exhausted; subscription suspended.
pausedBilling paused manually.

Cancel a subscription​

// Cancel immediately
await meridian.subscriptions.cancel('sub_Xyz123');

// Cancel at end of current billing period
await meridian.subscriptions.update('sub_Xyz123', {
cancel_at_period_end: true,
});

Listen for subscription events​

Subscribe to these webhook events to keep your app in sync:

EventWhen to act
customer.subscription.createdProvision access for new subscriber
customer.subscription.updatedUpdate access on plan change
customer.subscription.deletedRevoke access on cancellation
invoice.paidConfirm renewal succeeded
invoice.payment_failedNotify customer of failed payment
tip

Always use webhooks to gate access — don't rely solely on polling subscription.status at login time.