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| Parameter | Description |
|---|---|
percent_off or amount_off | Discount amount |
currency | Required if using amount_off |
duration | once, forever, or repeating |
duration_in_months | Required when duration=repeating |
max_redemptions | Maximum total redemptions across all customers |
redeem_by | Expiration timestamp |
applies_to | Limit to specific product IDs |
Duration behavior
once— applies only to the next invoice, then expiresforever— applies to all invoices indefinitelyrepeating— applies forduration_in_monthsmonths
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=falseStackable 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
discountsreplaces 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