Stripe Subscription Payment: Create and Apply Coupon for Subscription

Coupons for subscription

Ryohei Arai
Geek Culture
8 min readJul 10, 2021

--

Introduction

Coupon is one of the great ways to acquire new customers into your service. It’s providing customers with an incentive to buy your products. For marketing strategies, coupons can play a huge role to grow your business.

In this article, I will cover how to create a coupon and apply it to a new and existing subscription with Stripe API provided by Stripe that allows payment integration seamlessly into your apps. It can save you a tremendous amount of time in building payment-required apps.

Stripe is the most powerful payment infrastructure in the world.

Stripe handles almost all of the complex payment processing so that you can focus on developing apps such as e-commerce fully relying on their API. They also have a special checkout feature called Stripe Checkout which is a page created and maintained by Stripe.

In this example image displayed above, this Checkout does not include a coupon section but from settings, you can enable it for customers. The advantage of using this built-in page is that you are not required to write any single line of code in your app as customers are redirected to the checkout page to complete their purchases. If you want to add some logic in completing purchases, you can set up webhook in the backend too.

This feature is not going to be dwelled down in here, but for your reference, you can go check it here in detail. Although in-house development can cost a considerable amount of money and time, especially when engineers build it from scratch with its API, this feature opens up a new way that non-engineers can also effortlessly implement the payment system into an app. It comes with Apple Pay, Google Pay, Coupon features, and more — no code required. Very cool.

This article aims to help those who have apps that either are integrated or will be integrated with Stripe API. This guides you through understanding how discount in Stripe API works and implementing discounts for your app.

Before we dive into development, please let me first explain the difference between trial and coupon — key concepts in understanding discounts in Stripe. Because the difference is so important in order to integrate the discount feature into your app.

About Discount

When we hear “discount” we usually relate it to a shopping experience where you can buy goods such as shoes or accessories cheaper than the actual price — like let’s say 50% off or $5 off.

In Stripe, the discount is usually referred to as Trial and Coupon. They are mainly used for subscription payments where recurring charges occur. There is a distinct difference between them in discounting a subscription.

I summarized it below.

Trial

Trial in Stripe refers to a 100%-off discount on subscription until its free period ends.

This feature can only be used for recurring charges, subscription. You cannot use this feature for one time purchase because there is no trial on one time purchase.

Services such as Apple Music, Netflix, and Spotify are good examples. When you register for such services, you are sometimes given a “free months to use” period such as free 3 months from the registration. Until the end date arrives, you can use it for free. In other words, the discount is not flexibly customizable. For instance, the amount of a $1 coupon cannot be subtracted from $10.

As a developer, you can meet this requirement with the trial feature. You can specify an end date to enable this feature. After a free trial period ends, customers will be billed periodically for the whole subscription amount.

Coupon

Coupon in Stripe refers to a customizable discount on a subscription.

When you hear coupon, you maybe wonder if you can use this to one time purchase such as goods too. Stripe Checkout seems to accept it but if you want to use coupons to one time purchase on your end, you need a custom logic to adjust your product amount by the amount of coupon. Stripe does not have a feature to handle coupon on your product at the time of this writing 2021/07/10.

With Coupon API, you can make various types of discounts and distribute them to customers. If your business needs a 100% discount, the trial feature would be the best choice as you read the above section. But, if you want to make a $5 off discount from the total price or something, then Coupon API is going to be your option. You can of course use Coupon API to add a 100% discount on a subscription, but normally setting the trial would be better.

In addition to Coupon API, there is Promotion Code API, which also allows you to distribute coupon codes to customers. I have not researched enough to explain this feature, but as far as I understand, when it comes to promotion codes, how to distribute and manage coupons differs with its core feature remaining the same. One of the important points is you cannot customize the promotion code amount.

Each promotion code points to a specific coupon and references its coupon information. Due to this behavior, the coupon amount is not customizable. Also, if a parent coupon is deleted, promotion codes associated with it will no longer be available to use in the future.

It has other properties such as restrictions that Coupon API does not offer. In some cases, it seems that Promotion Code API probably has more flexibility in how to distribute and manage coupons than Coupon API in itself, but I am not sure about what are the best situations to use promotion codes. Because you can do everything you want with Coupon API without creating promotion codes. This is on my research list.

Okay, so this is probably enough information to grasp what the difference between Trial and Coupon is. Below, let’s actually start looking into how to create subscriptions with a trial and a coupon.

Development

I am not going to write everything in detail here, but instead, I will explain important elements for coupon and trial features with some snippets of code. For this section, I assume that you already have some familiarity with technologies such as javascript.

First, make sure that you are already registered into your Stripe Account and the test environment is set up. If you do not know how to set up your Stripe for testing, please refer to this page.

Trial on subscription via API

You can just set trial_end property at the time of a subscription creation. If the date arrives, the free period ends. Shortly before the trial ends, Stripe will trigger a webhook event. You can catch it from customer.subscription.trial_will_end to do something if you want to. For example, you can use email to notify customers that their free period is going to end. After the trial ends, an invoice will be automatically created for the next subscription cycle — customers will be ready to be billed.

const coupon = await stripe.subscriptions.create({
customer: customer_id,
items: [{plan: planid, quantity: 1}],
trial_end: 1610403705
});

For more reference: https://stripe.com/docs/billing/subscriptions/trials

Create a coupon via Stripe API

In order to implement Coupon API, first please refer to this page for your understanding about what are properties of the coupon object.

If you want to jump right into coding coupons, this video should help a lot. This official Coupon tutorial video by Stripe is very useful for development.

As the API doc describes, when you make a post request to create a coupon, you will receive an object below.

Response Object

{
"id": "25_5OFF",
"object": "coupon",
"amount_off": null,
"created": 1625883109,
"currency": "jpy",
"duration": "repeating",
"duration_in_months": 3,
"livemode": false,
"max_redemptions": null,
"metadata": {},
"name": "25.5% off",
"percent_off": 25.5,
"redeem_by": null,
"times_redeemed": 0,
"valid": true
}

Here I will explain properties and how you can define them for creating a coupon below.

Id: this is the coupon code that the user inputs in your checkout form or Stripe Checkout. Id has to be unique, otherwise, an error is thrown when you generate it via API.

Name: this is not required to specify. If it is missing, Stripe automatically fills it up with the text of the coupon code id. In the dashboard, coupons are displayed in a list with the title of the name. Good naming can be useful for managing coupons.

Amount: this is how much you want to take off from the subtotal of any invoices for a customer. If you want to take off $5 from a total price, then use amount_off, not percent_off.

Duration: this is an important concept in the creation of coupons. It has three properties called once, repeating, and forever. If you want a coupon to be applied once on a subscription, once is appropriate. If you want multiple months to be applied to a subscription, repeating is correct. Forever on subscription? As forever itself says, forever.

Duration_in_months: this is only available if you set duration as repeating. If you want to set three months $5 off from subscription, you can set repeating to 3. You must specify in that case.

Max_redemptions: this is the max number of coupon exchanges. If you set it as 5, the coupon is no longer available to use after 5 times.

Times_redeemed: this is the count of how many times the coupon is used. If you want to know how many times it is used, this property helps.

Redeemed_by: this is probably a new property that recently came out. This is an expiration date for a coupon. You can ignore this property by setting nothing or null.

Applies_to: this is probably a new property that recently came out. You can set hashed products ids in here to restrict products to be applied. If you only want certain products to be applied by a coupon, this should help.

Create Coupon Object via API

const coupon = await stripe.coupons.create({
amount_off: 5,
currency: 'usd',
duration: 'repeating',
duration_in_months: 3,
});

After successful coupon creation, the coupon should appear in the coupon section of your dashboard. Once a coupon is created, you cannot modify its properties except metadata.

Attach Coupon to Subscription

Instead of trial_end property shown above, here you assign a coupon. The billing price will be automatically calculated in the background and an invoice with the amount will be issued for customers. After all of the processing is done, you can fetch its object from the front end to display the discounted amount. This will be a bit tricky because Stripe does not change the plan amount if a coupon is attached. You need to fetch the subscription amount and discount amount from its fetched subscription object, and then calculate its billing price with these numbers accordingly.

// Create subscription with coupon
const coupon = await stripe.subscriptions.create({
customer: customer_id,
items: [{plan: planid, quantity: 1}],
metadata: { ...metadata },
coupon: coupon
});

After a coupon ends, an invoice will be automatically created for the next subscription cycle, which means customers will be billed without a coupon anymore. You can listen for an event called customer.discount.deleted to detect customers whose subscriptions are off coupons. You can email them or create a custom alert to display on your front-end to tell them their subscription is not available. This event is called before an invoice for the next cycle is created.

Update Subscription with Coupon

// Update subscription with coupon
const coupon = await stripe.subscriptions.update(subscription_id, {
coupon: coupon
});

For updating a subscription with a coupon, get the subscription id and coupon id and set on parameters of the update function. The updated subscription will be active when the next billing cycle begins.

For more reference: https://stripe.com/docs/billing/subscriptions/trials

Summary

I am not sure about what is the best use case for the promotion code, yet I successfully integrated the discount feature into our service — so far it’s been pretty good. In the future, I may update this article for Promotion Code API.

--

--

Ryohei Arai
Geek Culture

I like startup / fintech / commerce / productivity