#resumasterai-eric_code
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1271514363802423398
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
So it sounds like 3DS was most likely attempted, but failed either because the customer exited the page or provided bad auth credentials. In cases like this, you can either (a) manually confirm the Payment Intent with them on-session to reinitiate the 3DS auth attempt, or (b) create a new Checkout Session, or (c) send them to the previous Checkout Session to try again
Here is the info from the customer service:
Hi Ericqa,
Thanks for answering my call earlier. Apologies for the delayed follow-up email.
After further checking, if the payment failed, the 3DS authentication action should be done by your customer and not by you.
Looking at this event ID: evt_3PlMQsJkrystcxfZ08lHYQJN, you need to implement the next action (from line 30)
https://dashboard.stripe.com/events/evt_3PlMQsJkrystcxfZ08lHYQJN
For context, the PaymentIntent object's next_action parameter specifies the type of customer action required to complete the payment. Some common actions that customers may need to perform include:
Redirecting to their bank's online service to authenticate and approve the payment.
Verifying ownership of their account by providing a one-time code.
Pushing funds through their bank's online service in the case of bank transfers.
To do this, then you need to configure this on your side using the Stripe SDK.
Even if they are using Checkout, to create the session, you use API. So please consult a developer who knows about this. We can only advise you this much and we don't do coding for our users.
I hope this helps. If you have any additional questions, please reach back out to us.
Kind regards,
Chona
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
Here is the log of these failed transaction. It is common:
400 ERR
A request to update a PaymentIntent verify_challenge failed
8/7/24, 10:50:45 PM
A payment pi_3PlMQsJkrystcxfZ09oAjOCR for $45.99 USD was canceled
8/7/24, 10:50:33 PM
emilybev97@gmail.com's invoice A8AB37A7-0001 was voided
8/7/24, 10:50:33 PM
emilybev97@gmail.com's invoice has changed
8/7/24, 10:50:33 PM
emilybev97@gmail.com's invoice has changed
8/7/24, 10:50:31 PM
emilybev97@gmail.com's payment for an invoice for $45.99 USD requires a verification step by the user
8/7/24, 10:50:31 PM
emilybev97@gmail.com's payment for an invoice for $45.99 USD failed
8/7/24, 10:50:31 PM
The payment pi_3PlMQsJkrystcxfZ09oAjOCR for $45.99 USD requires you to take action in order to complete the payment
8/7/24, 10:50:31 PM
A draft invoice for $45.99 USD to emilybev97@gmail.com was finalized
8/7/24, 10:50:30 PM
You see, they almost happen on the same time. It looks like it didn't wait for user to finish the authentication, but fail the payment. In my Testing case, THhis also happened. after I click "complete" the authentication and redirect back to the checkout session, the session is already expired.
Hi ๐
This is a lot of text that appears to be copy/pasted from some interaction with Strip Support?
Can you please rephrase the current state of your question in your own words?
Yes. my App currently redirect user to Stripe checkout session to enter their payment info of subscription. However, in both real & test cases, if the card is required authentication, the stripe checkout session will fail. It will show "The payment pi_3PlMQsJkrystcxfZ09oAjOCR for $45.99 USD requires you to take action in ", and then it will fail immediately even before I try to authenticate my card.
I am thinking that I need to confirm paymentIntent manually since it shwos require MY action. However, Since I am using stripe checkout session, I don't know how to do it.
Your integration is making a request to delete the subscription within 2 seconds of the 3DS requirement. Why is that? https://dashboard.stripe.com/logs/req_N5CxLSfnp3124v
I don't know. I will share you my webhook
I think it is due to the event "invoice.payment_failed"
I did this in my webhook:
elif event_type == 'invoice.payment_failed':
print('subscription_payment failed: Subscription canceled:', data_object['id'])
handle_payment_failed(data_object)
It looks like the checkout session is expired right after the authentication start
Wait, I get your point!
I manually cancel the subscription of invoice.payment_failed, and didn't give it chance to retry!
Yes, that would allow you to retry the invoice payment
The initial goal here is that I want to cancel the subscription if the user's card has some issue and cannot pay further (for example, if they buy this month, but the card was freeze for next month cycle). If I want to do this, what event I should handle in the webhook?
Unfortunately the need to authenticate with 3DS shows up as an error or payment failure on the Invoice. That is what makes this more difficult. I think you could still use the same event but you would need to add more logic to you handler function.
I recommend retrieving the associated PaymentIntent from the Invoice https://docs.stripe.com/api/invoices/object#invoice_object-payment_intent
then check the status of the Payment Intent. https://docs.stripe.com/api/payment_intents/object#payment_intent_object-status
If this status property has a value of requires_action this means it failed due to 3DS not being completed and you can re-attempt
Thanks! I will read and try this.
Happy to shed what ๐ก I can ๐
Thank you so much! I am implenting the solution you just suggested.
Hi, Here is my handling. If is possible, could you help me double check this for some potential issues?
elif event_type == 'invoice.payment_failed':
print('Payment failed for invoice:', data_object['id'])
payment_intent_id = data_object.get('payment_intent')
if payment_intent_id:
payment_intent = stripe.PaymentIntent.retrieve(payment_intent_id)
if payment_intent['status'] == 'requires_action':
# Payment failed due to 3D Secure authentication required, no cancellation
print('Payment requires additional action (3DS not completed), will not cancel subscription.')
else:
# Handle actual payment failure, possibly cancel subscription
print('Payment failed due to card issues, canceling subscription.')
handle_payment_failed(data_object)
That looks pretty good to me. But I would test this in Test mode by using one of our Test cards that triggers 3DS authentication and then failing it.
Sure, Thanks
Hi, I have another question. I feel that this can be a better way:
elif event_type == 'customer.subscription.updated':
subscription_status = data_object['status']
user_id = data_object['metadata'].get('user_id') # Assuming you store user_id in metadata
if subscription_status == 'past_due':
# No action needed, Stripe will retry the payment automatically
print(f"Subscription for user {user_id} is past due. Stripe will retry the payment.")
elif subscription_status == 'unpaid':
# Payment retries failed, cancel the subscription
print(f"Subscription for user {user_id} is unpaid. Canceling the subscription.")
handle_payment_failed(data_object) # Cancels the subscription directly
I am wondering will stripe automatically retry the attempts of payment if it is past_due, and after several fails, it will become unpaid?
Sorry, can you try formatting your code? It's hard to read like this
๐งโ๐ป How to format code on Discord
Inline code: wrap in single backticks (`)
This:
The variable `foo` contains the value `bar`.
Will turn into this:
The variable
foocontains the valuebar.
Code blocks: wrap in three backticks (```)
Also, you can specify the language after the first three backticks to get syntax highlighting.
This:
```javascript
function foo() {
return 'bar';
}
```
Will turn into this:
function foo() {
return 'bar';
}```
Notes about **code blocks**:
- Specifying the language is optional (e.g., you can omit `javascript` in the example above)
- If you don't specify the language you won't get syntax highlighting
- When you're inside a code block (after you type \`\`\`) the `Return`/`Enter` key will add a new line instead of sending your message
- Once you end the code block `Return`/`Enter` works normally again
You can [read more about message formatting on Discord's website.](https://support.discord.com/hc/en-us/articles/210298617)
elif event_type == 'customer.subscription.updated':
subscription_status = data_object['status']
user_id = data_object['metadata'].get('user_id')
if subscription_status == 'past_due':
# No action needed, Stripe will retry the payment automatically
print(f"Subscription for user {user_id} is past due. Stripe will retry the payment.")
elif subscription_status == 'unpaid':
# Payment retries failed, cancel the subscription
print(f"Subscription for user {user_id} is unpaid. Canceling the subscription.")
handle_payment_failed(data_object) # Cancels the subscription directly
This is better!
You can configure retries on your subscriptions. We document this approach here: https://docs.stripe.com/billing/revenue-recovery/smart-retries