Managing subscriptions with the API
On this page, we'll go through how you can handle things like changing plans, cancelling and pausing subscriptions with the Lemon Squeezy API.
Creating subscriptions
Read the Taking payments page to find out how to create checkouts and let customers sign up to your subscriptions products.
Saving product data in your database
In the Saving checkout and subscription data in your database section of this guide, we went through the data that should be saved locally in your app. To be able to let customers switch between plans in your app, you need to store a list of your Lemon Squeezy products.
The easiest way to get product and variant data into your app is by manually calling the list all variants endpoint whenever you edit or add products (alternatively you could set up a background job to fetch data more regularly).
We recommend you save data like the product_id
, variant_id
, name
and price
values so you can display them in your app.
Changing plans
To change a subscription’s product, make a PATCH
request to the individual subscription endpoint with the new variant ID.
The subscription will be instantly moved to the new product variant and you will be able to verify this by checking the response (which will contain a subscription object).
You can also manage subscription plans in the dashboard.
Handling proration
When a subscription’s plan (variant) is changed, proration will occur. Proration is the term used for calculating the difference between payment totals and lengths, making sure the customer is charged correctly for the time they spend across different products.
For example, if a customer moves from a $19/month plan to a $99/month plan, a prorated amount will be charged based on the new $99 plan relative to how much time they have already spent on the $19 plan.
By default, this extra amount will be added to the next renewal.
There are two options you can use to determine how proration is handled when changing plans.
The first option is "invoice_immediately": true
, which will create a new invoice during the plan change. The invoice total will be zero if there is nothing to pay (the customer is changing to a lower-priced plan). If the invoice total is greater than zero, a payment of the difference will be attempted.
You can disable proration completely by adding "disable_prorations": true
to your request. When using this option, the customer will not be charged a prorated amount and will simply move to the new plan's price at their next renewal.
If used together in the same request, disable_prorations
will always override invoice_immediately
.
Note that the change of plan on the Subscription is always immediate, regardless of the proration option applied.
This is how API proration options compare to the options listed in the Manage Subscription panel in the dashboard:
- Changing plans without
invoice_immediately
ordisable_prorations
is the same as "Apply changes with proration" (the default) - Using
"invoice_immediately": true
is the same as "Apply changes with proration and invoice immediately" - Using
"disable_prorations": true
is the same as "Apply changes without proration"
Cancelling and resuming subscriptions
To cancel subscriptions, send a DELETE
request to the individual subscription endpoint. In the response, you will get an updated subscription object, with cancelled
set to true
and status
set to cancelled
.
If a subscription is cancelled mid billing period (either by the customer or by the store owner), it will enter a “grace period” before it expires at the next scheduled renewal date (refected in a subscription's ends_at
value). The customer should still have access to your app or product until this date because they have paid for that time period.
During this cancelled
grace period, it’s possible to resume the subscription with a quick API call with cancelled
set to false
.
If a subscription is resumed like this, the subscription is changed back to active
and the original payment schedule will continue.
However, if a subscription is cancelled
and then reaches its next renewal date (ends_at
) without being resumed, it will instead expire (its status will change to expired
). When a subscription is in the expired
state, your customer should no longer have access to your app and the subscription is no longer resumable.
Pausing and unpausing subscriptions
Pausing a subscription is a great option if you want to keep a subscription active but pause regular payment collection. Maybe this is because your app will be inaccessible for a temporary period or you will be on holiday during a service-based retainer. Alternatively you may want to let your customers pause subscriptions if they won’t be able to make full use of your product for a certain period of time.
A paused subscription with have a status
of paused
.
To pause a subscription, send a PATCH
request containing a pause
object:
There are two mode
values you can use when pausing a subscription. Both stop payment collection temporarily. Use free
if you want to offer your product or service for free. Use void
if you can't provide your services for the period in question.
In the request you can also specify an optional resumes_at
value, which will unpause the subscription automatically on a certain date.
To manually unpause a paused subscription, make a PATCH
request with pause
set to null
. Similarly to resuming a cancelled subscription, the subscription will be changed to active and payment collection will resume on its original schedule.
Updating billing details
Letting your customers update their payment details during a subscription is an essential feature, especially when cards expire or if payments fail for any reason.
We provide a signed URL in every Subscription-related API request and webhook event in urls.update_payment_method
, which customers can use to easily update their billing details. We suggest you make this URL easily available to your customers, for example in your app’s billing pages.
Note: If you have a custom domain set up, update_payment_method
will contain your custom domain.
For security, the URLs returned by the API expire after 24 hours. You will need to query the subscription over the API for a refreshed URL.
To make the URL open in a more seamless overlay on top of your app (similar to the checkout overlay) use Lemon.js to open the URL with the LemonSqueezy.Url.Open()
method.
Note: During our payment recovery process any subscriptions with failed payments will have four retries before entering the (optional) dunning flow. After each payment retry and for each of the dunning series emails, we will send the same URL to the customer to update their billing details.
Changing the billing date
You can easily change the billing date of a subscription by specifying a billing_anchor
value in a request:
By default, a subscription’s billing_anchor
will match the date the customer initially signed up, but you can easily change it to any other day of the month. As an example, some businesses like to charge all customers on the first of each month.
When changing the billing_anchor
value of a subscription, a proration will occur to make sure the customer is not overcharged or undercharged when the length of their billing period changes.
Note: If the current month doesn’t contain the day that matches your billing_anchor
(for example, if the billing_anchor
is 31 and the month is November), the customer will be charged on the last day of the month.
You can use null
or 0
to easily change the billing anchor to the current date. Doing this will also remove any active trial period.
Update a subscription's quantity
Go to the Usage-based billing page to find out how to update a subscription's quantity or usage.