Provision subscription in checkout.session.completed for first payment - stripe-payments

When I create a checkout session, I include the user_id in the metadata. This allows me to retrieve the user_id when checkout.session.completed event is fired which I will need in order to save the stripe customer id in the database for that user.
Is this the correct approach?
The issue I am having now, is that given this logic whenever the first payment is created I will need to provision the subscription in the checkout.session.completed event, future payments will be handled by invoice.paid event. This is because invoice.paid will can only recognise the user by customer id, which gets populated by checkout.session.completed.
Question:
Is my approach for storing the customer id correct?
How can I provision the subscription from the checkout.session.completed event for the first payment and then future payments are provisioned by invoice.paid?

To provision and monitor a subscription, Stripe recommends listening to three events: checkout.session.completed, invoice.paid, and invoice.payment_failed.
If you need a user_id to provision the subscription, then yes adding it on the Checkout Session metadata makes sense.
When you get the invoice.paid event you can retrieve the associated subscription with the subscription property of the invoice. And then, if needed, you can find the Checkout Session for that subscription with the list checkout sessions endpoint and passing the subscription ID.

Related

How to validate Stripe subscription is active and paid

First time using Stripe's API. What Stripe Webhook events should I use to ensure a user subscription is active and paid for and how should I store it in my database?
I was thinking to set up a Webhook for invoice.paid and then inserting the period_end datetime into my database and running something like
if ( $period_end < date('Y-m-d H:i:s') ) {
//treat subscription as inactive
} else {
//treat subscription as active
}
Is that an advisable way to ensure a subscription is active (paid for)?
You should use
customer.subscription.updated
invoice.payment_failed
invoice.payment_succeeded
You need to use customer.subscription.updated event to handle the case when first time user subscribes to your product.
then use of invoice.payment_failed will inform you about the successful payment of auto payment for subscription and use of invoice.payment_failed will inform you that auto payment for your subscription is failed.
If you want to check if your subscription is active then you can use stripe.checkout.sessions.retrieve(session_id);

What is the stripe webhook to listen to get notified about subscription item deletion

In my usecase i have multiple plans under same interval added as a subscription item under single subscription as documented here. Now when i cancel a single subscription item from a subscription, does stripe provide any webhook with particular event to notify that a subscription item is cancelled?. Read through all the webhooks events documented here but couldn't find a relevant one. Can only find events for subscription creation and subscription deletion only but not for subscription_item.
Read in here that customer.subscription.updated event with pending_update tag can be used to get notified about creation of a subscription_item, but not able to find any reference to handle subscription_item deletion.
You listen to the customer.subscription.updated event.
It contains a Subscription object in the Event object with the "new" updated Subscription. It will also have a previous_attributes hash in the response, which would be the diff between what fields changed in order to update the Subscription.
e.g. if I delete a SubscriptionItem from a Subscription, it shows up in the previous_attributes hash.

Stripe manage subscription - invoice.paid and checkout.session.completed

I've seen this similar question, but it did not answer the question asked.
I can't understand how to manage re-occurring subscription.
I did a test and the following events were fired after a successful Stripe Checkout test payment:
charge.succeeded
checkout.session.completed
payment_method.attached
invoice.created
customer.subscription.created
invoice.updated
customer.subscription.updated
invoice.finalized
invoice.paid
My issue is that both checkout.session.completed and invoice.paid is getting fired. I understand that session can be completed in the following cases
failure
cancel
start of a trial
successful start
Stripe docs says this:
The minimum event types to monitor:
EVENT NAME
DESCRIPTION
checkout.session.completed
Sent when a customer clicks the Pay or Subscribe button in Checkout, informing you of a new purchase.
invoice.paid
Sent each billing interval when a payment succeeds.
invoice.payment_failed
Sent each billing interval if there is an issue with your customer’s payment method.
And in the code part:
For checkout.session.completed:
# You should provision the subscription and save the customer ID to your database.
For invoice.paid:
# Continue to provision the subscription as payments continue to be made.
So then I thought there was surely a way to identify that checkout.session.completed and invoice.paid would be related to each other, but then the problem is that checkout.session.completed does not contain any Invoice id and the invoice.paid does not contain an id for the CheckoutSession where it was created from.
How do I give users only one month of subscription, instead of 2? Does Stripe even keep track of the end of the subscription?
Because in the tracking section here, it says:
...
Your site receives an invoice.paid event.
Your webhook endpoint finds the customer for whom payment was just made.
Your webhook endpoint updates the customer’s current_period_end timestamp in your database to the appropriate date in the future (plus a day or two for leeway).
So this page ignore the checkout.session.completed endpoint entirely and relies on invoice.paid only, which supposedly may only arrive hours later than the session completed. (I can't find the link on this.)
My issue is that both checkout.session.completed and invoice.paid is getting fired. I understand that session can be completed in the following cases
failure
cancel
start of a trial
successful start
This is not correct. checkout.session.completed only fires when the Checkout Session completes successfully. The documentation in the API reference for checkout.session.completed event says:
Occurs when a Checkout Session has been successfully completed.
I noticed you mentioned this quote from the documentation regarding this event:
Sent when a customer clicks the Pay or Subscribe button in Checkout, informing you of a new purchase.
The keywords there are "informing you of a new purchase"; this event will not fire on failure to pay (i.e. when no purchase has been made). It will be fired on successful creation of a Subscription with a trial though.
So then I thought there was surely a way to identify that checkout.session.completed and invoice.paid would be related to each other, but then the problem is that checkout.session.completed does not contain any Invoice id and the invoice.paid does not contain an id for the CheckoutSession where it was created from.
The Checkout Session will specify the associated Subscription in its subscription property. From there you can look at that Subscription's latest_invoice property to get the latest Invoice ID.
To determine if you should provide whatever goods or services your customer is subscribing to you may want to use the customer.subscription.updated event. This will give you updates about changes to the status of the Subscription, and you can provision based on that status. For example, if the status is trialing or active give them access, but if it's anything else don't give them access.

How to get the charge Id after subscribing a customer to a plan with recurring payment?

I have successfully created a customer in stripe with a subscription of plan .After successful payment I am not able to get the charge Id because after subscribing a customer to a plan.It automatically generates an invoice.So what is the way that I can get that particular charge stripe Id from stripe and store it in my system database.
Getting the charge ID for a subscription (or an invoice) can be done via their webhooks integration. You need to expose an API in your app where Stripe can fire these requests. You can subscribe to various events there, but in your case you'd need to do so on charge.succeeded. The charge ID will be in the data structure of the event object.
Take a look at the various other lifecycle events you can use with webhooks.

Stripe: handle the first subscription and webhook event

My customer join a our subscripton plan at the first time, I create a transaction (called START-transaction) and use Stripe's API to create new subscription and store subscription object return within above transaction.
I also using webhook to catch Stripe's events. My bigest purpose is handle recurring payment (send notification on charge success or fail, and something for customer's interaction). I catch event invoice.payment_succeeded to detect it's a recuring billing. I create a transaction too (call RECURRENCE) and, of couse, I store event object within transaction. (base on subscription information in event invoice.payment_succceeded, I find out relative-START transaction and create a new transaction as long as RECURRENCE)
And the problem exposes, in the first time customer creates plan, there 6 event called back to my system: customer.created; charge.succeeded; invoice.created; invoice.payment_succeeded; customer.card.created; customer.subscription.created. So, my customer have 2-transactiona: 1-START and 1-RECURRENCE at the first time.
Do you suggest me any idea to remove RECURRENCE transaction?
Thank you.
It sounds like you want to be able to tell if the invoice.payment_succeeded event you receive is for the first payment (which you already processed in your "START transaction") or not (in which case you want to process it in a "RECURRENCE transaction").
The simplest way to do this is to look at the event object's request attribute. Because the first invoice is a direct consequence of your subscription creation request, the first invoice.payment_succeeded event will have a non-null value for the request attribute. Subsequent invoices are created in the background by Stripe, and so the events will have a null value for the request attribute.
You can use the Stripe Request's billing_reason to identify if it is a first-time subscription, a recurring payment, or an updated invoice payment. See https://stripe.com/docs/api/invoices/object#invoice_object-billing_reason

Resources