Store → Affiliate Codes
Give partners a referral code they can publish, without building attribution yourself. You create the code through the Store MCP, a parent types it at checkout, and the Store records which affiliate drove the purchase. Payout share is attribution metadata — the Store does not settle partner payments.
Scope
Every affiliate belongs to exactly one of your apps. storeAppId is required on create_affiliate, and the tool checks your app:manage_store grant on that app before writing — so you can create affiliates for your own listings and only those. list_affiliates is the same scope: it requires storeAppId and returns only that app's rows. 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 an affiliate — they charge the catalog item price as configured.
Creating a Code
create_affiliate takes:
| Field | Required | Notes |
|---|---|---|
code |
yes | The string parents type. Case-insensitive and unique across the whole Store. |
name |
yes | Display name shown on the receipt. |
contactEmail |
yes | Email for payout and communication. |
payoutShareBps |
no | Integer 0–10000 (100 = 1%). Null or omit for no payout tracking. Attribution metadata only. |
storeAppId |
yes | The app the affiliate is scoped to. |
The code string is what the promoter has already published. It cannot be changed later.
What Stays Editable
update_affiliate takes the code plus any of:
| Field | Notes |
|---|---|
name |
Display name. |
contactEmail |
Email for payout and communication. |
payoutShareBps |
Integer 0–10000, or null to stop tracking a cut. |
state |
active or inactive. |
There is no app-scope field. An affiliate stays on the app it was created for.
This is deliberate, and it differs from discount codes. Affiliates touch Stripe nowhere, so no external identifier pins the code string. Renegotiating a partner's cut, or correcting a contact email, must not cost them a code they have already printed. Discount-code terms are frozen because they are a Stripe coupon; affiliate terms are not.
Retiring a Code
deactivate_affiliate 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.
Retirement is reversible. update_affiliate with state: active brings the same code back. Discount-code deactivation is permanent; affiliate deactivation is not, because recreating an existing unique code would conflict and strand a published string with no way back. deactivate_affiliate is the retirement verb; update_affiliate state is the way back.
Deactivating an already-retired code succeeds and changes nothing, so retries are safe.
Listing Your Affiliates
list_affiliates requires storeAppId and returns that app's affiliates, including retired ones and their current state. state (active or inactive) is the only optional filter.
Why a Code Was Rejected
Validation runs when the parent enters the code and again authoritatively when the checkout session is created. Checkout looks up active codes only, so a retired code is indistinguishable from a string that never existed. A rejection carries one of:
| Reason | Meaning |
|---|---|
unknown |
No active code with that string exists (never issued, or deactivated). |
app_mismatch |
The code belongs to a different app. |
Related Docs
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 → Discount Codes
Promo codes, which freeze terms at creation and cannot be reactivated.
Store → In-App Purchases
Server-to-server purchases, which affiliate codes do not apply to.
Store → Refunds
What happens to a purchase when it is refunded.
