Promotion Codes

Discounts belong entirely to the billing provider. Nothing about a code is stored locally, there's no coupons table, and no sync command keeping amounts current. A code is a string the customer types, and the provider decides what it's worth.

During checkout

Signups run through the provider's embedded checkout, which has its own promotion code field. The customer enters a code there, the provider validates it against its own rules, and the discount applies to the subscription it creates. The API isn't involved and doesn't need an endpoint for it.

That's the main reason checkout is embedded rather than assembled from payment elements. Codes, tax, and card authentication all become the provider's problem in one move.

On an existing subscription

Admins can apply a code to a subscription that's already running, or clear the discounts off one. That path does go through the API, so it resolves the code against the provider first and rejects anything expired, exhausted, or unknown before attaching it.

Removing clears all discounts rather than picking off a single code, since stacking isn't something the starter models.

What the provider owns

Percentage or fixed amount, currency, expiry, redemption limits, first-time-customer restrictions, and which products a code applies to. All of it lives in the provider's dashboard, none of it is mirrored locally, and marketing can create or retire codes without a deploy.

The tradeoff is that resolving a code is an API call, which is why it sits behind a deliberate admin action rather than anywhere in a render path.

© Websanova 2026 About Privacy