apply_promo_code_to_customer
Apply a registered Stripe promotion code to a customer's subscription, with dry-run preview and idempotent execution for safe application.
Instructions
Apply a user-facing promotion code already registered in Stripe (e.g. 'LAUNCH50') to your account's Stripe subscription (POST /v1/tier2/promo/apply). Founder-operations only (an internal support tool; general accounts get 403). It will not be opened up without terms covering economically impactful operations (timing undecided). 409 if an active discount already exists (structural defense against stacking), and 409 when the status is canceled / incomplete_expired. Redemption is delegated to Stripe via promotion_code (applying coupons directly is forbidden as a constraint bypass); dryRun must be passed explicitly, and idempotencyKey is required when dryRun=false. Re-calls with the same key return the cached result via the tier2_idempotency table, structurally serializing concurrent applies. dryRun=true previews resolution + the active-discount check + the estimated discount only (no Stripe mutation); dryRun=false applies the promotion code.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| dryRun | Yes | Must be passed explicitly. true = preview only; false = actual promotion-code application + Stripe mutation | |
| reason | Yes | Reason for applying it (recorded in the audit log; required, 200 chars max) | |
| promoCode | Yes | Promotion code already registered in Stripe (e.g. 'LAUNCH50'; alphanumerics plus '_-', 64 chars max) | |
| approvalId | No | Approval id granted via request_approval (apr_ + 32 hex; create with action 'apply_promo_code_to_customer'). Server-side verification + atomic consumption on a fresh execution (1 approval = 1 execution chain; retries with the same idempotencyKey do not re-consume). dryRun only verifies | |
| idempotencyKey | No | Required when dryRun=false. 16-128 chars alphanumeric plus '_-'; re-calls with the same key return the cached result | |
| targetAccountId | Yes | Target account id (your own account only for now; specifying another user gets 403) |