Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Finance automation
Platforms and marketplaces
Money management
Developer tools
Get started
Payments
Finance automation
Get started
Payments
Finance automation
Platforms and marketplaces
Money management
Overview
Billing
    Overview
    About the Billing APIs
    Subscriptions
      Overview
      Quickstart
      Use cases
      Build your integration
      Subscription features
        Subscription invoices
        Subscription schedules
        Subscription pricing
        Recurring pricing models
        Embed a pricing table
        Start subscriptions
        Set quantities
        Set billing cycles
        Backdate subscriptions
        Subscribe to multiple items
        Set trial periods
        Apply coupons
          Custom discount scripts
        Migrate subscriptions to Stripe
        How credit prorations are calculated
        Subscription payments
        Subscription payment methods
        Integrate with third-party payment processing
        Collection methods
        Share a link to update payment details
        Strong Customer Authentication (SCA)
        Manage subscriptions
        Modify subscriptions
        Manage pending updates
      Analytics
    Invoicing
    Usage-based billing
    Connect and Billing
    Tax and Billing
    Quotes
    Revenue recovery
    Automations
    Scripts
    Revenue recognition
    Customer management
    Entitlements
    Test your integration
Tax
Reporting
Data
Startup incorporation
HomeFinance automationBillingSubscriptionsSubscription featuresApply coupons

Extend Stripe Billing with custom discount logicPrivate preview

Implement custom logic to compute discount amounts for subscriptions and invoices.

Stripe Billing lets you configure a coupon with custom logic to compute the discount amount for subscriptions and invoices, beyond fixed percentages or amounts off. Here are some examples of what you can do with a single coupon:

  • Provide 10% off for annual subscribers, but no discount for monthly subscribers.
  • Provide 20% off, but up to a maximum of 1000 USD. Only provide this for your high-value customers (tagged using metadata).
  • Provide tiered discounts (for example, 100 USD off if more than 10 seats are purchased, otherwise 30 USD off).

Get started

To understand how custom logic integrates with the billing workflow, you can explore the Stripe-authored scripts available to Billing users in our script SDK.

You can use these scripts as a foundation to build your own logic using our scripting language. We recommend starting in a sandbox.

Use Stripe-authored custom logic

You can create a coupon with Stripe-authored custom logic by navigating to the Create a Coupon page and selecting Percentage off up to maximum type. This gives you an idea of how custom logic scripts are applied to a coupon before authoring your own script.

Create a coupon

We recommend starting this process in a sandbox. We don’t support scripts in test mode. For any testing, you must use a sandbox environment.

Create a coupon with no code

You can create a coupon with Stripe-authored custom logic by navigating to the create a coupon page, and using the Percentage off up to maximum coupon type, which uses a Stripe-authored script.

Create a coupon using the API

To create script coupons with the API, refer to the table below for the script specifications.

Name ID Script definition
Percentage off up to maximumbfsimpl_61S9T2y7zlKu9YlG116S8pZoN2SQpuwOX348dhXM0R9cSee script definition
Configuration fields
{ max_discount_amount: { amount: number; currency: string; }, discount_percent: number; }
  • max_discount_amount.amount: value in the currency’s minor unit
  • max_discount_amount.currency: The three-letter ISO code for the currency
  • discount_percent: value as percentage

For example, configuring a 20% off up to 100 USD coupon using Percentage off up to maximum looks like this:

Command Line
cURL
curl https://api.stripe.com/v1/coupons \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d duration=forever \ -d name="My coupon" \ -d "script[id]"=bfsimpl_61S9T2y7zlKu9YlG116S8pZoN2SQpuwOX348dhXM0R9c \ -d "script[configuration][max_discount_amount][amount]"=10000 \ -d "script[configuration][max_discount_amount][currency]"=usd \ -d "script[configuration][discount_percent]"=20

Apply a coupon

After creating the coupon, apply it to subscriptions or invoices following the same process as for a standard coupon. See coupons for detailed instructions.

Script coupon limitations

Script coupons have the following limitations:

  • You can’t use script coupons on line item coupons.
  • You can’t stack script coupons with other coupons.
  • You can’t use script coupons on Quote objects.
  • You can’t use script coupons on Customer objects.

Author a script

To meet specific business needs, you can create your own custom logic using our scripting language.

Note

You’re responsible for checking that your script reflects your desired functionality. Make sure not to enter any proprietary, confidential information (for example, PII), or malicious code.

Discount calculator interface

All coupon scripts must abide by the discount calculator interface defined by Stripe.

Discount calculator interface
export type DiscountFunction<T> = ( configuration: T, discountableItem: DiscountableItem, ) => DiscountResult;

Configuration

You can define configuration values that users must provide when they’re creating a script type coupon. The configuration values set for the coupon are passed into the discount function each time you invoke it.

Sample script configuration
export type DiscountCalculatorConfiguration = { max_discount_amount: { amount: number; currency: string; }, discount_percent: number; };

DiscountableItem

We pass the DiscountableItem into the discount calculator and make this data available for you to use within your script. As an example, the discountable item might look like the following. For the latest definition of the parameter, refer to our SDK.

DiscountableItem definition
export interface DiscountableLineItem { subtotal: MonetaryAmount; price_id?: string | null; quantity?: number | null; unit_amount?: MonetaryAmount | null; period: TimeRange; price?: Price | null; } export interface DiscountableItem { line_items: Array<DiscountableLineItem>; gross_amount: MonetaryAmount; customer?: Customer | null; billing_reason?: BillingReason | null; subscription?: Subscription | null; }

DiscountResult

Your script must return a discount result.

Discountable result
export interface DiscountResult { discount: Discount; }

Example of returning a discount result:

Sample Discountable result (truncated)
return { discount: { amount: { amount: discountAmount, currency: item.gross_amount.currency, }, }, };

Best practices

  • Use Stripe defined types in your configuration where possible (for example, MonetaryAmount)
  • Perform a currency check before applying your discount.

Sample Scripts

If you have access to the private preview, you can submit your custom discounting logic to the Stripe Billing team through email. The below sample scripts allow you to get a sense of the custom logic you can create, and gives you a template to start working with.

Percentage-off discount with a maximum amount

Percent-up-to-max script (truncated)
import type { DiscountCalculationFunction, DiscountableItem, DiscountResult, } from '@stripe/scripts/discount_calculation'; import type {PositiveMonetaryAmount, Percent} from '@stripe/scripts'; /** * Configuration for the discount calculator function */ export type DiscountCalculatorConfiguration = { max_discount_amount: PositiveMonetaryAmount; discount_percent: Percent; }; /** * Gives a percentage off discount up to a maximum discount amount * * @param {DiscountCalculatorConfiguration} config-The configuration containing max discount amount and discount percent * @param {DiscountableItem} item-The item to apply discounts to * @returns {DiscountResult} The discounts applied to the item */ const percentOffUptoMaxDiscount: DiscountCalculationFunction< DiscountCalculatorConfiguration > = ( config: DiscountCalculatorConfiguration, item: DiscountableItem, ): DiscountResult => { const {max_discount_amount, discount_percent} = config; let discountAmount = 0; if ( item.gross_amount.currency.toLowerCase().trim() === max_discount_amount.currency.toLowerCase().trim() ) { const discountAmountValue = (item.gross_amount.amount * discount_percent) / 100; discountAmount = Math.min(discountAmountValue, max_discount_amount.amount); } return { discount: { amount: { amount: discountAmount, currency: item.gross_amount.currency, }, }, }; }; export default percentOffUptoMaxDiscount;

Test your script

We recommend that you test Stripe-authored logic to get familiarized with the workflow. If you have access to the private preview, we load your custom logic into a sandbox on your account, where you can go through the necessary testing to verify that it’s working as expected. After you validate it in your sandbox environment, Stripe uploads your script to your production account.

Submit your script for review and testing

After you’re accepted to the private preview, you receive access to an SDK with tools for authoring, testing, and packaging scripts. You can submit your packaged scripts to Stripe for review.

Upon approval, we’ll import your custom logic into a sandbox of your choice for testing before you apply it to your production environment.

Private-preview eligibility criteria

This feature is in private preview and still under development. Functionality can change as we continue development of scripts. Be aware of the following considerations:

  • You can only attach script coupons to subscriptions or invoices.
  • During the preview, you can’t distribute scripts to connected accounts in Connect.
Was this page helpful?
YesNo
Need help? Contact Support.
Join our early access program.
Check out our changelog.
Questions? Contact Sales.
LLM? Read llms.txt.
Powered by Markdoc