Store → Discount Codes

Run promos on your Store listing without building redemption logic. You create a code through the Store MCP, a parent types it at checkout, and the Store validates it, prices it, and records which purchase it applied to.

Scope

Every discount code belongs to exactly one of your apps. storeAppId is required on create_discount_code, and the tool checks your app:manage_store grant on that app before writing — so you can create codes for your own listings and only those. A code presented at checkout for a different app is rejected as app_mismatch.

Codes apply to storefront checkout only. In-app purchases never carry a discount — they charge the catalog item price as configured.

Creating a Code

create_discount_code takes:

Field Required Notes
code yes The string parents type. Case-insensitive and unique across the whole Store.
discountType yes flat (fixed cents off) or percent (basis points off).
amountCents for flat Positive integer. Must be omitted for percent.
percentBps for percent 1–10000, where 100 = 1%. Must be omitted for flat.
currency for flat ISO 4217. Must be omitted for percent, since a percentage is currency-free.
storeAppId yes The app the code applies to.
expiresAt no ISO 8601. Must be in the future — Stripe rejects a past expiry. Omit for none.
maxRedemptions no Global cap across all parents. Omit for unlimited.
firstTimeCustomerOnly no, defaults false When true, only valid for a parent with no previous paid purchase.

A flat code only applies to a plan in the same currency; mismatches are rejected at checkout rather than converted.

Codes Are Immutable

There is no update tool. A code's terms are fixed the moment it is created.

This is deliberate. Your code string is also the identifier of the underlying Stripe coupon, and Stripe coupons cannot be edited — changing a discount means deleting and recreating the coupon. Because Stripe's discount records point at the coupon by ID rather than storing a copy of its terms, recreating one would retroactively rewrite what every past purchase appears to have been discounted by. Freezing terms at creation keeps your historical promo reporting honest.

To change a promo: deactivate the old code and create a new one with the new terms.

Retiring a Code

deactivate_discount_code takes the code and retires it. A retired code stops validating at checkout immediately, and purchases that already used it keep their attribution — your revenue history is unaffected.

Two consequences worth planning around:

  • Deactivation is permanent. There is no reactivation tool. Since terms are fixed at creation, a revived code would come back with exactly the terms you retired it for.
  • The string is spent. A retired code's string stays claimed forever and cannot be reused for a new code. Version your promo codes (LAUNCH20, LAUNCH20-Q2) rather than planning to recycle one.

Deactivating an already-retired code succeeds and changes nothing, so retries are safe.

Listing Your Codes

list_discount_codes requires storeAppId and returns that app's codes, including retired ones and their current state. discountType is the only optional filter. Each row carries redeemedCount so you can see how a promo is performing against its maxRedemptions cap.

Why a Code Was Rejected

Validation runs when the parent enters the code and again authoritatively when the checkout session is created. A rejection carries one of:

Reason Meaning
unknown No code with that string exists.
inactive The code was deactivated.
expired expiresAt has passed.
limit_reached maxRedemptions has been reached.
not_first_time firstTimeCustomerOnly is set and the parent has purchased before.
currency_mismatch A flat code's currency differs from the plan's currency.
app_mismatch The code belongs to a different app.

Store → Integration

The full MCP tool surface and the runtime entitlement check at app launch.

Store → MCP Setup

Connect Cursor / VS Code / Claude Code / ChatGPT to the Store MCP.

Store → In-App Purchases

Server-to-server purchases, which discount codes do not apply to.

Store → Refunds

What happens to a discounted purchase when it is refunded.