Subscriptions

Learn how to accept recurring crypto payments using Pluto.

Subscriptions allow you to charge customers by sending invoices on a recurring basis. Invoices must be paid manually, as Pluto does not currently support automatic billing. However, this will be made possible in the future by the addition of ERC-20 subscriptions, which will allow customers to set a token allowance that Pluto can automatically debit. The release of Pluto-managed custodial wallets will also allow for automatic recurring transactions.

Subscription lifecycle

All subscriptions start as either incomplete or trialing. They can subsequently be updated to active, past_due, or canceled.

  • incomplete: The subscription has been created, but still requires an immediate payment to be activated.
  • trialing: The subscription has been created successfully and does not require a payment until the trial period has been completed.
  • active: The subscription has been activated.
  • past_due: The latest invoice of the subscription is open and awaiting payment.
  • canceled: The subscription has been terminated and is no longer generating invoices.
227

Billing cycle

Billing invoices are generated automatically by the subscription. Subscriptions that are begin as trialing will not generate an invoice until the trial period is over. If you give customers a 7-day free trial, they won't receive their first invoice until the 7 days have passed. For subscriptions that require a payment upfront, an invoice will be generated immediately. This invoice can be accessed by retrieving the latest_invoice property of the subscription.

You can see the current billing period of a subscription by retrieving its current_period_start and current_period_end. Pluto automatically advances them when a subscription transitions from trialing to active, or when an active subscription reaches the end of its billing period. For instance, a monthly subscription purchased on Jan. 15th will have a current_period_start of Jan. 15th and a current_period_end of Feb. 15th. On Feb. 15th, the periods will be respectively updated to Mar. 15th and Apr. 15th, and a renewal invoice will be generated.

Subscriptions determine how often to generate invoices from their price, which stores the billing period duration in days. If the latest renewal invoice is not paid by its due date, the invoice will be marked as past_due and the subscription will be canceled. You can configure how long an invoice can remain open by setting "retry period days" in the dashboard. If an open renewal invoice is voided or marked as uncollectible prior to its due date, it will not be marked as past_due when the due date passes.

As an example, consider a monthly subscriber whose current period is Sept. 1 to Sept. 30th. If they haven't paid their renewal invoice due on Sept. 4th and you manually void it on Sept. 3rd, their subscription will remain active through the month of September. They will not be issued another invoice until Sept. 30th.

Add a trial period

You can specify the trial's duration by passing trial_period_days when creating a subscription.

const { Pluto } = require('@plutohq/pluto');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);

const subscription = await pluto.subscriptions.create({
  customer: '{{CUSTOMER_ID}}',
  price: '{{PRICE_ID}}',
  trial_period_days: 3,
});

Add additional fees to a subscription

One-time fees can be added by passing line_items to a subscription upon creation. For each line item, you can either pass existing price or pass an amount. Specifying an amount will create an archived price once the subscription is created.

Currently, a price is required for subscriptions, and each line item must match the currency and chain of this price. In the future, the price field will be optional. Additionally, you will be allowed to specify recurring prices in line_items as long as they have a consistent billing period, which is not currently supported.

const { Pluto } = require('@plutohq/pluto');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);

const subscription = await pluto.subscriptions.create({
  customer: '{{CUSTOMER_ID}}',
  price: '{{PRICE_ID}}',
  line_items: [
    // Using an existing price
    {
      price: '{{PRICE_ID}}',
      description: 'Existing price'
    },
    // Passing an amount
    {
      price_data: {
        amount: 0.2,
        description: '0.2 ETH initial fee',
      },
    },
  ],
});

Cancel a subscription

Cancelling a subscription can be done by making a DELETE request to the Subscriptions API or by using the SDKs.

const { Pluto } = require('@plutohq/pluto');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);

await pluto.subscriptions.cancel('{{SUBSCRIPTION_ID}}');

Cancel a subscription at a specific date

If a subscription has cancel_at_period_end set to true, Pluto will cancel it when it reaches the end of its billing period. Similarly, setting the cancel_at field will automatically cancel the subscription at the date specified.

const { Pluto } = require('@plutohq/pluto');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);

// Cancel at billing period end
await pluto.subscriptions.update('{{SUBSCRIPTION_ID}}', {
  cancel_at_period_end: true,
});

// Cancel at a set time
await pluto.subscriptions.update('{{SUBSCRIPTION_ID}}', {
  cancel_at: 1663029668784,
});

Change the billing period end of a subscription

Suppose you want to gift a subscriber a free week after the end of their subscription. This can be accomplished by updating the billing period end to 7 days in the future. It is important to note that this is different than modifying the billing period of a subscription, which means changing the duration of the billing period entirely — for example changing a monthly subscription to a weekly subscription.

const { Pluto } = require('@plutohq/pluto');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);

await pluto.subscriptions.update('{{SUBSCRIPTION_ID}}', {
  current_period_end: 1663023407495,
});

Update the price of a subscription

You can update the billing period or cost of a subscription by updating its price. Currently, Pluto does not support proration.

Consider a user paying 10 SOL/month for a subscription with a billing period of Jun. 1st - Jun. 30th. If the user upgrades their plan to 30 SOL/month on Jun 15th, with proration, they would be billed 20 SOL on Jun. 30th. This value is calculated by comparing the amount of time the user was on each plan (10 SOL 0.5 months) + (30 SOL 0.5 months). Without proration, the user would be billed 30 SOL for the month of June. Although prorated subscriptions are not supported now, they will be added as an option in the future.

const { Pluto } = require('@plutohq/pluto');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);

await pluto.subscriptions.update('{{SUBSCRIPTION_ID}}', {
  price: '{{PRICE_ID}}',
});

Change the billing period of a subscription

To update the billing period, you will have to update the subscription's price.

Pause a subscription

Pausing a subscription will prevent it from generating invoices while it is paused, and the billing period will not be advanced. If it is resumed before its original billing period end, Pluto will wait until the period end to generate a renewal invoice. Otherwise, an invoice will be generated immediately.

const { Pluto } = require('@plutohq/pluto');
const pluto = new Pluto(process.env.PLUTO_SECRET_KEY);

await pluto.subscriptions.update('{{SUBSCRIPTION_ID}}', {
  pause_collection: true,
});