When to register the "payment" event in Stripe webhook - stripe-payments

There is the following event from Stripe that shows a charge has went through:
charge.succeeded
https://stripe.com/docs/api/events/types#event_types-charge.succeeded
From this I can generate an invoice receipt and email it to the customer. Easy enough. However, there is zero information about what is charged in that item -- it only shows the amount. More importantly, it doesn't tell me when the subscription start/end is, which I need to tell the customer in the invoice receipt.
I need to get the different items in the subscription that were charged. It seems like I can use this item instead:
invoice.payment_succeeded
https://stripe.com/docs/api/events/types#event_types-invoice.payment_succeeded
This gives the items in the subscription and also the amount_paid, however it doesn't reference the charge object or anything. I'm also concerned that this event seems a bit more abstracted than the charge.succeeeded/refunded event, so it possibly may not capture anything (please correct me if I'm wrong).
For a subscription, which of the above two methods should I use to trigger when I send an invoice email? Why would one be preferred over the other?

For a subscription, which of the above two methods should I use to trigger when I send an invoice email? Why would one be preferred over the other?
You should prefer the invoice.payment_succeeded event, because as you noticed, it refers directly to the invoice from the subscription and thus has much more of the information that you would need to build a receipt email for the payment.
however it doesn't reference the charge object or anything
The event payload is an Invoice object, which has a charge field with the charge ID for the most recent charge on the invoice(which will be what caused the invoice.payment_succeeded event to trigger). You can retrieve that charge to get further information from that if needed.

Related

What is the correct stripe event when an invoice for a subscription fails?

I have a subscription whose collection_method has been set to send_invoice.
I can't figure out the correct webhook event when the invoice for the subscription is sent to the customer each month but the customer didn't pay it or the payment made by the customer failed.
I think it is invoice.payment_failed but I am not sure whether that applies when the customer doesn't pay the invoice situation too.
Can anyone help me out here?
The invoice.payment_failed is the right one to indicate a payment failure, but the case of customer not paying the invoice is a bit different. It depends on your settings to handle the invoice and/or subscription after payment failures or time past due.
If you choose to have the invoices marked uncollectible, you get the invoice.marked_uncollectible event. If there is a related subscription and you chose to modify it, you'd receive a customer.subscription.updated event (ref) with the new status.

Stripe webhooks, how can I receive the PRICE item when the product paid for is not a subscription but a one-time payment?

I have 1 product in Stripe with 2 prices
1st price is a recurring subscription
2nd price is a one-time payment
I process both by using redirectToCheckout, the first one with mode: subscription and the second one with mode: payment, and both indicating in lineItems the respective price codes
Then, when the payment is fulfilled on Stripe's side, I get webhooks sent to my php backend
With the 1st item I get the event type customer.subscription.created, and the info sent in that webhook includes the price code
I need this price code to be sure that the user has fulfilled the payment for that specific price item
The problem is with the 2nd item, I've been able to identify 4 events that are sent with the webhooks after payment:
customer.created
charge.succeeded
payment_intent.succeeded
checkout.session.completed
And none of them include the price information about what product the user has paid for
Probably I could ask stripe for that information in a fetch operation, but ... it is impossible that there isn't any webhook that includes this basic (?) information
Or maybe I'm understanding it wrongly?
EDIT:
Probably the answer is this one, so that the webhook (checkout.session.completed) by default is not including this information, and it indeed has to be retrieved in a 2nd step
As #ttmarek has said, the answer is here https://stripe.com/docs/expand#includable-properties indicating that one has to retrieve this information if using a single payment
If using a subscription this info is included by default and there's no need to start another request
An alternative to avoid this extra request could be using the amount charged (which comes with most webhooks), provided that you can identify your price from this amount

Stripe webhook confusion

I am having a hard time finding the right webhooks in Stripe to use since it seems a lot of get fired off for multiple situations.
So my site sells a few items (like 10) that can be bought as a single purchase or a subscription (you get the item every X days, no SASS jut products). I am using Stripe's Checkout and Portal to handle all subscriptions and single purchase and those parts work great. Person adds stuff to cart, checkouts out, pays, we are all good. The issue is adding an order to our system from the webhook.
Look at this scenario: a person adds 2 single items and 1 subscription to their cart. They checkout and pay. When that happens we had the checkout.session.completed catching the checkout session was completed and we add those items from their cart to an order. The subscription re-ups after "X" Days we would listen for the invoice.payment_succeeded webhook to create a new order in our system. This logic is flawed though since invoice.payment_succeeded is called on the first order too so basically when they checkout our system adds 2 subscription orders: one from the checkout.session.completed and one from the invoice.payment_succeeded. How can we handle this?
What I would like to have is:
1 webhook to know when the checkout is complete and is only called then, which they do: checkout.session.completed
1 webhook that is only called when a subscription is renewed, not also when created, which I cant find.
If they dont have that webhook for subscription renewals only, how can I tell in the "invoice" object is the very first one so I dont do anything on checkout, only create a new order on renewal?
Instead of using invoice.payment_succeeded you should consider using invoice.paid, as it will also fire when you mark an Invoice as paid out-of-band (which won't happen with invoice.payment_succeeded). Both describe an Invoice, so you should be able to switch between them with minimal or no changes to your code.
You're correct that there is no Event specific to renewals for a Subscription only, but you can use the billing_reason property on an Invoice to determine why the Invoice was created. If it's the first Invoice for a new subscription the Invoice will have billing_reason set to subscription_create.

Stripe subscription events webhooks are not clear

Say I am letting customers subscribe to a service, as I see it there are 2 events that I need to know about :
The current charge succeeded or failed, so I can congratulate him for joining in.
every next charge (every month) succeeded or failed.
Stripe have too many events, and it's hard to know which one of them to listen to :
invoice.paid - "Occurs whenever an invoice payment attempt succeeds"
charge.succeeded - "occures when a new charge was created" (so what's the difference??)
invoice.payment_succeeded - "Occurs whenever an invoice payment attempt succeeds."
customer.subscription.created - "Occurs whenever a customer is signed up for a new plan."
Now I am aware that a few events can happen for a single API call, but,
What should a developer listen to in order to know that his user successfully subscribed, or failed ? how invoice.paid is different than charge.succeeded ? and how invoice.payment_succeeded is different from those ?
It is too messy, I just need to get a yes or no.
I read the API https://stripe.com/docs/api/events/types
It comes down to what you want to listen for.
charge.succeeded will trigger when an invoice is successfully paid, but it'll also trigger for one-off payments.
invoice.paid will trigger when an invoice is paid but will also trigger if you mark the invoice as paid out of band (e.g. someone pays you in cash)
invoice.payment_succeeded is the same as invoice.paid, but won't trigger if you mark the invoice as paid out of band. If you don't anticipate ever accepting out of band payments, then consider using this event.
customer.subscription.created will trigger when a new subscription is created, which isn't the same as the first invoice being paid (e.g. you can create a subscription with a trial period that won't trigger an invoice paid event immediately).
If your business only works with subscriptions (and not one-off payments) and you don't particularly care about the invoice data, use charge.succeeded. If you use both then it's useful to listen to both events to distinguish between the two.
In your case, you probably only want to listen to invoice.payment_succeeded. When you get the invoice, look at the billing_reason field: https://stripe.com/docs/api/invoices/object#invoice_object-billing_reason
If it's set to subscription_create, then send your congratulatory email. If it's subscription_cycle, then it's because the subscription entered a new billing cycle and the payment succeeded.

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