#blackbirdgunner
1 messages · Page 1 of 1 (latest)
Can you share evt_xxx IDs please?
invoice.paid - evt_1NnJFGSAw4DIVBDnOIkvBvRM
invoice.payment_failed - evt_1NnJFDSAw4DIVBDnyBdAPtZr
I suspect this is normal inline with RBI regulations: https://stripe.com/docs/india-recurring-payments
Means 3DS/auth is required for all recurring payments. So initially it will fail (invoice.payment_failed) and then succeed once 3DS is complete
is there something I can use in the payment_failed event data that will allow me to ignore it just for this particular case? Problem is, I'm using this failure event to handle some other stuff and it's unwantedly triggering that.
You could look at the billing_reason field which would indicate it's the initial payment on creation
billing_reason: "subscription_create"
This also happens during plan change like upgrade and downgrade
and I'm using this event to revert user to previous plan in case of actual payment failure
In that case you can expand the payment_intent field and look at https://stripe.com/docs/api/payment_intents/object#payment_intent_object-last_payment_error
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
So will it be null in case of above 3D Secure issue and be populated with some other value for all other errors?
above image is of invoice.payment_failed payment_intent
Hmm, honestly I'm surprised that is null
Is that the field from the pi_xxx object after retrieving it?
I used this to fetch the above data:
stripe.Invoice.retrieve("in_1NnJt9SAw4DIVBDnFvOasPHh", expand=['payment_intent'])
it was under payment_intent key
Right, but at that point the Invoice was paid
yes, I get invoice.paid just after that
should I print it out and check directly on the webhook code?
Yes you need to make that API call on receipt of the .payment_failed event
Ok, some additional context. The .payment_failed event that omits here is for legayc/migration reasons, noted here: https://stripe.com/docs/billing/migration/strong-customer-authentication#summary-webhooks
This isn't technically considered a payment failure, hence why last_payment_error on the PI is null
Now you said that these errors also fire in other scenarios, so you couldn't rely on billing_reason field. Which other scenarios and do you have examples?
We are using invoice.payment_failed to handle card errors and such in these cases:
- New user's initial subscription purchase
- During plan upgrade/downgrade
- During plan renewals
For our site, because of how it works, we need the users to stay on their existing plan in case their payment fails. For example, if a user on Basic plan tried to upgrade to Pro plan but failed, stripe by default moves them to Pro plan. But we want them to stay on Basic plan. So we downgrade users to Basic plan and void the new "open" invoice that was created. This approach was suggested by one of your team members yesterday.
Are you using pending updates for that? https://stripe.com/docs/billing/subscriptions/pending-updates
That's exactly what that is designed for
New user's initial subscription purchase
You shouldn't need to handle anything in that scenario as you're using a hosted UI (Payment Links/Checkout) which will handle failures accordingly.
No. I was checking based on user's current price id (stored on our end) and the price id of payment failed invoice.
didn't know about this
My bad. The initial purchase part was actually changed today and is no longer being handled in payment failure webhook. Only plan change and renewals are being handled.
Hi! I'm taking over this thread. Let me know if you have any follow up questions.
so should I be checking if last_payment_error is null to know if it was from the 3D Secure?
Our recommendation is to check the Invoice billing_reason, and ignore events about subscription_create because those are being handled in your checkout flow (in this case, Checkout specifically), so you don't need to (and shouldn't) action them.
And in case you make an upgrade/downgrade, keep track of of the invoice ID you just upgraded/downgraded so you can ignore the corresponding events.
There's unfortunately not a great solution here.