ApplyCoupon connects a discount to an existing subscription. When you call it, the action stores the coupon_id on the Subscription model and pushes the coupon to the configured gateway — for Stripe, this attaches the coupon to the gateway customer record. The discount takes effect on the subscriber’s next invoice, not retroactively.
Creating a coupon
Before you can apply a coupon, you need aCoupon model. Create one with Coupon::create().
Applying the coupon
Pass the resolvedSubscription and Coupon models to ApplyCoupon::execute().
Coupon model for you.
Coupon model fields
| Field | Type | Description | |
|---|---|---|---|
code | string | Unique coupon code that subscribers enter | |
type | string | 'percent' or 'fixed' | |
amount | int | Discount amount — percentage (1–100) for percent, minor currency units for fixed | |
duration_in_months | `int | null` | How many months the discount applies; null = forever |
expires_at | `datetime | null` | After this date the coupon cannot be redeemed; null = no expiry |
max_redemptions | `int | null` | Maximum number of times the coupon can be used; null = unlimited |
applies_to_plans | `array | null` | JSON array of plan keys this coupon is restricted to; null = any plan |
first_payment_only | bool | If true, the discount applies to the first invoice only | |
minimum_amount | `int | null` | Minimum invoice amount (in minor currency units) required to use this coupon |
feature_grants | `array | null` | Additional feature overrides to apply while the coupon is active |
Coupon types
- percent
- fixed
A percentage discount is applied to the invoice subtotal before tax.
When the discount takes effect
The discount is reflected on the next invoice generated for the subscription. It does not apply retroactively to invoices that have already been issued or paid. For Stripe, the coupon is attached to the customer record and Stripe applies it automatically when the next billing cycle runs.If
duration_in_months is set, the discount expires after that many months. Subscribd records the coupon_id on the subscription and the gateway tracks the duration independently.