# Billing scripts Use scripts to program custom billing logic that runs directly on Stripe. Using [a subset of Typescript](https://docs.stripe.com/billing/scripts/script-language.md), you can write and submit custom logic in Stripe. With scripts, you can: - Define your own logic for specific Stripe objects - Tailor your Stripe account for your specific business needs - Extend Stripe beyond its standard functionality For example, you can use scripts to [create custom discount logic on new coupons](https://docs.stripe.com/billing/subscriptions/script-coupons.md), and then apply the coupons to Subscriptions and Invoices. ## Script lifecycle See the following script lifecycle to understand how to use scripts: - Start by authoring custom logic for a supported use case. - As part of script-authoring, you can define configuration values. These are parameters that a script user passes when creating a custom object. - Stripe registers your script on the script service after you submit it for review. - You can then invoke the script when creating objects, such as a `Coupon` or `Subscription` object. ## Function arguments You can place the argument of the functions into two categories: ### Author-defined values You can think of author-defined values having two audiences: - **Script author**: The script author defines the function (that is, the actual logic) and the input values to the function. For example, you could write a “percent-up-to-a-maximum” script where the author defines two input values (`percent` and `maximum`). - **Script user**: After the script author defines the values, the script user can define the values for the two inputs through the Dashboard or API (for example, 10% off a 100 USD maximum). The script author decides what parts of the script to make customizable for the script user. The script user then applies their own values to the customizable parts of the script. ```typescript export type scriptConfiguration = { max_discount_amount: { amount: number; currency: string; }, discount_percent: number; }; ``` [The SDK](https://github.com/stripe/scripts/blob/main/src/types.ts) provides built-in types that you can use as part of your configuration definition. These built-in types render with a relevant input field UI in the Dashboard. If you have suggestions for new built-in types, contact [scripts-preview@stripe.com](mailto:scripts-preview@stripe.com) or our Support team. ```typescript import type {PositiveMonetaryAmount, Percent} from '@stripe/scripts'; export type scriptConfiguration = { max_discount_amount: PositiveMonetaryAmount; discount_percent: Percent; }; ``` Configuration values have default schema validations when the script user tries to set the values. In addition, you can define custom validation by referencing the [schema validations](https://docs.stripe.com/billing/scripts/script-language.md#schema-validation). If we don’t support your validation use case, we recommend building the validation check into your function definition and contacting [scripts-preview@stripe.com](mailto:scripts-preview@stripe.com). ### Stripe-defined values Stripe provides argument values at function runtime that you can’t customize, such as the `Customer` or `DiscountableLineItem` objects. The specific objects vary by function interface. If you’re missing any data you need, contact [scripts-preview@stripe.com](mailto:scripts-preview@stripe.com). We also pass a `RunContext` object to your function that provides execution context for the current run (for example, which account is executing, whether it’s livemode, and the current clock time). This is available as the first argument to your function (for example, `context: RunContext`). ```typescript export interface RunContext { account_id: string; livemode: boolean; clock_time: Date; } ``` ```typescript /** * DiscountableLineItem data structure * * @typedef {Object} DiscountableLineItem * @property {MonetaryAmount} subtotal * @property {number | null} quantity * @property {TimeRange} period * @property {Price | null} price */ export interface DiscountableLineItem { subtotal: MonetaryAmount; quantity?: number | null; period: TimeRange; price?: Price | null; } ``` ## Function logic The script author defines the customization used by the script function logic. All arguments are “pass by value,” which means any modifications made to the argument values within the function don’t affect the original value outside the function. ### Handling runtime errors appropriately In most cases, you want to catch the error and have fallback behavior. In rare cases, you might want to throw an exception. Throwing an exception halts the entire code execution associated with the script, so only throw an exception when no other option exists. ### Write tests Although we don’t mandate that you use an automated test suite with your script function, we recommend it. You can write tests against your sandbox environment or in test mode. If you need guidance, contact [scripts-preview@stripe.com](mailto:scripts-preview@stripe.com) ### Function return value The return value of the function must abide by the interface, which varies by customization. Consult the [SDK](https://github.com/stripe/scripts) for the specific interface definition, and make sure your function abides by the interface. ## See also - [Script coupons](https://docs.stripe.com/billing/subscriptions/script-coupons.md)