Subscriptions

How to create plans, attach subscriptions, and handle billing cycles.

Overview

The Subscriptions API automates recurring billing. You define a billing plan, a customer subscribes, and PayMongo generates invoices and collects payment on each cycle automatically. Account configuration is required before going live — contact PayMongo support to enable subscriptions on your account.

Supported payment methods: Visa/Mastercard cards and Maya. GCash, GrabPay, and ShopeePay are not supported. Card-based subscriptions require Card Vaulting — the customer's card must be stored on a Customer object.


Create a subscription

To set up a subscription you need three things: a plan, a customer, and a subscription linking the two.

Create a plan — defines the billing amount, currency, and interval. One plan can be reused across many subscriptions.

const plan = await fetch('https://api.paymongo.com/v1/plans', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('sk_test_YOUR_SECRET_KEY:')
  },
  body: JSON.stringify({
    data: {
      attributes: {
        name: 'Monthly Pro Plan',
        amount: 29900,
        currency: 'PHP',
        interval: 'month',
        interval_count: 1
      }
    }
  })
}).then(r => r.json());

Create a customer — represents the subscriber in PayMongo.

const customer = await fetch('https://api.paymongo.com/v1/customers', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('sk_test_YOUR_SECRET_KEY:')
  },
  body: JSON.stringify({
    data: {
      attributes: {
        first_name: 'Juan',
        last_name: 'dela Cruz',
        email: '[email protected]',
        phone: '09171234567'
      }
    }
  })
}).then(r => r.json());

Create a subscription — links the customer to the plan. PayMongo generates the first invoice immediately.

const subscription = await fetch('https://api.paymongo.com/v1/subscriptions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('sk_test_YOUR_SECRET_KEY:')
  },
  body: JSON.stringify({
    data: {
      attributes: {
        plan_id: 'plan_xxx',
        customer_id: 'cus_xxx'
      }
    }
  })
}).then(r => r.json());

The first invoice generates a Payment Intent. Direct the customer through the normal payment flow — this also vaults their payment method for future cycles. The customer must complete this first payment within 24 hours or the subscription is automatically cancelled.

Subscription and invoice statuses

Subscription statusWhat it means
incompleteWaiting for the customer to complete the first payment
incomplete_cancelledNot paid within 24 hours — create a new subscription to retry
activeAll invoices paid; service can be provided
past_dueLatest invoice failed — PayMongo retries once per day, up to 3 times
unpaidStill unpaid after 3 retries — consider pausing service
cancelledSubscription was cancelled; no new invoices will be generated
Invoice statusWhat it means
draftGenerated 1 day before the billing date; amount can still be adjusted
openFinalized 12 hours after draft; payment attempt is made
paidPayment succeeded
voidInvoice was cancelled

Manage a subscription

Cancel a subscription — takes effect immediately. Any existing open invoices remain collectible.

await fetch(`https://api.paymongo.com/v1/subscriptions/${subscriptionId}`, {
  method: 'DELETE',
  headers: {
    'Authorization': 'Basic ' + btoa('sk_test_YOUR_SECRET_KEY:')
  }
});

Change the plan — plan changes take effect at the next billing cycle; the current cycle continues at the original plan rate.

Change the payment method — the customer must re-authenticate. PayMongo authorizes a small test amount on the new card then cancels it. The subscription continues with the new method from the next cycle.


On-demand subscriptions

On-demand subscriptions give you full control over when each billing cycle is charged. PayMongo links the customer's payment method to a plan but does not automatically collect future payments — you trigger each invoice manually by calling the Initiate On-Demand Payment endpoint.

Only Maya is supported for on-demand subscriptions.

The recurring schedule is your responsibility. PayMongo does not manage when or how often to charge customers. You must inform customers of the payment schedule.

Create a plan with type: "on_demand". The amount on an on-demand plan only applies to the first payment — you set the amount for each subsequent cycle when triggering the invoice.

const plan = await fetch('https://api.paymongo.com/v1/plans', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa('sk_test_YOUR_SECRET_KEY:')
  },
  body: JSON.stringify({
    data: {
      attributes: {
        name: 'Insurance Monthly Plan',
        type: 'on_demand',
        amount: 100000,
        currency: 'PHP'
      }
    }
  })
}).then(r => r.json());

The setup flow (create customer, create subscription, first payment) is the same as a regular subscription. For each subsequent cycle, call the Initiate On-Demand Payment endpoint — PayMongo creates the invoice and attempts to charge the stored payment method automatically, up to 3 attempts 24 hours apart.