Subscription Renewal Related - stripe-payments

I was using your stripe payment gateway for a while then one day one thing came to my mind. I would like to explain it with an example.
Suppose I am a customer and subscribed to some app. So you will deduct that monthly charges every month. Now what happens is my card got empty and the subscription renewal date is near. As I was not having enough money in my card I got logged out from the app and stripe kept trying my card. Then to re-login to app I was asked to enter the card details again. Now this time I used another card and got logged in successfully as a new user on the app (as my status was marked as 'not renewed' in the database).
So now my questions are:
What will happen if I put some money in my previous card?
Will I get charged twice every month?
How can handle this equation?
Have you understood my point of view?

With Stripe, users (merchants) can set a retry schedule for recurring payments in their account settings: https://dashboard.stripe.com/account/recurring. There can be up to 3 retries after the initial attempt, each retry separated by 1 to 7 days from the previous one.
If all payment attempts fail, users can choose the final fate of the subscription:
cancel it automatically
mark it as unpaid
leave it as-is
If you update a customer with a new payment source, for each of the customer's current subscriptions, if the subscription is in the past_due state, then the latest unpaid, unclosed invoice for the subscription will be retried.

Related

How can you pre-auth a subscription payment with stripe (after the first payment)

I know I can pre-auth a stripe subscription with a trial period. I want to pre-auth the 2nd, 3rd, 4th, nth subscription payment. The info we are sending out is time critical and if their subscription lapses due to NSF or something else, it would be nice for them if they could rectify the problem BEFORE it lapses.
There is a pending invoice you can get for a subscription, and you can create a payment intent with an invoice ID so that when the invoice is paid, the payment intent (that captured the money) will be used to collect the money. BUT the pending invoice doesn't have an ID until one or 2 hours before they try to collect the money which is 3-4 days too late.
Has anyone figured out how to pre-auth subscription payments other than the first one?
Is there a subscription engine I could use (with stripe/paypal/venmo) that would mean I could quit using the deficient stripe subscription system?
Subscription invoices don't exist until the renewal of the billing cycle, and the underlying payment intent is created by the invoice. It's not supported to "pre-auth" subscription payments. Instead, you need to handle payment failures when those occur, optionally by letting Stripe handle that for you.
If you want to have successful payment in advance of some time-sensitive event, then I'd suggest one of two alternatives:
Shift your billing cycle to invoice 3-4 days ahead of what you have set now, allowing you time to recover from payment failures before the delivery timing.
Alternatively you would implement your own recurring payments using saved payment details. You would similarly want to authorize the payment ahead of time to allow for recovery. You could optionally use manual capture to defer capture until the time of delivery.

On recurring billing, is it possible to get declined payments back?

In our system we use Automated Recurring Billing for our members. We check our users subscription status from Recurring Billing API. We check failed payments from Transaction Reporting API and it appears that some of the subscriptions status code return “active” from API even not charged. Let me give a scenario about it :
A user has an ARB monthly subscription which payment cycle is 14th of every month. User has been successfully charged for 3 months. But on 4th payment, we saw that the payment failed and response code from API is “this transaction has been declined”. We think that credit card expiration info may be failed and user may update it. So we put the user in a grace period(two days) and let user update credit card information. If user updates credit card information in two days we call API to update subscription with new credit card info. Let’s say this update subscription request is done on 16th of the current month. Can we get the payment which has passed on 14th ? Or has user been charged on 16th which update subscription request is sent and is ARB payment cycle changed from now on ? Or user will be charged on the next month and we can not get failed payment ?
I could not find any details about failed transactions payment flow when credit card info is updated. Thanks in advance.
A failed subscription payment won't be retried after you update the customer profile. However, you can use the updated custer profile to make your own one-time payment.

Stripe charges twice every time i create a new customer and post a charge

Today after doing thorough testing i switched to Live Account for Stripe. For my very 1st customer stripe charged twice even though on the server side i am creating just one customer and posting a single charge. I have a monthly subscription plan that i am using.
I never saw this issue in Test Account. I even tried my own card and got charged twice. The two charges are posted within 1 second of each other. I have checked my plan too and they are correctly set up
If you have a monthly subscription, that will automatically make a charge, there is no need for you to be posting a charge when the subscription does it automatically.
(Should have commented but i do not have the rep)
I had the same problem on production not in testing.
I found that if a customer is not a subscriber, my code was making it a customer first and then charging customer. But Stripe is already charged customer upon subscription.
"If(subscriber)->charge
else(make subscriber(Stripe charges now))->charge as customer"
The obvious fix is to make the customer a subscriber and quit if it is a new one, please do not call charge.
The not reproducible on testing issue is because all test accounts were already a subscriber .

Resuming a subscription with Stripe (and charging for previously unpaid service)

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.

How to make a Stripe subscription status go from trialing to cancelled if there is no card?

We let our customers do a 30 day free trial using Stripe subscriptions. We want the trial period to last exactly 30 days. If the subscription status is trialing, active or past_due then the customer can use our service.
If the customer has moved out of the trial period and has been paying and for some reason their card is no longer good then the subscription status goes from active to past_due. And the subscription status is past_due for 15 days (dictated by our retry settings). In other words, if they have been a paying customer and their card is not good when their monthly payment is due, then they can still use our service for an additional 15 days while they fix their card.
If the 30 day trial period ends and there is no card then the status moves from trialing to active. And then 3 minutes later the status goes from active to past_due. And then the status stays past_due for 15 days - essentially making the trial period 45 days. We don't want that; we want the trial period to only be 30 days.
How do we not allow those 15 extra days?
I would think that there would be a setting to make the subscription status go from trialing to cancelled in this situation so that it is easy to set the trial period length given the way we have it setup above. But this setting does not appear to exist.
So do I need to manually cancel the subscription when I detect(via webhook) the trialing to active, and then 3 minutes later active to past_due? I would store the datetime in my database when it goes from trialing to active. And then when it goes from active to past_due, I would check to see if that stored datatime was say less than 15 minutes ago - and if it is then I know I have a trial period that ended without a card and I cancel the subscription. Or is there a simpler way to do it?
I was researching this myself. Turns out you can just set the cancel_at on creating a subscription using the same timestamp as your trial_end. When you receive a validated Payment Method from the user, you can remove the cancel_at timestamp by setting it to null so the subscription continues. Then just check if payments succeed and handle that properly.
So, if a user does not give you a Payment Method before the trial ends, then the subscription will get canceled at the cancel_at timestamp.
The first solution would be to change the way you want failed payments for subscriptions to be handled. By default, when an invoice payment fails it is automatically retried after 3 days, then 5 days, then 7 days and then gets ultimately cancelled. You can definitely decide that the subscription needs to be cancelled after the first failed payment by changing the settings in your dashboard.
The second solution is to catch the invoice.payment_failed in the webhook and immediately cancel the subscription on your end.
EDIT: Even if the customer does not have any active card associated and is now out of the trial period it should definitely be raised:
Occurs whenever an invoice attempts to be paid, and the payment fails. This can occur either due to a declined payment, or because the customer has no active card. A particular case of note is that if a customer with no active card reaches the end of its free trial, an invoice.payment_failed notification will occur.
EDIT 2: If you want to know whether the trial just ended the easiest solution would be to save this on your end. You could just store when the customer subscribes to a plan and then detect whether this is the end of the trial based on the date when the invoice.payment_failed is received.
The simplest way I can think of is to add a boolean has_paid attribute to your user model, which is only set to true when you receive an invoice.payment_succeeded webhook for an invoice whose total is greater than 0. (When a trial begins, Stripe creates a $0 invoice for the trial period, which is always paid successfully, so you have to ignore that invoice.) Then your invoice.payment_failed webhook can cancel the subscription immediately if has_paid is false, or let the automatic retry cycle continue if has_paid is true.

Resources