#instance_error
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/1336320921522274345
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Hi, let me help you with this.
Yes, could you please share the relevant frontend code?
Also, do you have a screenshot of the error/Request ID?
const handlePaymentElement = async (e: any) => {
const email = e.billingDetails.email;
// const email = generateRandomEmail();
setEmail(email);
try {
const response = await createCustomerAndSubscription(
email,
selectedPlan,
trialPriceId,
freeTrialTag,
);
if (!response?.subscription.clientSecret) {
datadogLogs.logger.error(
'[PaymentScreen] clientSecret from createCustomerAndSubscription function is not available',
{ email: email },
);
return;
}
if (!stripe || !elements) {
datadogLogs.logger.error(
'[PaymentScreen] Stripe or Elements is not available',
);
return;
}
const { error: submitError } = await elements.submit();
if (submitError) {
setShowErrorNotification(true);
datadogLogs.logger.error(
'[PaymentScreen] Submit expressCheckoutElement error',
{
error: submitError,
},
);
return;
}
const returnPath =
environment === 'production' ? '/instruction.html' : '/instruction';
const returnUrl = `${window.location.origin}${returnPath}?redirect_status=${REDIRECT_STATUSES_ENUM.SUCCEEDED}`;
const confirmationResult = await confirmPaymentOrSetup(
elements,
response.subscription.clientSecret,
response.subscription.subscriptionType,
);
const operationIntent =
(confirmationResult as PaymentIntentResult).paymentIntent ??
(confirmationResult as SetupIntentResult).setupIntent;
if (operationIntent?.status == REDIRECT_STATUSES_ENUM.SUCCEEDED) {
return await handleSuccessfulPayment(
email,
response.accessToken,
response.subscription.id,
returnUrl,
);
}
From datadog
I have no more info from the error
Why is the function called handlePaymentElement()? Are you using Payment Element or Express Checkout Element?
What is happening inside confirmPaymentOrSetup() function?
On my site we have options for trial (setup) and basic subscription
const confirmPaymentOrSetup = async (
elements: any,
clientSecret: string,
subscriptionType: 'setup' | 'payment',
) => {
if (subscriptionType === 'setup') {
return await stripe.confirmSetup({
elements,
clientSecret,
redirect: 'if_required',
});
} else {
return await stripe.confirmPayment({
elements,
clientSecret,
redirect: 'if_required',
});
}
};
First. Just naming, yea I'am using ExprssCheckoutElement
<ExpressCheckoutElement
onConfirm={handlePaymentElement}
options={expressCheckoutElementOptions}
/>
Do you call this method anywhere else?
No
Interesting, I think I was able to reproduce this error.
As is said, it happens when I'am pressing Pay (trial, so setup), then closing the googlePay window and paying again. This how it looks on console.
And in datadog what I send previously
Yea, in console about submit, but in datadog about confirmSetup. I think the source of them is the same
Submit error disapeared, and this error now comes in console
It seems like some kind of race condition where the confirmSetup() is called multiple times.
Could you please add a console log next to it and see if it prints more than once when you submit the payment?
So a I added a count on the first line of confirm function (confirm payment) and another right above confirmSetup
So it's seems like it's called twice?
Looks like no. Every 'Confirm payment' is my click on Pay button in googlepay window. So 1 confrim setup on 1 click. But if closing the window right after the click and pay in another there is problem. Previous payment is still processing but user executing the new one. As I get it... And i need somehow stop this process or find some idea about it
Maybe I am wrong somewhere, codebase is kinda messy, sorry, but I have to deal with it)
Yea unfortunately it seems like those repeated calls are coming from your application code. I'd suggest you keep moving the counter/dupe check earlier in the call sequence until you find the culprit.
@rigid wind it seems like there's no repeated calls - every handlePaymentElement() call corresponds to only 1 stripe.confirmSetup() call
What do those confirm payment / confirm setup logs correspond to? Are you invoking both?
No. The 'Confirm payment' is from ExpressCheckoutElement onConfirm callback. 'Confirm setup' is right above confirmSetup() inside of it
Hmm
What is createCustomerAndSubscription doing, an async call to your server?
Can you try moving elements.submit() before that call? It should be invoked ASAP after the customer completes the payment UI, and I'm wondering if this is an issue with transient user activation, even if the error doesn't indicate that ๐ค
Creates customer and subscription in stripe for confirmSetup. handleSuccessfulPayment creates user in our system