Skip to content
Create account or Sign in
The Stripe Docs logo
Search/Ask AI
Create accountSign in
  • Get started
  • Payments
  • Revenue
  • Risk
  • Data
  • Money management
  • Stablecoins
  • Embedded finance
  • Developer resources
More
APIs & SDKsHelp
Overview
Versioning
Changelog
Upgrade your integrationHow API versioning works
Essentials
SDKs
API
Events
Testing
Stripe CLI
Tools
Stripe Dashboard
Stripe Projects
Provisioning
Workbench
Developers Dashboard
Stripe for Visual Studio Code
Terraform
Stripe Discord server
Features
Workflows
Batch jobs
Stripe health alertsFile uploads
AI tools
Agent pluginsModel Context ProtocolAgent skillsStripe Directory
Extend Stripe
Overview
Build Stripe apps
Use apps from Stripe
Build extensions
    How extensions work
    Manage extension lifecycle
    Build a prorations extension with a script
    Build a custom action with a script
    Build a custom action with a remote function
    Extension points
    Scripts
    Custom actions
Custom objects
Security and privacy
Security
Activity logsStripebot web crawler
Privacy
Partners
Partner ecosystem
Partner certification
United States
English (United States)
  1. Home/
  2. Developer resources/
  3. Build extensions
Public preview

How extensions workPublic preview

Learn how you can customize Stripe with extensions.

Extensions let you run custom logic at designated places in Stripe called extension points. When Stripe has to run the logic at these extension points, it checks if an extension is plugged into them and if found, runs the custom logic in the extension.

For example, Stripe defines an extension point for prorations. When Stripe reaches the proration calculation step, it runs your extension’s logic instead of the default proration logic. Your extension determines how to prorate, returns the amount, and Stripe continues the billing flow with that result.

Stripe also defines a custom action extension point for Workflows. When a workflow triggers, Stripe calls your extension to send an email, update a CRM, or perform any other operation you define.

How the model works

Stripe defines extension points, designated places in Stripe products where your code can run. Each extension point specifies:

  • Input: The data Stripe sends to your extension when the extension point is reached, including input from the extension user
  • Output: The data your extension must return to Stripe
  • Allowed implementation types: Which implementation types (scripts, remote functions, or both) you can use at that extension point

Start by finding the extension point for your use case.

You build your custom logic as an extension that plugs into an extension point. We package extensions as part of Stripe Apps, which handles installation, permissions, and distribution. You can have multiple extensions packaged within the same app, of any implementation type: scripts, remote functions, or UI extensions. Apps can also contain custom objects.

Implementation types

Each extension point supports one or more implementation types. The implementation type determines where your code runs and how it interacts with external services.

Choose an implementation type

If an extension point supports both scripts and remote functions, use this table to decide:

ConsiderationScriptRemote function
Where it runsStripe managed runtimeYour infrastructure
LanguageTypeScriptAny language (HTTP endpoint)
External API callsExtension-point-dependent. Allowed for custom actions (through endpointFetch()). Not allowed for billing extension points.Yes, you make calls directly from your servers
Authorization for external servicesStripe injects secrets through the endpoint configuration and the Secret Store (where external API calls are allowed)You manage authentication yourself
Authorization from Stripe to your codeN/A, your code runs on StripeStripe signs each request. You verify the webhook signature.
Best forLogic that doesn’t need your own infrastructureLogic that needs your own systems, transforms, or non-TypeScript languages
LimitationsNo third-party dependencies, no raw fetch(), TypeScript onlyYou manage hosting, availability, and deployment

Scripts

Scripts are TypeScript methods that run on the Stripe fully managed runtime. You don’t need to host infrastructure because Stripe runs your code and you deploy by uploading your app through the Stripe CLI.

Scripts run your business logic when Stripe reaches an extension point. Use scripts when you need to:

  • Apply complex business rules using code, such as calculating a discount based on customer purchase history and sales events.
  • Validate or transform data before Stripe processes it, such as checking if a customer meets eligibility criteria.
  • Integrate external data into Stripe operations without building and maintaining webhooks.
  • Prototype quickly without deploying and managing your own services.

What scripts can do depends on the extension point:

  • At billing extension points (customer balance, item handling, prorations): Scripts receive data from Stripe, run your logic, and return a result. External API calls aren’t permitted. These extension points run in the billing pipeline, where Stripe restricts side effects to maintain reliability.
  • At the custom action extension point (for Workflows): Scripts can make external HTTP calls using endpointFetch(). You declare endpoints in your app manifest, and Stripe handles secret storage and authentication injection through the Secret Store. This is designed for actions that reach external services without requiring you to manage infrastructure.

Use cases

Use caseBilling behaviorScriptDescription
Set a minimum charge threshold.Customer balanceMinimum amount before collectionUse this script to avoid collecting on small invoices by deferring them to the customer balance until the total owed reaches a threshold you define. Use it when you want to accumulate charges across billing cycles before collecting, or avoid charging customers for small amounts.
Set a maximum of credit to apply to a single invoice.Customer balanceMaximum credit per invoiceUse this script when you want to spread credits across multiple billing cycles instead of applying them all at once, or when business rules require limiting credit usage per invoice.
Put metered usage items and licensed items on separate invoices.Invoice item creation and routingSeparate invoice for metered itemsUse this script when your finance team needs to reconcile usage charges separately from recurring seat or license fees, or when your customers expect different invoices for them.
Calculate prorations by hours, days, weeks, or months.ProrationProrate by custom intervalUse this script whenever your business needs proration calculated in units larger than a second, whether to match regional billing conventions, align with contractual terms, or reduce customer confusion caused by fractional amounts.
Refund or charge the full amount for some items in a subscription.ProrationCredit and debit full product priceUse this script when certain products on a subscription aren’t prorated. For example, a flat support fee or a platform access charge that’s always billed in full regardless of when the subscription changes.
Apply a percentage discount with a maximum amount.Discount calculationPercent off up to maximumUse this script to offer a percentage discount while limiting the maximum discount exposure on an invoice.
Give additional units of selected products for free.Discount calculationBOGO and quantity promosUse this script for quantity-based promotions on products selected by metadata.
Apply a fixed discount to selected prices.Discount calculationPrice-targeted amount offUse this script to take a fixed amount off prices selected by metadata without discounting unrelated invoice items.
Apply a percentage discount to selected prices.Discount calculationPrice-targeted percent offUse this script to apply a percentage promotion to prices selected by metadata without discounting unrelated invoice items.

Limitations

Most TypeScript features work on Stripe’s runtime, but the following patterns aren’t available. The build and upload steps catch these automatically:

  • Code evaluation such as eval() or new Function().
  • Timer functions such as setTimeout(), setInterval(), and setImmediate().
  • The WeakMap, WeakSet, WeakRef, FinalizationRegistry, performance, WebAssembly, SharedArrayBuffer, and Atomics globals.
  • Global scope access through global or globalThis.
  • Process APIs such as process.exit() or process.env.
  • Console output. console.log() and other console methods don’t produce output. Use Workbench to view the input, output, and error details for each run.
  • Embedded API keys or secrets. Use the Stripe secret store to manage sensitive values.
  • Network access APIs such as fetch(). Use endpointFetch() to invoke endpoints from a script.

Stripe doesn’t currently support third-party libraries as dependencies.

Remote functions

Remote functions are HTTP endpoints that you host on your own infrastructure. Stripe calls your endpoint when the extension point is reached, signing each request with a webhook signature so you can verify it came from Stripe.

You manage authentication for any external services your code calls, Stripe doesn’t inject secrets for remote functions. You verify the incoming Stripe signature, and you handle outgoing authorization yourself.

Use remote functions when you need to:

  • Run logic on your own servers or in your own environment
  • Integrate with your own systems such as an ERP or CRM
  • Use a language other than TypeScript

Limitations

Remote functions currently have the following limitations:

  • You manage hosting, availability, and deployment.
  • Your endpoints must respond within the timeout defined by the extension point (for example, 20 seconds for custom actions).

UI extensions

React components that display inside the Stripe Dashboard. Use a UI extension to present custom UI to Dashboard users. See UI extensions.

Permissions

When you build an extension, you must declare the permissions your extension needs. An extension can only access the data it has been granted permission to read or write. Users of extensions grant these permissions when installing the app that contains the extensions. See a complete list of all permissions.

Connected accounts

Your configured extensions don’t apply to your connected accounts. Connected accounts must configure the extension independently in their installed app.

Lifecycle

An extension can follow this lifecycle. Versioning, publishing, deprecation, and archival are optional:

  1. Build: You build an extension within a Stripe app.
  2. Upload: You upload the app using the Stripe CLI. Stripe processes it and makes it available to install.
  3. (Optional) Version: You upload new versions as you iterate.
  4. (Optional) Publish: You share the app through an external testing channel or the Stripe App Marketplace. It becomes available to install in their accounts.
  5. Install: You, or those the app is shared with, install it, accepting associated permissions.
  6. Activate: The app user activates an extension at its extension point.
  7. Invoke: Stripe calls the activated extension whenever it reaches the extension point.
  8. (Optional) Deprecate: The app user is prevented from activating a version of an extension, but extensions already activated on that version continue to run.
  9. (Optional) Archive: Activated extensions are moved to a compatible version, or prevented from running if a version isn’t defined.
  10. Deactivate: The app user deactivates the extension. It remains on the account but Stripe no longer calls it when it reaches the extension point.
  11. Uninstall: The app user removes the app and its extensions from the account.

Get started building

If you’re here for billing customizations, start with the step-by-step guide: Create a billing script extension. It covers prerequisites, app creation, CLI commands, and uploading.

The guide you follow otherwise depends on which extension point you’re building for:

  • Create a billing script extension to customize customer balance, item handling, or prorations behavior.
  • Create a custom workflow action with a script or remote functions. Learn more about How custom actions work.

For a complete list of available extension points and their supported implementation types, see extension points.

Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Chat with Stripe developers on Discord.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc
On this page