Hi there,
I just ran into an unexpected API behavior, so I wanted to document it here and suggest some possible improvements.
If you add a multi-month coupon to a yearly subscription, the coupon ends up applying for the entire year.
This is because the coupon applies to all invoices generated while the coupon is active, as per the docs. So let's say you add a one year subscription with a free 30 day trial, along with a 10% coupon for 6 months. At day 30, the yearly subscription will get invoiced, and the 10% gets applied for the entire year.
Here are some workarounds:
- Use a monthly subscription instead. This won't work if you actually want to bill someone for the entire year.
- Create a separate coupon for yearly subscriptions. So a 10% 6-month coupon would require a corresponding 5% yearly coupon. This means every affected coupon has to be duplicated.
- For 100% off coupons ("Get 6 months free"), use a free trial instead. The disadvantage is that there's no record of the promotion. You can either add that as metadata on the subscription, or you can add a corresponding coupon (the coupon won't have any effect but will make the promotion easier to find in the dashboard).
This being said, I'd argue that the current behavior is confusing. I can see someone possibly using this with a coupon on the customer ("get 10% off any subscription you add in the next 6 months") but for a subscription-level coupon, it makes the 6-month duration completely meaningless.
With that in mind, you may want to consider one of the following API changes when the period of an invoice exceeds the duration of the coupon:
- Automatically pro-rate the discount to account for the coupon duration. [breaking change]
- Create an invoice for the duration of the coupon, followed by invoices at the regular schedule. [breaking change]
- Create an invoice for the duration of the coupon, followed by an invoice for the remaining duration. [breaking change]
- Add some sort of warning when a multi-month coupon is applied to a yearly subscription. I know the API doesn't supports warnings, so this would only make sense if you foresee other use cases for warnings down the line. [non-breaking change]
One argument for a breaking change here is that the current behavior doesn't seem like it would ever be the desired behavior, so people are unlikely to be relying on it (in fact, they most likely have a bug they're unaware of).
Thoughts?
-Nick