Stripe handling the customer.subscription.deleted - stripe-payments

I have a code that disables the user to access my website upon receiving this event : customer.subscription.deleted . However, I want to set a specific condition before applying this code.
I have two cases, in one case, if the user is subscribed to INFINITE plan, he pays 40$ each month for 5 months (cancel_at field of subscription is set after 5 months)and then when the subscription ends, his access to the website remains valid. so after 5 payments, he no longer pays, but he still have access to the website. whereas in a second case, if the website's admin manually cancels the subscription or if it is cancelled after many failed payments, I want to disable the user's access. so is there any condition I can set to differentiate between a subscription that was cancelled after being fully paid and another one that was cancelled before it is fully paid ?

You would have to keep track of this on your end, or using metadata on the Subscription that you kept up to date. There's no way in Stripe to make this distinction.

Related

Subscription Renewal Related

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.

How to deal with subscriptions using PayPal's REST SDK

I am trying to create a basic subscription service on my site and I am not sure of a standard way to deal with subscriptions. I'm sure I could hack something together but I'm just wondering if there is a suggested way.
So I have created a billing plan and activated it.
I have a subscribe button on my site that creates a billing agreement referring to the billing plan created in step 1 and redirects the user to the PayPal website were they can login and accept the subscription.
Once the user completes the actions on the PayPal website they are returned back to my site with a token were I then execute the agreement using the returned token from PayPal as per the documentation.
So I guess after these steps the subscription is created for that user, is active and the first payment is made immediately.
In my database, I have a field for each user names subscribed and it's value is a boolean which I set to true once they are returned to my site and the execute command is successful.
My problem is keeping this boolean value up to date for each user as this is the value I check to see if they can access the content.
Canceling - I can provide a cancel button on my site to cancel their subscription and when successful I can set the value to false. But what if they cancel through the PayPal website? I think there is a webhook names BILLING.SUBSCRIPTION.CANCELLED which may send me the agreement ID and If I save it in my database I can see which user it belongs to and set their subscription to false.
After the first month has passed and the next payment is due, is there a webhook sent for a successful payment or a failed payment so I can then set the subscription value accordingly? I see there is a webhook named PAYMENT.SALE.COMPLETED but I don't know if this fired for a successful payment and PAYMENT.SALE.DENIED for a failed payment. If these webhooks exist for subscriptions I imagine it should be a simple solution to keeping this subscribed value up to date.
Hope this made some sense.

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.

Webhook for Paymill cancelled subscription

Context: We allow users to subscribe to our content by using Paymill subscriptions (monthly or yearly). The user can cancel the subscription at any time, which will remove any future transactions under their client account, but not the current transaction (ex current month or year). We do this by using subscription.setCancelAtPeriodEnd(true); when the users cancels their subscription. Also, as you can see, we are using the Java paymill-java library.
Question: The only missing bit is to actually cancel their content in our app when the current period ends. So, is there a webhook for EventType.SUBSCRIPTION_CANCELLED which will be called at the actual period end ? I see there is a EventType.SUBSCRIPTION_DELETED webhook, but I presume this won't work as we don't actually delete the subscription. I know there are probably other solutions to this matter, like managing the cancelled period end in our app, but this would be much more cumbersome than just using a webhook. At least IMHO.
there are some new webhooks with the subscription v2.1 coming out last week. For example
* subscription.expiring: returns a subscription-object
* subscription.deactivated: returns a subscription-object
* subscription.activated: returns a subscription-object
* subscription.canceled: returns a subscription-object
Have a look at https://www.paymill.com/de-de/dokumentation/referenz/api-referenz/#events
Think yours is the subscription canceled one but you need to make the subscription creation with the api v2.1.

Resources