Billing
Additional features
Applying discounts

Applying discounts to subscriptions

Reduce the amount charged to a customer by discounting their subscription with a coupon.

Coupons in Stripe provide discounts on recurring charges. Like subscriptions, coupons allow for great flexibility in how you define and use them. They can:

  • Apply to every invoice, just one invoice, or for a certain length of time
  • Reduce invoices by a percentage or a flat amount
  • Apply to every subscription a customer has or only specific ones

You can even define a coupon that must be redeemed by a certain date or is limited to a set number of redemptions (across all of your customers).

Creating coupons

Coupons have the following parameters:

  • id, a unique identifier for the coupon
  • currency
  • percent_off or amount_off
  • duration, once, forever, or repeating
  • max_redemptions
  • redeem_by, the latest date at which this coupon can be applied to customers
  • applies_to, limits the items in an invoice that the coupon can apply to, but does not add restrictions to subscriptions

For duration, when using the value repeating, also specify duration_in_months as the number of months for which the coupon should repeatedly apply. Otherwise the coupon can be set to apply only to a single invoice or to them all.

The max_redemptions and redeem_by values apply to the coupon across every customer you have. For example, you can restrict a coupon to the first 50 customers that use it, or you can make a coupon expire by a certain date. If you do the latter, this only impacts when the coupon can be applied to a customer. If you set a coupon to last forever when used by a customer, but have it expire on January 1st, any customer given that coupon will have that coupon’s discount forever, but no new customers can apply the coupon after January 1st.

If a coupon has a max_redemptions value of 50, it can only be applied among all your customers a total of 50 times, although there’s nothing preventing a single customer from using it multiple times. (You can always use logic on your end to prevent that from occurring.)

You can limit the products that are eligible for discounts using a coupon by adding the product IDs to the applies_to hash in the Coupon Object. Any promotion codes that map to this coupon are also restricted to this list of elegible products. When adding a coupon with applies_to to a subscription with no applicable products, a discount of zero is generated.

When making changes to a subscription, any existing discounts are applied when proration is calculated. You cannot discount proration line items further on the invoice that’s generated.

Coupons can be created in the Dashboard or via the API, as shown here:

curl https://api.stripe.com/v1/coupons \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d duration=once \ -d id=free-period \ -d percent_off=100
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' coupon = Stripe::Coupon.create({ duration: 'once', id: 'free-period', percent_off: 100, })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' coupon = stripe.Coupon.create( duration='once', id='free-period', percent_off=100, )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $coupon = \Stripe\Coupon::create([ 'duration' => 'once', 'id' => 'free-period', 'percent_off' => 100, ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; CouponCreateParams params = CouponCreateParams.builder() .setDuration(CouponCreateParams.Duration.ONCE) .setId("free-period") .setPercentOff(new BigDecimal("100")) .build(); Coupon coupon = Coupon.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const coupon = await stripe.coupons.create({ duration: 'once', id: 'free-period', percent_off: 100, });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CouponParams{ Duration: stripe.String(string(stripe.CouponDurationOnce)), ID: stripe.String("free-period"), PercentOff: stripe.Float64(100), } free, _ := coupon.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new CouponCreateOptions { Duration = "once", Id = "free-period", PercentOff = 100, }; var service = new CouponService(); Coupon coupon = service.Create(options);

Discounting subscriptions

Once you’ve created a coupon, create a discount by applying the coupon to a subscription. You can do this when creating the subscription, as in the following code, or by updating an existing subscription.

curl https://api.stripe.com/v1/subscriptions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d customer=cus_4fdAW5ftNQow1a \ -d "items[0][price]"=price_CBb6IXqvTLXp3f \ -d coupon=free-period
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' subscription = Stripe::Subscription.create({ customer: 'cus_4fdAW5ftNQow1a', items: [{price: 'price_CBb6IXqvTLXp3f'}], coupon: 'free-period', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' subscription = stripe.Subscription.create( customer='cus_4fdAW5ftNQow1a', items=[{'price': 'price_CBb6IXqvTLXp3f'}], coupon='free-period', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $subscription = \Stripe\Subscription::create([ 'customer' => 'cus_4fdAW5ftNQow1a', 'items' => [['price' => 'price_CBb6IXqvTLXp3f']], 'coupon' => 'free-period', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SubscriptionCreateParams params = SubscriptionCreateParams.builder() .setCustomer("cus_4fdAW5ftNQow1a") .addItem( SubscriptionCreateParams.Item.builder() .setPrice("price_CBb6IXqvTLXp3f") .build()) .setCoupon("free-period") .build(); Subscription subscription = Subscription.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const subscription = await stripe.subscriptions.create({ customer: 'cus_4fdAW5ftNQow1a', items: [{price: 'price_CBb6IXqvTLXp3f'}], coupon: 'free-period', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" items := []*stripe.SubscriptionItemsParams{ { Price: stripe.String("price_CBb6IXqvTLXp3f"), }, } params := &stripe.SubscriptionParams{ Customer: stripe.String("cus_4fdAW5ftNQow1a"), Items: items, Coupon: stripe.String("free-period"), } subscription, _ := sub.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var items = new List<SubscriptionItemOptions> { new SubscriptionItemOptions {Price = "price_CBb6IXqvTLXp3f"} }; var options = new SubscriptionCreateOptions { Customer = "cus_4fdAW5ftNQow1a", Items = items, Coupon = "free-period", }; var service = new SubscriptionService(); Subscription subscription = service.Create(options);

If the effect of a coupon means no immediate payment is required, the subscription can be created even if the customer has no stored payment method (e.g. credit card).

Discounting customers

A coupon can be attached specifically to a subscription or broadly to a customer. A coupon added to a customer applies to all recurring charges for that customer. (Coupons never apply to standalone, nonrecurring charges.) For this reason, we recommend adding coupons to subscriptions, not customers, unless you’re certain you’ll always want to discount all recurring charges for a customer, even on subscriptions added later.

Attach a coupon to a customer when the customer is created, or by updating the customer.

Using coupons in Checkout

You can apply coupons to subscriptions in a Checkout Session by setting subscription_data.coupon. This parameter is similar to the one used when directly creating a subscription. This coupon overrides any coupon on the customer.

If you’re creating a subscription with an existing customer, any coupon associated with the customer is applied to the subscription’s invoices.

curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "line_items[][price]"="{{PRICE_ID}}" \ -d "line_items[][quantity]"=1 \ -d mode=subscription \ -d "subscription_data[coupon]"=co_123 \ -d success_url="https://example.com/success" \ -d cancel_url="https://example.com/cancel"
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'subscription', subscription_data: { coupon: 'co_123', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': '{{PRICE_ID}}', 'quantity': 1, }], mode='subscription', subscription_data={ 'coupon': 'co_123', }, success_url='https://example.com/success', cancel_url='https://example.com/cancel', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price' => '{{PRICE_ID}}', 'quantity' => 1, ]], 'mode' => 'subscription', 'subscription_data' => [ 'coupon' => 'co_123', ], 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; SessionCreateParams params = SessionCreateParams.builder() .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) .addLineItem( SessionCreateParams.LineItem.builder() .setPrice("{{PRICE_ID}}") .setQuantity(1L) .build()) .setMode(SessionCreateParams.Mode.SUBSCRIPTION) .setSubscriptionData( SessionCreateParams.SubscriptionData.builder() .setCoupon("co_123") .build()) .setSuccessUrl("https://example.com/success") .setCancelUrl("https://example.com/cancel") .build(); Session session = Session.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'subscription', subscription_data: { coupon: 'co_123', }, success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Price: stripe.String("{{PRICE_ID}}"), Quantity: stripe.Int64(1), }, }, Mode: stripe.String("subscription"), SubscriptionData: &stripe.CheckoutSessionSubscriptionDataParams{ Coupon: stripe.String("co_123"), }, SuccessURL: stripe.String("https://example.com/success"), CancelURL: stripe.String("https://example.com/cancel"), } session, _ := session.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1, }, }, Mode = "subscription", SubscriptionData = new SessionSubscriptionDataOptions { Coupon = "co_123", }, SuccessUrl = "https://example.com/success", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); var session = service.Create(options);

Negative invoice items and customer balances

Although coupons are the most common way to discount a subscription, you can also do so via negative invoice items or by adding a negative customer balance to the customer. Of the two options, we recommend using invoice items, which provide a better paper trail as to what discount was created, when, and why.

Deleting coupons

You can delete coupons via the Dashboard or the API. However, deleting a coupon does not remove the applicable discount from any subscription or customer. Deleting a coupon does prevent it from being applied to future subscriptions or customers, though.

Next steps

Now that you understand how to use coupons to create discounts, you may want to check out:

Was this page helpful?
Questions? Contact us.
Developer tutorials on YouTube.