#neil_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/1332450018053066822
📝 Have more to share? Add more details, code, screenshots, videos, etc. below.
does elements.submit() somehow override the paymentMethodTypes i've set based on the wallet and for google_pay its changing the paymentMethodTypes to be card, us_bank_account?
elements.submit won't override that. Can you show me your code for creating your elements instance on your client?
And do you have the ID of an intent that you got this error with?
yup one minute
wait sorry, no intent ID, because this the create on server flow. The create intent call is what is failing
I can give you the confirmation token generated on the FE: ctoken_1QktJWFdviIHOKAn7DtSXUvM
Ah gotcha, can you provide the code for creating the intent as well? Looking through your logs but that may help me spot this quicker. Basically payment method types disagrees between what you sent on Stripe elements and what the intent is calculating for its payment method types
right right, Im just trying to figure out why, because from our code im pretyt sure its now on our end
const elements = useElements();
useEffect(() => {
// Note: Stripe Elements throws a fit if amount and currency are not valid.
// It is important that we check for these conditions before updating it.
if (
elements &&
currency &&
currency.length > 0 &&
amount &&
amount > 0 &&
styles
) {
const paymentMethodTypes = [];
if (paymentOptions.allowPaymentViaACH) {
paymentMethodTypes.push('us_bank_account');
}
if (paymentOptions.allowPaymentViaCC) {
paymentMethodTypes.push('card');
}
elements.update({
currency: currency.toLowerCase(),
paymentMethodTypes,
amount,
...styles,
customerSessionClientSecret: customerSession,
setupFutureUsage: showSubscribeAction ? 'off_session' : null,
});
setIsOptionsUpdated(true);
}
}, [
elements,
styles,
paymentOptions,
showSubscribeAction,
invoiceId,
currency,
amount,
customerSession,
]);
this is what we do on the client ^
params.OffSession = stripe.Bool(false)
params.ConfirmationToken = stripe.String(input.ConfirmationToken.ID)
params.PaymentMethodTypes = input.Invoice.GetAllowedStripePaymentMethodTypes()
params.AutomaticPaymentMethods = &stripe.PaymentIntentAutomaticPaymentMethodsParams{
Enabled: stripe.Bool(false),
}
if input.Invoice.IsAutoChargeSubscription() {
params.SetupFutureUsage = stripe.String(string(stripe.PaymentIntentSetupFutureUsageOffSession))
}
if input.ConfirmationToken.PaymentMethodPreview.Type == stripe.ConfirmationTokenPaymentMethodPreviewTypeUSBankAccount {
// us_bank_account_ach_payments capability is required to enable ACH debit capabilities
// https://stripe.com/docs/payments/ach-debit#request-ach-debit-capabilities-for-your-connected-accounts
_, err := l.StripeService.GetCapability(input.DestinationAccount.ID, stripe_cli.AchPaymentsCapability)
if err != nil {
return output, err
}
}
if input.ConfirmationToken.PaymentMethodPreview.Type == stripe.ConfirmationTokenPaymentMethodPreviewTypeCard {
params.OnBehalfOf = stripe.String(input.DestinationAccount.ID)
params.PaymentMethodTypes = []*string{stripe.String(string(stripe.PaymentMethodTypeCard))}
}
paymentIntent, err := l.StripeService.CreatePaymentIntent(params)
^ backend
just looking at the stripe dashboard im certain this code path is running
if input.ConfirmationToken.PaymentMethodPreview.Type == stripe.ConfirmationTokenPaymentMethodPreviewTypeCard {
params.OnBehalfOf = stripe.String(input.DestinationAccount.ID)
params.PaymentMethodTypes = []*string{stripe.String(string(stripe.PaymentMethodTypeCard))}
}
and on the front-end you can see we are also setting the paymentMethodType on elements to card
^ im also confident about that because we know its working for apple_pay
Gotcha yeah so overall it looks like paymentOptions.allowPaymentViaACH is triggering and adding us_bank_account on the client side but then you are passing payment_method_types on the backend but are only passing 'card' there
no no, when the pay action is clicked we pdate the element before confirming. Sorry I think that code snippet got mixed in my initial post in the "Repro steps"
const handleSubmit: MouseEventHandler<HTMLButtonElement> = async (event) => {
event.preventDefault();
if (!stripe || !elements) return;
setIsPaying(true);
if (
selectedSource === 'card' ||
selectedSource === 'apple_pay' ||
selectedSource === 'google_pay'
) {
elements.update({
onBehalfOf,
paymentMethodTypes: ['card'],
});
}
const { error: submitError } = await elements.submit();
if (submitError) {
handleError(submitError);
return;
}
const { error, confirmationToken } = await stripe.createConfirmationToken({
elements,
});
if (error) {
handleError(error);
return;
}
handlePayInvoiceClicked(confirmationToken);
};
The only thing between the elements.update and createConfirmationToken code is await elements.submit();
Hence my suspision that code is doing something with google pay specifically to payment methods
And you have double checked that paymentMethodTypes only includes card when you initialize the elements instance on your actual page?
can you clarify what you mean by "when you initialize the elements instance ". Happy to share the code snippet for that to confirm
but im pretty sure we are because apple_pay is working fine.
Here is an example of apple pay transaction with the EXACT same code: https://dashboard.stripe.com/test/logs/req_kcVAaEoZwvDRWL
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
oh yea, using the elements component for tht. No payment method types are set there. Use the elements.update to modify them
Basically, the issue is that that one way or another payment_method_types is getting set as ['card', 'us_bank_account'] on your frontend which disagrees with it just being ['card'] on the backend. The two places that that can be set are when initializing elements or when updating the elements.update call
<Elements
stripe={stripe}
options={{
fonts: [
{
cssSrc: 'https://fonts.googleapis.com/css?family=Inter',
},
],
// set the default configuration for stripe elements.
// this is the only way to setup verification method for ACH payment.
// but if you provide that you need to also provide other options
// like mode, amount, currency
mode: 'payment',
amount: 100, // must be greater than 0, otherwise stripe will throw an error
currency: 'usd',
paymentMethodOptions: {
us_bank_account: {
verification_method: 'instant',
},
},
}}
>
Ah, if you don't pass paymentMethodTypes we use the configuration for automatic payment method types that i on your account. So maybe ACH is turned on there
Yea, Pompey, im totally on the same page with you. But im telling you its not our code that is doing that :p
Otherwise apple_pay would also not work
for that matter no cards would work
i know I've said this before but it has to be elements.submit() that is the only thing before confirmation that could be interrupting the paymentMethodsTypes set already
as you see above, we also have elements.update() which sets the paymentmethodType. So we do update the paymentMethodTypes before sending the request
I am not seeing other reports of this at the moment and am not seeing any code in elements.submit that tries to manipulate the settings. If you cut out the code that dynamically sets payment method types, does this behavior stop or at least become more consistent?
oh yea, none of the our cards work without that code. Everytime we get the paymentMethodTypes mismatch error because the backend only has card but hte client sets card and bank
I have an idea of what to do to fix things. In the server flow i can use the confirmationToken data to access the ConfirmationTokenPaymentMethodPreviewCard and see if it has ConfirmationTokenPaymentMethodPreviewCardWallet with google pay. If so, i'll update the payment method types on the backend.
But this would me blindly applying a solution
Oh, I think elements.update has asynchronous effects, I think I've seen this with other elements updates that users have tried. so you may be running into a race condition here.
Okay sorry I was confused by a couple things. Taking a step back, do you know why your page tries to make this update call before making the submit call here? As long as card is present in the payment method types, the card payment can succeed when you create the intent, setting PMT to just card won't have a benefit that I am aware of
hmmm... maybe but tbh it wouldn't explain why Apple pay works consistently! liek zerro issues
It is unlikely for race conditions to have consistent issues like this but I have seen it before
yes we make the update call because we have to remove on behalf of dynamically based on card or us bank account. We use desitnation charges
Ah and the connected account is in a country that doesn't support ACH?
yea eactly or missing capabilities
And confirmed my memory on the update call. It has asynchronous effects and for some reason you can't use await on it, so we have an update-end event that you can wait on for update to resolve. After that event is called you can proceed with the rest of the process.
https://docs.stripe.com/js/element/events/on_update_end
okay that might be something
but elements.submit() opens the dialog for wallet right?
so shoulnd't that be super slow?
meaning that element.update has plenty of time to finish before we get to the confirmation
One way or another, we don't reccommend calling update immediately before calling submit. I am not as familiar with the internal implementation details but that is in unsupported/unexpected behavior territory. Though we do need to call this out better in our docs.
okay got it
Of course, and I will raise that with our docs team
Good question, I am not as familiar with Stripe.js + React, looking into this and will get back to you
so here's a hack for you
I tried calling update again! after the submit
and before the confirm
and it worked!
so yea...
definitely there is something sus about update/submit
Huh, that is surprising. Unfortunately I am not seeing a hook for the update-end event. I will file something with the team that makes that library, that is definitely something we should have added when we added that event. I'm also not sure if we have an official suggestion of how to make this work consistently without that event. I can create a ticket, ask my colleagues, and get back to you on that if that works for you
thank you that will work
also believe me, I know my solution above is super hacky
but atleast it works right :p
Hello @placid heath, we have sent you a direct message, please check it at https://discord.com/channels/@me/1326640130097942609
- 🔗The message has instructions on how to open a direct support case with our Developer Support team, in order to help you more effectively.
Sounds good, can you fill out the thing from above and let me know when you've finished? I can pick it up from there