Coupons

View as Markdown

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:

  • 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

TypeDescriptionExample
PercentagePercentage off the total (1-100%), accepting up to 2 decimal places (e.g. 16.67)20% off
Fixed amountFixed discount in a currency$10 off
Trial extensionAdditional free trial days14 extra days

Duration options

Control how long a discount lasts:

DurationBehaviorUse case
OnceApplies to first invoice onlyOne-time promotions
RepeatingApplies for N monthsLimited-time offers (e.g., “3 months free”)
ForeverApplies indefinitelyLoyalty discounts, partner pricing

Creating a coupon

Create coupons in the dashboard or via API:

  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

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:

$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:

RestrictionDescription
First-time onlyOnly customers with no prior transactions
Minimum amountMinimum order total required
Expiration dateCode expires after a specific date
Max redemptionsTotal number of times code can be used

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:

$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:

LevelScopeUse case
CustomerAll future subscriptionsVIP customers, partner accounts
SubscriptionSpecific subscriptionPromotional pricing on one plan
InvoiceSingle invoiceOne-time adjustment
Invoice itemSingle line itemPer-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:

StateCan redeem?Description
ActiveYesAvailable for use
InactiveNoManually paused, can be reactivated
DepletedNoMax redemptions reached (reactivates automatically if a redemption is released)
ExpiredNoPast expiration date (terminal)

Checkout integration

Apply coupons during checkout session creation:

$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:

$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:

$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.