Skip to main content

Overview

Coupons in FlexPrice provide flexible discount mechanisms for subscriptions and invoices. They support fixed amount and percentage discounts, time-limited redemption periods, usage limits, and rule-based application logic.

Coupon Structure

{
  "id": "coupon_spring2024",
  "name": "Spring 2024 Promotion",
  "type": "percentage",
  "percentage_off": "25.0000",
  "amount_off": "0.00",
  "currency": null,
  "cadence": "repeated",
  "duration_in_periods": 3,
  "redeem_after": "2024-03-01T00:00:00Z",
  "redeem_before": "2024-04-01T00:00:00Z",
  "max_redemptions": 100,
  "total_redemptions": 23,
  "rules": {
    "apply_to": "invoice",
    "conditions": [
      {
        "field": "plan_id",
        "operator": "in",
        "value": ["plan_premium", "plan_enterprise"]
      }
    ]
  },
  "metadata": {
    "campaign": "spring_promo_2024",
    "target_segment": "new_customers"
  }
}

Coupon Types

FlexPrice supports two primary discount types:
Reduces the total by a specific currency amount.
{
  "type": "fixed",
  "amount_off": "50.00",
  "currency": "usd",
  "percentage_off": "0.00"
}
Example: $50 off any subscription
For fixed amount coupons, the currency field is required and must match the subscription/invoice currency. Percentage coupons don’t require a currency.

Coupon Cadence

Cadence determines how long the discount applies:
Discount applies only to the first invoice/period.
{
  "cadence": "once",
  "duration_in_periods": null
}
Use for: Welcome discounts, trial conversions

Redemption Period

Control when coupons can be redeemed:
{
  "redeem_after": "2024-03-01T00:00:00Z",
  "redeem_before": "2024-04-01T00:00:00Z"
}
  • redeem_after: Coupon cannot be used before this date
  • redeem_before: Coupon cannot be used after this date
1

Before redeem_after

Coupon is not yet valid. Redemption attempts will fail.
2

Between dates

Coupon is active and can be redeemed.
3

After redeem_before

Coupon has expired. No new redemptions allowed.

Usage Limits

Limit how many times a coupon can be used:
{
  "max_redemptions": 100,
  "total_redemptions": 23
}
  • max_redemptions: Maximum number of times the coupon can be used
  • total_redemptions: Current redemption count
When total_redemptions >= max_redemptions, the coupon cannot be used anymore.

Unlimited Redemptions

{
  "max_redemptions": null,
  "total_redemptions": 150
}
Set max_redemptions to null for unlimited usage.

Rule-Based Discounts

Coupons support complex rule engines for conditional application:
{
  "rules": {
    "apply_to": "invoice",
    "conditions": [
      {
        "field": "plan_id",
        "operator": "in",
        "value": ["plan_premium", "plan_enterprise"]
      },
      {
        "field": "subtotal",
        "operator": "gte",
        "value": 1000
      }
    ],
    "logic": "all"
  }
}
Rule components:
  • apply_to: Target entity (invoice, subscription, line_item)
  • conditions: Array of conditions that must be met
  • logic: all (AND) or any (OR) for multiple conditions

Common Rule Examples

Only apply to specific plans:
{
  "conditions": [
    {
      "field": "plan_id",
      "operator": "in",
      "value": ["plan_premium"]
    }
  ]
}

Coupon Associations

When a coupon is applied to a subscription, a coupon association is created:
{
  "id": "ca_abc123",
  "coupon_id": "coupon_spring2024",
  "subscription_id": "sub_premium",
  "customer_id": "cus_xyz789",
  "applied_at": "2024-03-15T10:00:00Z",
  "expires_at": "2024-06-15T00:00:00Z",
  "periods_remaining": 2,
  "metadata": {
    "applied_by": "sales_rep_jane"
  }
}
Associations track:
  • Which coupons are attached to which subscriptions
  • When the coupon was applied
  • When it expires (for repeated cadence)
  • How many periods remain

Coupon Applications

Each time a coupon discount is applied to an invoice, a coupon application is created:
{
  "id": "capp_xyz",
  "coupon_id": "coupon_spring2024",
  "subscription_id": "sub_premium",
  "invoice_id": "inv_abc123",
  "customer_id": "cus_xyz789",
  "discount_amount": "250.00",
  "currency": "usd",
  "applied_at": "2024-03-15T10:00:00Z",
  "metadata": {
    "billing_period": "2024-03"
  }
}
Applications provide:
  • Audit trail of discount usage
  • Discount amounts per invoice
  • Reporting and analytics data

Coupon Lifecycle Example

1

Create Coupon

{
  "name": "New Customer 50% Off",
  "type": "percentage",
  "percentage_off": "50.0000",
  "cadence": "repeated",
  "duration_in_periods": 3,
  "max_redemptions": 50
}
2

Associate with Subscription

When customer redeems the coupon:
{
  "subscription_id": "sub_new_customer",
  "coupon_id": "coupon_50off"
}
3

First Invoice

Discount applied to first invoice:
{
  "invoice": {
    "subtotal": "1000.00",
    "total_discount": "500.00",
    "total": "500.00"
  },
  "coupon_applications": [
    {
      "coupon_id": "coupon_50off",
      "discount_amount": "500.00"
    }
  ]
}
4

Subsequent Invoices

Discount continues for 2 more periods, then expires.

Multiple Coupons

Subscriptions can have multiple coupons applied:
{
  "subscription": {
    "coupon_associations": [
      {
        "coupon_id": "coupon_seasonal",
        "periods_remaining": 2
      },
      {
        "coupon_id": "coupon_loyalty",
        "periods_remaining": null
      }
    ]
  },
  "invoice": {
    "subtotal": "1000.00",
    "total_discount": "350.00",
    "coupon_applications": [
      {
        "coupon_id": "coupon_seasonal",
        "discount_amount": "250.00"
      },
      {
        "coupon_id": "coupon_loyalty",
        "discount_amount": "100.00"
      }
    ]
  }
}
Stacking rules:
  • Multiple coupons apply sequentially
  • Percentage discounts typically apply to subtotal
  • Fixed amount discounts reduce the remaining balance
  • Total discount is sum of all applications

Coupon Expiration

Time-Based Expiration

{
  "redeem_before": "2024-04-01T00:00:00Z"
}
Coupon becomes invalid after this date.

Usage-Based Expiration

{
  "max_redemptions": 100,
  "total_redemptions": 100
}
Coupon becomes invalid after reaching max redemptions.

Period-Based Expiration

{
  "coupon_association": {
    "periods_remaining": 0
  }
}
For repeated cadence coupons, expires after specified periods.

Metadata

Store campaign and tracking information:
{
  "metadata": {
    "campaign_name": "Spring Sale 2024",
    "campaign_id": "CAMP-2024-Q1-001",
    "target_segment": "new_customers",
    "channel": "email",
    "attribution": "newsletter_march_2024",
    "created_by": "marketing@company.com",
    "budget_code": "MKT-DISC-Q1-2024"
  }
}
Useful for:
  • Campaign tracking and ROI
  • Attribution analysis
  • Budget allocation
  • A/B testing

Best Practices

Always set redemption limits for publicly shared coupons:
{
  "max_redemptions": 100
}
Prevents abuse and controls discount costs.

Common Patterns

Welcome Discount

{
  "name": "Welcome: 50% Off First Month",
  "type": "percentage",
  "percentage_off": "50.0000",
  "cadence": "once"
}

Extended Trial

{
  "name": "3 Months at 75% Off",
  "type": "percentage",
  "percentage_off": "75.0000",
  "cadence": "repeated",
  "duration_in_periods": 3
}

Loyalty Discount

{
  "name": "Loyal Customer: $100/month Forever",
  "type": "fixed",
  "amount_off": "100.00",
  "currency": "usd",
  "cadence": "forever"
}

Flash Sale

{
  "name": "24-Hour Flash: 40% Off",
  "type": "percentage",
  "percentage_off": "40.0000",
  "cadence": "once",
  "redeem_after": "2024-03-15T00:00:00Z",
  "redeem_before": "2024-03-16T00:00:00Z",
  "max_redemptions": 50
}

Minimum Purchase

{
  "name": "$50 Off Orders Over $500",
  "type": "fixed",
  "amount_off": "50.00",
  "currency": "usd",
  "rules": {
    "conditions": [
      {
        "field": "subtotal",
        "operator": "gte",
        "value": 500
      }
    ]
  }
}