Subscription billing edge cases

2,243 views
Skip to first unread message

Mantas Konstantinavicius

unread,
Jun 20, 2014, 4:40:51 PM6/20/14
to api-d...@lists.stripe.com
Well not really "edge" cases, but some of the things that I've had trouble with when building a billing system on top of Stripe. Is there a better way to do this?

1. Say a user wants to go from paid plan A to paid plan B. Plan B is more expensive than plan A. This happens half-way through their current billing cycle. Ideally, I'd call this an "upgrade", bill their card (prorated charge) immediately, then change plans if payment succeeds, otherwise keep them on their current plan and show a billing/plan change error.

Can this be done using Stripe?

Right now I do this by changing plans, then creating an invoice and force-paying this invoice. The problem is that invoice payment can easily fail at this point (say the user upgraded to a bad card or ran out of funds) and there's no easy way to roll them back to their old plan. Stripe goes into the usual "retry in three days, then mark unpaid or w/e" cycle - which is very confusing for both customers and admins.

2. Let's say that one of my users decides to downgrade from Plan B to Plan A. Ideally, I'd process the downgrade "at period end" - as in I'd like to change plans at period end (similar to how you can cancel at period end) - so they can still use their current higher value plan (already paid for...) until the end of current billing cycle.

Can this be done using Stripe?

Right now I'm using a hack where I "cancel" their subscription, set "downgrade at period end" to true on my end and then process plan changes when Stripe sends over the subscription cancellation webhook. Very meh.

3. Let's say that one of my users ran out of monies and his subscription renewal payment was declined. I email him and he updates his billing/card info to a new card. Ideally, I'd like to charge this card straight away to return the user's subscription back to "active" status... what's the best way to accomplish this? There doesn't seem to be an easy way to keep track of unpaid invoices, especially since there can be numerous unpaid invoices (rare, but it can happen). Not really sure how to go about this one.

Thanks!

Jim Danz

unread,
Jun 20, 2014, 5:37:09 PM6/20/14
to api-d...@lists.stripe.com
Hey Mantas,

Really good questions here -- thanks much for raising.


On Friday, June 20, 2014, Mantas Konstantinavicius <mant...@gmail.com> wrote:
Well not really "edge" cases, but some of the things that I've had trouble with when building a billing system on top of Stripe. Is there a better way to do this?

1. Say a user wants to go from paid plan A to paid plan B. Plan B is more expensive than plan A. This happens half-way through their current billing cycle. Ideally, I'd call this an "upgrade", bill their card (prorated charge) immediately, then change plans if payment succeeds, otherwise keep them on their current plan and show a billing/plan change error.

Can this be done using Stripe?

Right now I do this by changing plans, then creating an invoice and force-paying this invoice. The problem is that invoice payment can easily fail at this point (say the user upgraded to a bad card or ran out of funds) and there's no easy way to roll them back to their old plan. Stripe goes into the usual "retry in three days, then mark unpaid or w/e" cycle - which is very confusing for both customers and admins.
You are not the only user who has been forced into this strategy, and the fact that you have to do it that way is something that I consider to be actively broken with our design.  So while there isn't a better way right now, this is something that we hope to fix "sooner rather than later." It will likely take the form of a `pay_now` parameter at upgrade time to specify that prorations should be invoiced immediately and that the semantics should be exactly as you said -- failed payment means rollback, and payment won't automatically be reattempted.

 

2. Let's say that one of my users decides to downgrade from Plan B to Plan A. Ideally, I'd process the downgrade "at period end" - as in I'd like to change plans at period end (similar to how you can cancel at period end) - so they can still use their current higher value plan (already paid for...) until the end of current billing cycle.

Can this be done using Stripe?

Right now I'm using a hack where I "cancel" their subscription, set "downgrade at period end" to true on my end and then process plan changes when Stripe sends over the subscription cancellation webhook. Very meh.

 Also very valid.  "Schedule modification of subscription for period end" has been on our radar.



3. Let's say that one of my users ran out of monies and his subscription renewal payment was declined. I email him and he updates his billing/card info to a new card. Ideally, I'd like to charge this card straight away to return the user's subscription back to "active" status... what's the best way to accomplish this? There doesn't seem to be an easy way to keep track of unpaid invoices, especially since there can be numerous unpaid invoices (rare, but it can happen). Not really sure how to go about this one.
When you update a customer's default credit card, we automatically retry the latest unpaid, unclosed invoice for each subscription.  If the payment succeeds, the subscription transitions back to active.
 
More than one invoice in arrears is something that you would need to handle on your side, in the current implementation.

Jim


Thanks!

--
You received this message because you are subscribed to the Google Groups "Stripe API Discussion" group.
To post to this group, send email to api-d...@lists.stripe.com.
Visit this group at http://groups.google.com/a/lists.stripe.com/group/api-discuss/.

To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss...@lists.stripe.com.

Mantas Konstantinavicius

unread,
Jun 21, 2014, 6:26:45 AM6/21/14
to api-d...@lists.stripe.com
Hey Jim,

Thanks for getting back to me so quickly! I really appreciate it. :)

I guess I don't have a choice but to continue working around some of these issues until you guys update your API. Any idea on the timeframe? Just a rough guess will do - I want to open source a subscription management package for Stripe/PHP. Would be nice to know if we're talking 1-2 months or something more like 6-24 months for these new features.
 
3. Let's say that one of my users ran out of monies and his subscription renewal payment was declined. I email him and he updates his billing/card info to a new card. Ideally, I'd like to charge this card straight away to return the user's subscription back to "active" status... what's the best way to accomplish this? There doesn't seem to be an easy way to keep track of unpaid invoices, especially since there can be numerous unpaid invoices (rare, but it can happen). Not really sure how to go about this one.
 
When you update a customer's default credit card, we automatically retry the latest unpaid, unclosed invoice for each subscription.  If the payment succeeds, the subscription transitions back to active.

 Awesome, I had no idea that Stripe handled card updates this way. Update your API reference to reflect this - it's a really useful feature. :) It does say that updating a customer's default card automatically validates the card, but doesn't mention anything about retrying latest unpaid invoices.

Thanks!

Alex

unread,
Aug 23, 2014, 6:47:46 AM8/23/14
to api-d...@lists.stripe.com
I don't think this is a edge case. This is how most SaaS would process their subscriptions. 

I think the hack for the upgrade is fine-ish. Is better if it actually have a process for it, but...
 
For the downgrade. Can you set the new subscription to trial until the other one expires? 

  :-)

Sebastian Gierlinger

unread,
Mar 19, 2015, 2:27:36 PM3/19/15
to api-d...@lists.stripe.com
Hey Jim,

I'm running into the same problems Mantas describes. Since this thread is about 9 months old I wanted to ask if there are any updates on how to handle failed payments for pro-rated upgrades? Even if there isn't an update to the API on the horizon it would be interesting to know what a common way to keep track of the subscription state/unpaid invoice would be?

Thank you,
Sebastian

George Millo

unread,
Apr 6, 2015, 1:04:22 PM4/6/15
to api-d...@lists.stripe.com
I have the exact same issue - I need to implement all three scenarios here. +1 to Sebastian's questions.

Thibaud Spieser

unread,
Aug 24, 2015, 4:26:13 AM8/24/15
to Stripe API Discussion
Hi Jim,
Same issue here, especially the 2nd point for "downgrade at end".

Raza Umer

unread,
Aug 28, 2015, 10:31:23 AM8/28/15
to api-d...@lists.stripe.com
i have solved this problem if you still in problem then i will send you solution i just updated library if you want i will send you
Regards Raza Umer

On Mon, Aug 24, 2015 at 12:57 AM, Thibaud Spieser <thibaud...@gmail.com> wrote:
Hi Jim,
Same issue here, especially the 2nd point for "downgrade at end".

--
You received this message because you are subscribed to the Google Groups "Stripe API Discussion" group.
To post to this group, send email to api-d...@lists.stripe.com.
Visit this group at http://groups.google.com/a/lists.stripe.com/group/api-discuss/.

To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss...@lists.stripe.com.



--
I am GooD And hope u will be Well

Daniel C

unread,
Jan 25, 2016, 8:26:16 AM1/25/16
to Stripe API Discussion
Any news regarding “Schedule modification of subscription for period end”   ? Since it's been on the radar for a while  ?
Hey Mantas,

To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss+unsubscribe@lists.stripe.com.

Vid Mahovic

unread,
Feb 5, 2016, 12:20:13 PM2/5/16
to Stripe API Discussion
Hello Mants,

I know it's been a while since you posted this question, but I'm answering it regardless of that, so other potential help-seekers will know. 

First of all, the only method to change billing cycle in Stripe is to set trial periods on subscriptions (as explained here: https://support.stripe.com/questions/how-can-i-change-the-billing-cycle-of-a-subscription). So if you want to change the billing cycle (say you want to upgrade a subscription for a user "instantly"), then you should set trial_ends_at on his new subscription to a near future (e.g. 1 minute from now) and wait for Stripe to fire a webhook event called invoice.payment_succeeded. This event will notify you that an invoice for a subscription was successfully paid and you can then upgrade a user's subscription.

However, if you want to update subscription at the end of the current billing cycle, then my best suggestion will be to (again) set the trial period, but in this case new subscription should "trial" until the end of the current billing cycle. When that time expires, an invoice will be created and a user will have to pay it. 


I hope I clarified some things.



Cheers, Vid


Dne petek, 20. junij 2014 22.40.51 UTC+2 je oseba Mantas Konstantinavicius napisala:

Udayakumar Rayala

unread,
Feb 5, 2016, 2:45:57 PM2/5/16
to Stripe API Discussion
I am facing the same problems and I don't see them implemented in Stripe yet. Will these functionalities be added to Stripe anytime soon?
Hey Mantas,

To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss+unsubscribe@lists.stripe.com.

Remi J.

unread,
Feb 5, 2016, 2:54:08 PM2/5/16
to api-d...@lists.stripe.com
Hey,

I'll address each point separately as some of it have some solutions:

1. You can do this on your end using the Upcoming Invoice API feature [1] . The idea is that you'll let us calculate the proration and then you charge that amount yourself. If the charge goes through, you update the subscription with `prorate` false while if it fails you leave the customer on the current subscription. The main caveat here is that that charge is separate from the subscription.

2. This isn't something we support just yet unfortunately. I'd recommend creating the new subscription to the new plan immediately and set `trial_end` to the `current_period_end` of the one you just canceled so that it starts at the same time the other ends. This avoids having to go through webhooks but it's definitely not the greatest solution either.

3. As mentioned in that email, this is handled automatically for invoice/subscription in the `past_due` state as long as you pass the new card token in the `source` parameter of the Update Customer API [2]. Otherwise, you can simply trigger the payment automatically using the Pay Invoice API [3].

We are also working on improvements on our end though we don't have any specific timeline to share at the moment and those are top of our mind on things we'd love to fix.

Hope this helps!
Remi


Hey Mantas,


To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss...@lists.stripe.com.

--
You received this message because you are subscribed to the Google Groups "Stripe API Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss...@lists.stripe.com.

To post to this group, send email to api-d...@lists.stripe.com.

Udayakumar Rayala

unread,
Feb 6, 2016, 12:28:32 PM2/6/16
to Stripe API Discussion
Thanks for the replies Remi.

Regarding the first point about prorating, if I raise a charge, will it consider the customer's credit? If the customer has some credit, I don't want to charge their credit card instead deduct from their credit.

Thanks,
Uday.
Hey Mantas,


To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss+unsubscribe@lists.stripe.com.

Remi J.

unread,
Feb 6, 2016, 12:34:22 PM2/6/16
to api-d...@lists.stripe.com
The preview endpoint will take it into account as it returns the `starting_balance` and use it when calculating `amount_due`. If you end up making the calculation yourself though to charge only the proration you'd have 2 options:

1/ Take the account balance into account already and then charge the correct total amount in the end. If it succeeds you then update the account balance to reflect it's been used.

2/ Create an invoice item for the amount you want to charge and then invoice it. This takes the account balance into account automatically. The caveat here is that invoices aren't charged automatically so you'll still need to call the Pay Invoice API [1] and then close the invoice if the charge fails so that we don't retry it.

Cheers,
Remi


Hey Mantas,


To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss...@lists.stripe.com.

--
You received this message because you are subscribed to the Google Groups "Stripe API Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-discuss...@lists.stripe.com.
To post to this group, send email to api-d...@lists.stripe.com.
Visit this group at https://groups.google.com/a/lists.stripe.com/group/api-discuss/.

Udayakumar Rayala

unread,
Feb 6, 2016, 12:59:12 PM2/6/16
to Stripe API Discussion
I am thinking of another approach: I will raise the invoice and trigger the payment. My understanding is customer delinquent attribute will change to True if last payment fails. I will then make my application handle the customer based on delinquent attribute. If they change the card and payment processes, this attribute should become false and I will let them continue to use our services.

Are there any caveats with this approach?

Remi J.

unread,
Feb 6, 2016, 1:02:03 PM2/6/16
to api-d...@lists.stripe.com
The invoice is not linked to the subscription so the plan he is currently in would still renew automatically and complicate your flow here.

I would go with one of the options I offered before if I had to build this. I'd personally go with the one-time charge because it's easier to handle and allows you to give an immediate feedback to your customer.



On Sat, Feb 6, 2016 at 12:56 PM, Udayakumar Rayala <uday....@gmail.com> wrote:
I am thinking of another approach: I will raise the invoice and trigger the payment. My understanding is customer delinquent attribute will change to True if last payment fails. I will then make my application handle the customer based on delinquent attribute. If they change the card and payment processes, this attribute should become false and I will let them continue to use our services.

Are there any caveats with this approach?

Udayakumar Rayala

unread,
Feb 6, 2016, 1:44:28 PM2/6/16
to Stripe API Discussion
Let me explain my flow completely and then you can tell me if it will still be complicated. I am asking because I want to be sure about this approach as find this simple. If you point me to the issues, I will follow what you are suggesting. 

Let's say, we offer customers 3 plans then can subscribe to Entry ($10), Mid ($50), Premium($100). 

If a customer subscribed to Entry plan and in the middle of the month they decide to upgrade to Premium, we will take the following steps:

1. Update the subscription with plan id = premium and prorate = True.
2. Raise an invoice. This will raise an invoice with the pending invoice items which has prorated amount.
3. Pay the invoice which is just raised.

But if the customer's credit card got declined, then the Pay invoice will go through since it will retry multiple times according to the retry settings. I was hoping that the subscription status would become 'unpaid' as defined in the retry settings but it doesn't change. And Stripe support clarified that the subscription doesn't change status in this scenario.

From our website we categorise customers into different states:

a. Active - If subscription state is active/trailing. 
b. Unsubscribed - If there is no subscription
c. Unpaid - If subscription status is anything else other than active/trailing.

I will now change "Unpaid" state to be - If subscription status is anything else other than active/trailing or customer delinquent flag is True. In this scenario, their services will be stopped and they have to change their credit card details.

You expressed the following concerns:
- The invoice will not be linked to the subscription - Will the invoice be linked to the subscription if I follow the above steps? 
- The plan will be automatically renewed - Since the credit card is declined, the subscription will be canceled automatically. 

Please let me know if there are other scenarios I haven't thought about. 

Remi J.

unread,
Feb 6, 2016, 1:54:51 PM2/6/16
to api-d...@lists.stripe.com
Hey,

That flow works and the customer would end up in the delinquent state if you can't charge the invoice with the proration items. It's fairly straightforward to test and confirm too. Simply open a new test account and mark the retry settings to cancel the subscription after the first failure and attempt to upgrade the subscription and pay the invoice with the "4000000000000341" test card.

Your system would simply ask your customer to update his card details and make sure to call the Pay Invoice API on the invoice you created for the proration before giving them access to their account again.

I see two caveats here though:

1/ It's still possible for the renewal invoice, 15 days later, to be raised and paid successfully if the customer has enough funds by then. What would happen is that the customer wouldn't be delinquent anymore, his subscription would be active and you'd miss the fact that he didn't pay the proration invoice mid-month. This is obviously an edge-case but I wanted to raise so that you can account for it.

2/ The customer paid for the full month on the lower plan and lost access to it completely by trying to upgrade. This doesn't seem fair and is usually not what you want. When someone upgrades to a new plan you either attempt to charge them once immediately or you wait for the next billing cycle. If it fails immediately then you should consider that the upgrade failed and leave them on the old plan.

Those are decisions you need to make in your code based on what makes the most sense for your business.

I hope this clarifies!
Remi

Udayakumar Rayala

unread,
Feb 6, 2016, 2:09:54 PM2/6/16
to Stripe API Discussion
That clarifies and I will discuss the caveats you mentioned with my team. If the caveats are not acceptable, I will go with the approaches you suggested.

Thanks a lot for your help.

Volodymyr Khoroz

unread,
Mar 7, 2016, 3:13:39 PM3/7/16
to Stripe API Discussion

To Udayakumar Rayala:

I have a workflow very similar to what you need right now.
For a case when a user upgrades from Base plan to Premium plan I do the following:

1. Update a plan.
2. Create an invoice passing a subscription ID - this way an invoice is referencing a subscription.
3. Try to charge the invoice.

These steps above are the same as you do I guess. And below goes a trick:

4. In a charge has failed - I forgive an invoice (look in API documentation) and revert a plan to a previous value.

This way Stripe will not try to charge anymore.


However, I take a possibility to raise an issue that an initial feature request to charge upgrades on Stripe side immediately would be a great addition and protect us from a necessity to go into tricks like this.

Matthew Arkin

unread,
Mar 7, 2016, 3:17:34 PM3/7/16
to Jake K.
Another option, you can use the preview invoice API to calculate what the proration will be. Create a charge for the proration amount and then if the charge succeeds update the subscription with prorate=false.

--
Reply all
Reply to author
Forward
0 new messages