Skip to content

Coupons & Promotions Fresh

Apply discounts to subscriptions using coupons and promotion codes.

  • Coupons — define the discount (percent off or amount off, duration)
  • Promotion codes — customer-facing codes that map to coupons (e.g., FALL25OFF)

Create a coupon

bash
curl https://api.stripe.com/v1/coupons \
  -u "sk_test_YOUR_KEY:" \
  -d id=free-period \
  -d percent_off=100 \
  -d duration=once
ParameterDescription
percent_off or amount_offDiscount amount
currencyRequired if using amount_off
durationonce, forever, or repeating
duration_in_monthsRequired when duration=repeating
max_redemptionsMaximum total redemptions across all customers
redeem_byExpiration timestamp
applies_toLimit to specific product IDs

Duration behavior

  • once — applies only to the next invoice, then expires
  • forever — applies to all invoices indefinitely
  • repeating — applies for duration_in_months months

Note: After a duration=once coupon is applied, it no longer appears in the subscription's discounts array.

Apply a coupon to a subscription

bash
curl https://api.stripe.com/v1/subscriptions \
  -u "sk_test_YOUR_KEY:" \
  -d "customer=cus_123" \
  -d "items[0][price]=price_456" \
  -d "discounts[0][coupon]=free-period"

Or apply at Checkout:

bash
curl https://api.stripe.com/v1/checkout/sessions \
  -u "sk_test_YOUR_KEY:" \
  -d "line_items[][price]=price_456" \
  -d "line_items[][quantity]=1" \
  -d mode=subscription \
  -d "discounts[][coupon]=free-period" \
  -d success_url="https://example.com/success"

Delete a coupon

Deleting prevents future applications — it doesn't remove existing discounts.

bash
curl -X DELETE https://api.stripe.com/v1/coupons/free-period \
  -u "sk_test_YOUR_KEY:"

Promotion codes

Promotion codes are customer-facing strings that map to coupons.

bash
curl https://api.stripe.com/v1/promotion_codes \
  -u "sk_test_YOUR_KEY:" \
  -d coupon=free-period \
  -d code=FALL25OFF \
  -d "customer=cus_123"

Promotion codes are case-insensitive and unique across active codes. You can restrict by customer, first-time order, minimum amount, or expiration date.

Enable promotion codes in Checkout

javascript
const session = await stripe.checkout.sessions.create({
  // ...
  allow_promotion_codes: true,
});

This adds a promotion code redemption field to the Checkout page.

Deactivate a promotion code

bash
curl https://api.stripe.com/v1/promotion_codes/promo_123 \
  -u "sk_test_YOUR_KEY:" \
  -d active=false

Stackable discounts

Apply multiple coupons and promotion codes to a single subscription. The order matters when mixing percent_off and amount_off.

bash
curl https://api.stripe.com/v1/subscriptions \
  -u "sk_test_YOUR_KEY:" \
  -d "customer=cus_123" \
  -d "items[0][price]=price_456" \
  -d "discounts[0][coupon]=sub-coupon" \
  -d "discounts[1][promotion_code]=sub-promo" \
  -d "items[0][discounts][0][coupon]=item-coupon"

Restrictions:

  • Maximum 20 entries in discounts
  • Each entry must be unique
  • Cannot stack a coupon and a promotion code from the same coupon
  • Updating discounts replaces all existing discounts — pass all you want to keep

Alternative discount methods

  • Negative customer balance — applies as a credit on future invoices
  • Negative invoice items — more detailed, shows what discount was created and why
  • Second (discounted) price — create a cheaper price variant for specific customers

Stripe API Reference - Self-contained docs reference, refreshed 2026-05-18