Problem:
I had my first user upgrade to a higher priced subscription plan, under the proration settings, the user is set to be charged a higher amount next month ($84.95 instead of $67).
Question:
How can I charge the user the difference ($17.95) upfront, so they are charged this amount when they press upgrade, and then on the next billing cycle get charged just the normal amount ($67)
Is there an option to enable this in Stripe?
As ceejayoz mentioned, the solution here is to generate a one off invoice right after the upgrade.
Generating a one-off invoice pulls in any pending invoice items that would have been added to the regularly scheduled invoice.
Related
My goal is this: sub service started to experience issues on 11/9. Instead of pausing payments immediately, I let a few weeks go by. I now want to refund the cost incurred to each user based on the prorated cost for the number of days of bad service. So refund each user 19 or 20 days based on their current subscription. Is there a way to do this via API?
It get's so complex with the past month's proration on the bill. It's a nightmare and this would save me so much time. Willing to compensate. Thank you.
I havent been able to try anything yet.
You can issue a partial refund by specifying an amount less than the original amount of the payment being refunded using the Stripe API. You would specify the payment_intent belonging to the Subscription Invoice in question (which you can find on the Invoice object).
However, you need to calculate the amount you wish to refund on your end based on the amount you want to refund for each Subscription.
I am currently in the process of creating the billing system for my first SaaS. A simple tool to generate videos. There will be a free, mid, and pro tier. The main difference will be the number of minutes you can generate per month.
I created 3 Stripe products for the tiers. The free product consists of one price ($0) with a monthly charge interval. The mid and pro tier consists of 2 prices, a monthly and annual charge interval.
When a user signs up for an account, my backend automatically creates a Stripe customer and subscribe it to a free plan. A user can upgrade their account to a mid or pro tier. The plan will be downgraded to a free tier when the user cancels or if the payment failed.
I reset the number of available render minutes after each successful payment, at the start of the billing month. I do this by listening to the successful payment Stripe webhooks. Even when the user is on the free tier, the webhook still gets fired since it is a plan.
The problem is that this method would not work for annual plans.
Which made me think that the method that I went for may not be the correct one.
Do you know if this is a good method if there is a better one and if there is a workaround for annual subscriptions?
Thank you very much for your time.
I think for the annual billing you'll likely want to just set up a cron job or similar that runs daily, and that looks at which annual subscriptions' 'billing day anniversary' (i.e., billing date is Aug 7, so billing day anniversary is the 7th of each month) and resets the counts - unless it is the billing date, in which case leave it to your webhook.
We are using Stripe payment processing for our customer's subscriptions. When users change plans, we want them to be charged immediately for the prorated difference. Stripe does this automatically when plans have different billing intervals but when changing between plans with the same interval, Stripe defers payment till the next billing period.
The way we handle this now is to create an invoice after updating the subscription, but if the billing fails for it fails, we need to do a rollback.
stripe.subscriptions.update(/* change plan */);
if (plans_have_different_billing_intervals) {
try {
stripe.invoices.create(/* for all pending charges */);
} catch (err) {
/* rollback subscription to old plan */
}
}
Overall, this feels wrong and convoluted. Is there an easier/cleaner way to implement this that we aren't seeing?
You can use billing_cycle_anchor set to now when updating a subscription to force it to change the billing cycle and thus always charge the customer immediately. Personally I think this makes a lot more sense. Also this works well with prorating.
await stripe.subscriptions.update(subscription.id, {
billing_cycle_anchor: 'now',
items: [{ id: itemId, plan: planId }]
});
https://stripe.com/docs/billing/subscriptions/billing-cycle#changing
To immediately charge your users the prorated price difference when the user upgrades, use the proration_behavior='always_invoice' option when modifying the user's subscription. Quoting from the docs:
... In order to always invoice immediately for prorations, pass always_invoice.
Python example:
stripe.Subscription.modify(
subscription_id,
items=[{
'id': item_id,
'plan': plan_id,
}],
# Charge the prorated amount immediately.
proration_behavior='always_invoice',
)
This immediately charges the user a prorated amount when the user changes to a more expensive plan. However, when the user changes to a cheaper plan, the user will be given a prorated credit, making the user's next bill cheaper by the prorated amount.
Scenarios
In these scenarios, suppose the billing date is on the first day of each month. Further suppose that the month has 30 days.
Scenario 1: The user is subscribed to a $5 monthly plan. The user decides to upgrade to a $30 plan on the 22nd day of the month. With 8 days left in the month, the unused portion of the $5 plan is approximately (8 / 30) * 5 = $1.33, and the prorated amount for the $30 plan is (8 / 30) * 30 = $8.00. So the user will be charged 8.00 - 1.33 = $6.67 immediately.
Scenario 2: The user is subscribed to a $30 monthly plan. The user decides to downgrade to a $5 plan on the 22nd day of the month. With 8 days left in the month, the unused portion of the $30 plan is approximately (8 / 30) * 30 = $8.00, and the prorated amount for the $5 plan is (8 / 30) * 5 = $1.33. In this case, the user will not be charged, but the user's next bill (on the next billing date) will be reduced by 8.00 - 1.33 = $6.67.
The example calculations above are only approximate because Stripe prorates to the exact second, not by day.
Side notes
dearsina's answer is correct, but involves at least three API calls rather than one. To explicitly follow the steps in that answer, you could do this instead:
# Step 1 in dearsina's answer: Modify the subscription.
modified_subscription = stripe.Subscription.modify(
subscription_id,
items=[{
'id': item_id,
'plan': plan_id,
}],
)
# Steps 2 and 3: Create and retrieve invoice.
invoice = stripe.Invoice.create(customer=modified_subscription.customer)
# Steps 4 and 5: Finalize and pay invoice.
stripe.Invoice.pay(invoice.id)
But why do this when you could do all the steps in one API call?
To take payment for a change of quantity or subscription plan, you need to do the following:
Update subscription with the new changes.
Create an invoice.
The thing that confused me by this is that Stripe magically knows to only invoice for the updated subscription items, and not for upcoming billing cycle items.
Retrieve the newly created invoice
Finalise the invoice
Take payment for the invoice This assumes that your customer has a payment method stored.
Only when all of the steps have been completed, you've successfully charged for the subscription change (and charged for the change only). You can do it all of it in one go. The customer should get an invoice email from Stripe at the end of it.
As OP says, it gets particularly complicated if the payment fails. The way I see it, you have three choices:
Ignore the failed payment, give the customer access to the service, and hope that they'll pay the next time payment is attempted.
Roll-back the subscription upgrade, warn the customer that payment failed.
Put the entire subscription on hold until the customer pays.
I'm only mentioning #3 because at times, the subscription upgrade process may be complicated. And the customer, having spent time upgrading their subscription, wouldn't want the work to be undone, for what could be a completely harmless reason (their credit card had expired for example).
It may be easier, from a development perspective, to mark a subscription as unpaid, than to roll back or to freeze (and then unfreeze) certain parts of the subscription. But you'll then run foul of barring the customer from a service that they have already paid for (their existing subscription) because they couldn't pay for the additional service.
You can use webhooks in Stripe. After creating an invoice, you can charge the invoice right away (invoice now). If the invoice payment fails, you can use a webhook to rollback to the old account.
Check this guide for more information about Stripe Subscriptions: https://www.truespotmedia.com/testing-webhooks-in-stripe-with-php/
My application allows a customer to purchase credits for later in-app use.
I want to enable customers to buy credits throughout the month, and only get billed at the end of the month.
Should I be using a Stripe Subscription at an amount that equals the price of one credit, and change the quantity according to the number of credits the customer purchased?
(After a successful invoice - I'll reset the subscription quantity to 0)
Is there a better solution? Perhaps some clever method of using Stripe Checkout?
Your proposed approach sounds reasonable.
I've not tried it but an alternative I can think of would use a free plan and the Invoice Items part of the API.
Create a free plan with amount with amount field set to 0. As far as I can see from the docs, all the subscription lifecycle webhooks should be triggered for Customers who're subscribed to the plan.
Through the month, create InvoiceItems for the Customer. According to the docs, at the end of the billing cycle, those InvoiceItems are added to the customer's invoice.
Sometimes you want to add a charge or credit to a customer but only actually charge the customer's card at the end of a regular billing cycle. This is useful for combining several charges to minimize per-transaction fees or having Stripe tabulate your usage-based billing totals.
Beyond that, you'll want to consider if you should have Stripe generate/email your invoices.
I don't think this is the way to go, because subscriptions are billed the first time among other things.
The recommanded way is: stripe doc: Place a hold on a card
summary
You first ask authorization for a certain amount (the max amount). Eg: 1000$
Your custommer buy 50 credits in the month
At the end of the month you charge the customer for 50$ (it can not be greater that the maximum you authorized in the first step)
That's all :)
I have a web service which publishes and hosts certain information for my users. Each user's editing interface is separate from the information they've published. I'm billing for it using Stripe subscriptions, but I'm having trouble coming up with a workable way of handling unpaid subscriptions. Here's the logic I want to implement:
Upon the first failed billing attempt, my app should lock down the user's editing interface; instead, it should present them with a page with options for resolving their payment problem. However, information they've published will still be published, so a late payment doesn't interrupt things for their visitors.
Upon the last failed billing attempt, 15 days later, my app should remove information they've published as well. At this point, the user's editing interface is replaced with one that allows them to either re-activate their account with a new credit card, or completely delete the account.
If the user chooses to re-activate the account, they should not get a trial period
If the user re-activates, they should also have to pay for the 15 days they previously skipped out on, either by having their first billing period shortened by 15 days or by having a charge equal to 15 days' service added to their first bill.
#1 and #2 are very easy to implement if I watch for the right webhooks—just redirect requests for a delinquent customer, or a customer with a deleted or unpaid subscription, to a "fix this problem" page. #3 is pretty easy too—just create the subscription with trial_end set to now.
It's #4 that's tricky. How do I determine exactly how long the user's last invoice went unpaid before their subscription was canceled? How do I shorten the first billing period of the new subscription? Alternately, how do I pro-rate the customer's last invoice total to represent the portion that I actually provided to them, so I can add that amount to the new invoice? (I know I can create an Invoice Item to charge for the amount before I start the new subscription, so at least that's a possibility.)
Finally, does Stripe's "Mark Subscription Unpaid" option help with any of this? It looks like it keeps creating invoices but doesn't try to charge for them; I don't think that's what I want here.
You can definitely do all of that with Stripe's subscriptions. As you mentioned, the first two questions should be solved with webhooks. You would listen for invoice.payment_failedon your end to detect when a payment fails and immediately block you UI asking your customer to update their card details.
To update their card details you can use Stripe Checkout and just not set the data-amount parameter so that it doesn't display a price to your customer. Here is an example for this:
<form action="/charge" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="pk_test_XXXX"
data-image="/square-image.png"
data-name="Demo Site"
data-description="Update Card Details"
data-panel-label="Update Card Details"
data-label="Update Card Details">
</script>
</form>
Each time your customer tries to update his card, you would use the Update Customer API and pass the new card token in the card parameter. This will delete the default card on the customer and replace it with the new one. It will also try and pay the latest invoice of each subscription in the "Past Due" state. In your case it means that the latest invoice still in retry mode will be attempted to be paid. This does not count as a retry and can be seen as independent. If it succeeds, you just reenable the UI otherwise you continue asking the customer to update his card details.
When you reach the fourth failed payment you will get a customer.subscription.canceled if that's what you set up in your retry settings in the dashboard. You can detect that it's an automatic cancelation by checking the request key on the event and making sure it's null. In that case you block the UI/account completely for your customer.
For the last 15 days, if I understood your flow correctly, the customer hasn't really been able to use your application since you locked down the UI partially. But if you still want him to pay for that amount, you should store in your database that the customer owes you $X for the 15 days he couldn't use the subscription.
Later on, your customer finally comes back and want to reenable his account. At that point you inform him that the payment flow will restart from today and that you will charge him for the extra 15 days he missed before. To do that, I would use Invoice Items which will allow you to add an extra amount to the first invoice automatically. You would follow those steps:
Create the invoice item for $X for your customer.
Create a new subscription to your plan setting trial_end to "now" in case you have a trial period set by default on your plan.
This will automatically create the first invoice for the plan amount and add the invoice item created before.
Another solution here would be to reopen their latest closed invoice that wasn't paid and use the Pay Invoice API. When this happens you know your customer paid you for a full month now instead of just the 15 days he owed you. In that case you would create a new subscription and set a trial period of 15 days so that he starts paying again after that trial.
I wouldn't use the "Mark as unpaid" option here because you completely lock the customer out of your application. This feature for me is to be used when you let your customer use your application and plan to charge him in a few months for each of the invoices. This would be used for an electricity provider for example who would keep your electricity on for multiple billing cycles and continue to try charging you for each invoice.
The amount your customer really owes you in that case is dependent on the number of retries you allow and the days between each retry. What you can do here is use the created value on the invoice and compare it to the current time when you get the customer.subscription.canceled to determine how much time passed and calculate the proration of how much your customer owes you at that point.