#paramnesia_unexpected
1 messages · Page 1 of 1 (latest)
👋 Welcome to your new thread!
⏲️ We'll be here soon! We typically respond in a few minutes, but in some cases we might need a bit more time (e.g., server's busy, you've got a complex question, etc.).
⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can 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/1251180953003364362
📝 Have more to share? Add details, code, screenshots, videos, etc. below.
Hi, taking a look here
Thanks
Can you share an example request id where you're seeing this error? Here's how you can find a request ID: https://support.stripe.com/questions/finding-the-id-for-an-api-request
I have a payment intent id if that's of any use ?
Looking at the guidance for link above just now.
That works as well
I think this is the API request when it occured (earlier today) ...
req_Zo4Zcfc7X8k0DD
More info / maybe useful: After clicking continue on the 3DS challenge the 3DS window dissappeared, and my integration did not respond. At that point I was able to use another (Visa) card which also prompted a 3DS challenge, which I responded to successfully and the payment went through and my integration responded (as expected).
Still looking here
This sounds like a transient error from the bank as this error happens after Stripe redirect the customer to complete 3DS.
Ok, should Stripe not still send a failure message back from stripe.confirmPayment ?
It's just that the integration is left in limbo at this point and the customer does not know if the payment went through (it didn't).
Is there any way of me detecting this outcome?
You should look at requires_action status in the response: https://dashboard.stripe.com/logs/req_Zo4Zcfc7X8k0DD
When the 3DS was completed ... I don't think I GOT a response in the frontend of the integration. (Could be wrong). The handler for that has been changed to console.log anything that was sent back. I don't think anything was sent back.
Hm, that sounds a little odd. If the payment failed, then confirmPayment should have responded with an error containing some information about what happened.
That's explained in the Returns section here where we discuss how confirmPayment responds:
https://docs.stripe.com/js/payment_intents/confirm_payment
Are you able to reproduce this behavior in testmode by failing a test 3DS authentication? Or does your code handle that as expected?
Handles as expected in Test Mode as I mentioned in the query ... so I have to keep making real payments to test this.
I even waited a long time in Test Mode before clicking the pass btn in the faux-3DS panel. It responded as expected.
We have had card-testing fraud ... so I upgraded API to latest and implemented CAPTCHA in some scenarios (which seems to work). I don't know if that's relevant.
I don't remember having this problem in previous version of Stripe API.
If you're passing the authentication, then you'll go to the return_url and won't see the failure behavior. What happens if you fail the authentication?
Yeh - that works (in test mode) - my integration receives an error object from stripe.confirmPayment and it handles it by showing a message to the user. That's what's not happening in live mode.
Hi there 👋 taking over, as my colleague needs to step away
Give me a few minutes to get caught up.
So what is happening when 3DS fails in live mode?
I complete the challenge (a phone app authorization), for the Mastercard, click the "continue" btn, and the 3DS panel dissappears and then ... nothing.
I guess I'm expecting SOMETHING to come back from confirmPayment ... but nothing does & there is nothing in the browser console (from my integration) ... but there are a few other JS errors related to https://secure7.arcot.com & Content-Security-Policy issues (I am not implementing CSP on this site).
Do you have the ability to screenshot those errors? That sounds like it might be the cause of the issue
I copied them from the console ... (not from the transaction mentioned above, but a previous one):
15:50:59.130 Uncaught TypeError: selections is undefined
onBodyLoad https://secure7.arcot.com/content-server/api/tds2/txn/browser/v1/creq:2643
setCookies https://secure7.arcot.com/content-server/api/tds2/txn/browser/v1/creq:2854
onload https://secure7.arcot.com/content-server/api/tds2/txn/browser/v1/creq:1
creq:2643:41
onBodyLoad https://secure7.arcot.com/content-server/api/tds2/txn/browser/v1/creq:2643
setCookies https://secure7.arcot.com/content-server/api/tds2/txn/browser/v1/creq:2854
onload https://secure7.arcot.com/content-server/api/tds2/txn/browser/v1/creq:1
That's a JS error from the arcot people. And then I have some CSP errs:
15:56:43.622 Content-Security-Policy: The page’s settings blocked an inline style (style-src-attr) from being applied because it violates the following directive: “style-src 'self'”
Source: width:0;height:0;visibility:hidden three-ds-2-fingerprint-4f6956abdda7af06406a29484f940b22.html
15:56:43.623 Content-Security-Policy: (Report-Only policy) The page’s settings would block an inline style (style-src-attr) from being applied because it violates the following directive: “style-src 'self'”
Source: width:0;height:0;visibility:hidden three-ds-2-fingerprint-4f6956abdda7af06406a29484f940b22.html
15:56:43.624 Content-Security-Policy: The page’s settings blocked an inline style (style-src-attr) from being applied because it violates the following directive: “style-src 'self'” three-ds-2-fingerprint-4f6956abdda7af06406a29484f940b22.html
15:56:43.625 Content-Security-Policy: (Report-Only policy) The page’s settings would block an inline style (style-src-attr) from being applied because it violates the following directive: “style-src 'self'” three-ds-2-fingerprint-4f6956abdda7af06406a29484f940b22.html
I'm not sure about the top one ... but I don't think the CSP errs are relevant.
No I don't think so either. Is secure7.arcot.com your domain? Or is that a plugin or something?
Nope - I think that's something to do with the 3DS for Mastercard.
Maybe something in the Mastercard 3DS system is dying and failing to respond to Stripe in an orderly fashion, so Stripe does not respond to my integration.
Let me confer with ny colleagues a bit to see if there's any other troublshooting steps I can take you through.
Have you tried other cards that require 3DS? Did they work?
I tried Visa immediately after - which prompted 3DS and that worked.
Okay, so it's just Mastercard. Are you mounting the Payment Element in an i-frame?
No.
Yeh - just Mastercard so far.
I have to go AFK soon, but I will double-check my code again and see if I can get it to console.log ANYTHING when the 3DS completes in LIVE mode (when it fails) ... but in the meantime are you aware of any situations where stripe.confirmPayment timesout or does not respond? To me - that is what appears to be happening.
That's not common, but also not impossible. Can you copy/paste the code you're using to mount the Payment Element?
/**
* Mounts payment element
*/
const mountPaymentElement = function(){
// We should have a clientSecret at this point
elementsForPayment = stripe.elements({clientSecret: clientSecret})
// NOTE : Card details and billing details MAY be different, when asking for Country and Post Code
// info during the Payment Element phase, you are asking for Country and Post Code associated with your
// card details (which may be used for AVS), not necessarily the same as your billing details.
let args = {
layout: 'tabs',
defaultValues : {
billingDetails : {
address : {
country : addressData.country ?? '', // Pre-fill this info if we have it
postal_code : addressData.postal_code ?? '', // Pre-fill this info if we have it
}
}
}
}
paymentElement = elementsForPayment.create('payment', args)
paymentElement.mount('#payment-element')
// This fires whenever the inputs used in the payment element are changed
paymentElement.on('change', (event) => {
evtLastPaymentElementChange = event // Last paymentElement change event
// Clear any existing errors
reportError(true, errorCntrDonate)
if( event.complete ){
btnContinueDonate.disabled = false
paymentInfoComplete = true
}else{
btnContinueDonate.disabled = true
paymentInfoComplete = false
}
btnContinueDonate.classList.remove('loading')
})
// This fires when the paymentElement becomes ready
paymentElement.on('ready', (event) => {
// formDonate.style.visibility = 'visible'
formDonateSpinner.classList.remove('loading')
})
}
A few irrelevant items have been removed. I don't know if that will be much use to you.
I was really hoping your code would indicate you were doing something weird, but this seems like a very Main Street integration
I prob am doing weird stuff elsewhere 🙂
It seems like Stripe is responding to the error, because the modal is closed, right? Or does something else happen where the flow gets hung up?
The modal does close.
This is how I'm calling stripe.confirmPayment (on a submit handler) .. again less relevant parts removed:
// Confirm Payment
const response = await stripe.confirmPayment({
elements : elementsForPayment,
confirmParams: {
receipt_email: ( ( giftAidCheckbox.checked ) ? emailInputGiftaid.value : emailInput.value ),
return_url: options.returnURL,
},
redirect: 'if_required',
})
// Re-activate the btn
if( evtLastPaymentElementChange.value.type == 'card' )
setLoading(btnContinueDonate)
console.log(`initDonateForm response`, response)
// Show payment outcome page
handlePaymentOutcome( response )
The line console.log(initDonateForm response, response) should catch anything back from confirmPayment, no ?
It does in TEST mode but not in LIVE.
What happens if you use a destructuring assignment for the error instead of creating a normal response variable?
So do this instead:
const {error} = await stripe.confirmPayment({ {...} console.log(error)
I would have to try it & I will but I have to go - so I will double check my code and come back to the thread. Thanks for your assistance (& your colleagues). Hopefully this is not dumb mistake on my part.