#Himel

1 messages ยท Page 1 of 1 (latest)

bold groveBOT
wet mortar
#

Hi ๐Ÿ‘‹

I'm not sure what your actual question is. What about failed payments is confusing you?

warm current
#

I mean i have implemented stripe subscriptiion before but never really care about the payment failure! now lets say my first payment went well and the second payment failed for some reason card is decline or something like that! if the payment of the subscription failed i wanna store the reason of the failure to my database and what webhook should i listen too., and whats the best practices

wet mortar
#

You would want to listen to the invoice.payment_failed webhook event.

#

You could then retrieve the Payment Intent and Charge to get all the details of the card decline

warm current
#

i need the charge object to get the error!?

wet mortar
#

Not necessarily, we pass the error back on the Invoice.

warm current
#

I did! i also console.log the event for the invoice.payment_failed but i didnt get the reason why it's failed

wet mortar
#

Do you have an example invoice ID?

warm current
#

in_1NMCb8G6ekPTMWCwbS3yQ3Gw

#

this invoice i think automaticlly deleted! but you can check!

wet mortar
#

Okay the error is on the Payment Intent associated with the Invoice. You can see it on the automated attempts to collect the funds

warm current
#

It says: "No request log found with the specified ID.
The log may have passed its retention period.****"

#

the link you sent me

#

so i just need to fetch the payment intent object from invoice_failed webhook!?

wet mortar
#

Yes. That will have a last_payment_error property which will be populated with data about the payment failure. For this invoice I see this errror:

last_payment_error: {
        charge: "ch_XXXXXX",
        code: "card_declined",
        decline_code: "generic_decline",
        doc_url: "https://stripe.com/docs/error-codes/card-declined",
        message: "Your card was declined.",
        source: {
          id: "card_XXXXXX",
          object: "card",
          address_city: null,
          address_country: null,
          address_line1: null,
          address_line1_check: null,
          address_line2: null,
          address_state: null,
          address_zip: null,
          address_zip_check: null,
          brand: "Visa",
          country: "US",
          customer: "cus_XXXXXX",
          cvc_check: "pass",
          dynamic_last4: null,
          exp_month: 3,
          exp_year: 2043,
          fingerprint: "XXXXXX",
          funding: "credit",
          last4: "0341",
          metadata: {}
          name: null,
          tokenization_method: null,
          wallet: null,
        },
        type: "card_error",
      },

I adjusted the object IDs to be more annonymous

warm current
#

Yeah thanks! man! You are a life saver! wasted a lot of times on the webhook! Thanks a lot!

wet mortar
#

Great ๐ŸŽ‰ Happy to help ๐Ÿ™‚

warm current
#

Hey it safe to store this information to notify user in the frontend!

#

``last_payment_error: {
charge: 'ch_3NMDB2G6ekPTMWCw028d5w8N',
code: 'card_declined',
decline_code: 'generic_decline',
doc_url: 'https://stripe.com/docs/error-codes/card-declined',
message: 'Your card was declined.',
source: [Object],
type: 'card_error'
}, `

wet mortar
#

I'm not sure what you mean here. We do design the message property of the last_payment_error to be something you can display to your customers though

warm current
#

Oh dont mind! i just double checking!

wet mortar
#

But things like the charge ID obviously won't mean anything to the customer so they would probably just be confused if you showed that to them

warm current
#

yeah! that make sense!

#

if the due get paid then the error object will also be null right!@?

wet mortar
#

Not if there was a previous error for this payment

warm current
#

can you explain a little bit!

wet mortar
#

A single payment attempt can be associated with multiple charges. If the first attempt to pay this payment intent results in a failure but then you use that same intent to collect new payment method data and are successful in paying the invoice, the last_payment_error may still be populated. But you could test this by triggering the failed invoice payment and then use the invoice.payment_intent to collect new payments and verify this behavior

warm current
#

let say payment failed! i can use the same payment intent with stripe Payment element to collect new card details!?

wet mortar
#

Yep. We design Payment Intents to be re-used until they are successful

warm current
#

I didnt knew that! that was great!

#

One last thing i will ask! i wont bother then!

wet mortar
#

No worries, it's why we're here

warm current
#

i am not using stripe smart retries for subscription retry! so even if i dont use does stripe do any reattempt to charge!?

wet mortar
#

For the Retry schedule setting you can either use Smart retries or create a custom schedule. Or not use either and handle the logic yourself

warm current
#

Thanks!

wet mortar
#

No problem.