> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.paymentkit.com/guides/product-catalog/discounts/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.paymentkit.com/_mcp/server.
# Coupons
> Create and manage discounts with coupons and promotion codes. Offer percentage discounts, fixed amounts, or extended trial periods with flexible rules and limits.
# How coupons work
The coupon system has three components:
```mermaid
flowchart LR
Coupon["Coupon
(Template)"] --> PromoCode["Promotion Code
(Shareable)"]
PromoCode --> Customer["Customer
Redeems Code"]
Coupon --> Discount["Discount
Applied to Subscription"]
Customer --> Discount
```
* **Coupons** - Reusable discount templates with rules and limits
* **Promotion codes** - Customer-facing codes that link to coupons
* **Discounts** - Applied instances of coupons on subscriptions or invoices
# Discount types
| Type | Description | Example |
| ------------------- | ---------------------------------------------------------------------------------- | ------------- |
| **Percentage** | Percentage off the total (1-100%), accepting up to 2 decimal places (e.g. `16.67`) | 20% off |
| **Fixed amount** | Fixed discount in a currency | \$10 off |
| **Trial extension** | Additional free trial days | 14 extra days |
# Duration options
Control how long a discount lasts:
| Duration | Behavior | Use case |
| ------------- | ----------------------------- | ------------------------------------------- |
| **Once** | Applies to first invoice only | One-time promotions |
| **Repeating** | Applies for N months | Limited-time offers (e.g., "3 months free") |
| **Forever** | Applies indefinitely | Loyalty discounts, partner pricing |
# Creating a coupon
Create coupons in the dashboard or via API:
#### Dashboard
1. Navigate to **Coupons** in the sidebar
2. Click **Create Coupon**
3. Configure discount type, amount, and duration
4. Set optional limits (max redemptions, expiration date)
5. Save the coupon
#### API
```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/coupons \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Summer Sale 20%",
"discount_type": "percent_off",
"percent_off": 20,
"duration": "repeating",
"duration_in_months": 3,
"max_redemptions": 100
}'
```
# Promotion codes
Promotion codes are shareable codes that customers enter at checkout. Each code links to a coupon and can have its own restrictions.
**Creating a promotion code:**
```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/promotion-codes \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"coupon_id": "cpn_abc123",
"code": "SUMMER20",
"max_redemptions": 50
}'
```
# Promotion code restrictions
Add additional rules to promotion codes:
| Restriction | Description |
| ------------------- | ----------------------------------------- |
| **First-time only** | Only customers with no prior transactions |
| **Minimum amount** | Minimum order total required |
| **Expiration date** | Code expires after a specific date |
| **Max redemptions** | Total number of times code can be used |
> **Note**
>
> Promotion code restrictions are checked **in addition to** the coupon's rules. Both must pass for the discount to apply.
# Product restrictions
Limit coupons to specific products:
```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/coupons \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Enterprise Discount",
"discount_type": "percent_off",
"percent_off": 16.67,
"duration": "forever",
"product_ids": ["prod_enterprise", "prod_enterprise_annual"]
}'
```
When product IDs are specified, the discount only applies to line items matching those products.
# Applying discounts
Discounts can be attached at different levels:
| Level | Scope | Use case |
| ---------------- | ------------------------ | ------------------------------- |
| **Customer** | All future subscriptions | VIP customers, partner accounts |
| **Subscription** | Specific subscription | Promotional pricing on one plan |
| **Invoice** | Single invoice | One-time adjustment |
| **Invoice item** | Single line item | Per-product discounts |
When more than one discount could apply, only the single highest-value coupon is used — discounts do not stack. Ties are broken in favor of the more specific level (invoice, then subscription, then customer).
# Coupon states
Coupons have a lifecycle with automatic state transitions:
| State | Can redeem? | Description |
| ------------ | ----------- | ------------------------------------------------------------------------------- |
| **Active** | Yes | Available for use |
| **Inactive** | No | Manually paused, can be reactivated |
| **Depleted** | No | Max redemptions reached (reactivates automatically if a redemption is released) |
| **Expired** | No | Past expiration date (terminal) |
# Checkout integration
Apply coupons during checkout session creation:
```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/checkout-sessions \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cus_abc123",
"line_items": [
{ "price_id": "price_xyz", "quantity": 1 }
],
"promotion_code": "SUMMER20",
"success_url": "https://example.com/success",
"return_url": "https://example.com/return"
}'
```
Or let customers enter a code on the hosted checkout page. The promo code
field is shown when the account's checkout field settings enable it
(`enable_promo_code`). The customer's entered code is applied to the session
through the token-scoped hosted-checkout endpoint:
```bash
curl -X POST https://app.paymentkit.com/api/checkout-sessions/token/{checkout_token}/promo-code \
-H "Content-Type: application/json" \
-d '{ "promotion_code": "SUMMER20" }'
```
# Invoice discount calculation
When an invoice is generated, discounts attached at the invoice, subscription,
and customer levels are all collected, and only the single highest-value coupon
is applied (discounts do not stack). On a value tie, the more specific level
wins, in this order:
1. Invoice-level discount
2. Subscription-level discount
3. Customer-level discount
**Percentage discounts:**
```
item_discount = item_amount × (percent_off / 100)
```
The result is truncated down to the smallest currency unit — a 16.67% discount
on 999 cents gives 166 cents, not 166.53.
**Fixed amount discounts (distributed proportionally):**
```
item_discount = total_discount × (item_amount / invoice_total)
```
# Validating promotion codes
Check if a code is valid before applying:
```bash
curl -X POST https://app.paymentkit.com/api/{account_id}/promotion-codes/validate \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"code": "SUMMER20",
"customer_id": "cus_abc123"
}'
```
The response indicates whether the code can be used and any restrictions that apply.
# Best practices
#### Use coupons as templates
Create coupons with business rules, then distribute via multiple promotion codes.
#### Set redemption limits
Always configure max\_redemptions for promotional campaigns to control costs.
#### Use validity periods
Set expiration dates to create urgency and manage campaign timelines.
#### Track redemption sources
Use different promotion codes for different channels to measure effectiveness.
---