#PERF - Confirm Pamyent Intent
1 messages · Page 1 of 1 (latest)
This confirm call is coming from the react-native sdk as well
Okay but I'm seeing that you are passing an empty string for setup_future_usage
Why is that?
But I agree the error message is confusing, since you are using the Publishable key
I payload for the request was automatically created via the stripe react-native SDK
const res = await confirmPaymentSheetPayment();
if (!res.error) {
// We good
} else {
// Error
}
Hmmmm.... Okay let me take a look and see if there are any open issues with the RN SDK
I'm not seeing anything on the GH Issues page so I'm reaching out to the team that manages the SDK
alright, for context. It has worked in the past. So it might be a setup issue. (just thinking out loud)
The exact code, no changes?
wym?
You said "it has worked in the past". I"m asking, during those successful calls, was the Payment Intent created the same? Was the RN code the same?
not exactly the same, but the same gist. Code was moved around during development. Not really sure the exact tracing. We were just able to created, confirm and capture a payment intent previously
Little more context, when saving the cards via the setup intent flow. I am getting the original error.
However when creating and saving a card via the payment intent sheet I am able to successfully submit and confirm a payment.
pi_3LQwDVFdV4bT3T5F0TIVULDN - worked
pi_3LQwCeFdV4bT3T5F0jbYw1xK - failed
Using the same card that was created via the sheet still fails. pi_3LQwGKFdV4bT3T5F1ZqOTXid for the same reason
"The sheet"? There is only the PaymentSheet regardless of what type of intent you are using.
But I'm looking into these
yea sorry i know. It is the same call just different keys
const res = await initPaymentSheet({
merchantDisplayName: MERCHANT_DISPLAY_NAME,
customFlow: true,
applePay: {
merchantCountryCode: MERCHANT_COUNTRY_CODE,
paymentSummaryItems: [],
},
googlePay: {
merchantCountryCode: MERCHANT_COUNTRY_CODE,
testEnv: config.ENV !== 'production',
currencyCode: MERCHANT_CURRENCY_CODE,
},
returnURL: MERCHANT_RETURN_URL,
customerId: stripeCustomerId,
paymentIntentClientSecret: paymentIntentClientSecret,
customerEphemeralKeySecret: ephemeralKey,
});
"@stripe/stripe-react-native": "^0.15.0",
When you say different keys, are you talking about API keys, ephemeral keys, ?
export declare type ClientSecretParams = {
paymentIntentClientSecret: string;
setupIntentClientSecret?: undefined;
} | {
setupIntentClientSecret: string;
paymentIntentClientSecret?: undefined;
};
these two types
when using either a payment intent or setup intent
Okay, client secrets, not keys. And yes that is how you let the PaymentSheet know what record to update.
i believe the issue comes from the original statement you asked the beginning though. Why is setup_future_usage empty.
{
"payment_method": "pm_1LQwCYFdV4bT3T5FSoPFJfWN",
"return_url": "thentwrktest://noop",
"payment_method_options": {
"card": {
"setup_future_usage": ""
}
},
"use_stripe_sdk": "true",
"client_secret": "************************************************************",
"expand": {
"0": "payment_method"
}
}
Right. Which you pointed out was not explicitly passed from your RN code.
that is correct
Because the successful /confirm calls included setup_future_usage: "off_session"
So I'n trying to understand if the Payment Sheet might have been initialized in a different way that resulted in that weird payload to the /confirm API call
If that makes sense
yes it does. We are using golang in our servers to create the payment intent
params := &stripev72.PaymentIntentParams{
Params: stripev72.Params{
Context: ctx,
IdempotencyKey: stripev72.String(orderID),
},
CaptureMethod: stripev72.String(string(stripev72.PaymentIntentCaptureMethodManual)),
Amount: stripev72.Int64(amount),
Currency: stripev72.String(string(stripev72.CurrencyUSD)),
Customer: stripev72.String(stripeCustomerID),
Description: stripev72.String(description),
PaymentMethodTypes: []*string{
stripev72.String(string(stripev72.PaymentMethodTypeCard)),
},
PaymentMethodOptions: &stripev72.PaymentIntentPaymentMethodOptionsParams{
Card: &stripev72.PaymentIntentPaymentMethodOptionsCardParams{
SetupFutureUsage: stripev72.String("off_session"),
},
},
StatementDescriptor: stripev72.String(descriptionShort),
TransferGroup: stripev72.String(orderID),
}
if klarnaMinimumAmountInCents <= amount && amount <= klarnaMaximumAmountInCents {
params.PaymentMethodTypes = append(params.PaymentMethodTypes, stripev72.String(string(stripev72.PaymentMethodTypeKlarna)))
}
which is then fed into
paymentIntent, err := s.stripePaymentIntents.New(params)
Okay so you are always creating a Payment Method that can be used again in the future for off-session payments.
yea all the payment methods attached to the customer i am using are all saved as off_session
That makes sense.
strange how this one doesn't have the label though
vs
the last line
since the second was created via setup intent not during the payment intent sheet
Wait wait wait. Look at the request bodies for these two requests:
So it fails when you use a saved payment method only?
yea it appears that way
is the addition of
"payment_method_options": {
"card": {
"setup_future_usage": "off_session"
}
},
needed for existing?
I would think that should only be added if it was a new card
That is what I would think too. Essentially I would expect the PaymentSheet to not pass and payment_method_options at all when using a saved card.
At some point but both the successful and failed requests occurred on the same day
oh yea
when i said before, that it succeeded before. I think that was on version 0.13.0
i think
Question: Are you using the default PaymentSheet or are you employing the custom UI confirmation process outlined here:
https://stripe.com/docs/payments/accept-a-payment?platform=react-native&ui=payment-sheet#react-native-flowcontroller ?
Okay I've reached out to a colleague to dig further into this. Thanks for the confirmation
thank you @honest tartan I am going to reinstall package version 0.13.0 to see if it succeeds in that version like it was before
I would clone the project first, or create a separate git branch, so you can apply any fix to v0.15.0 that we might find.
all these changes are in a experimental branch anyways 😉
The error still happens during version 0.13.0
Hello! I'm taking over and catching up...
🆒
It looks like the SDK is doing this intentionally here: https://github.com/stripe/stripe-ios/blob/ef0c465f84402af07565d637ffb5952d3d2cc37b/Stripe/Intent.swift#L179-L182
The mobile SDKs want to have control over setup_future_usage, but they can't override it if you've set it explicitly server-side with your secret key, which leads to the error you're seeing.
so we should omit
PaymentMethodOptions: &stripev72.PaymentIntentPaymentMethodOptionsParams{
Card: &stripev72.PaymentIntentPaymentMethodOptionsCardParams{
SetupFutureUsage: stripev72.String("off_session"),
},
},
from our server code?
That would prevent this issue from happening, yes.
This might be a bug in the mobile SDKs, we're investigating further now, but in the meantime omitting setup_future_usage when creating the Payment Intent is a viable workaround.
Out of curiosity, why are you setting that specifically for cards instead of at the top-level of the Payment Intent?
I believe the original reason was because klarna was failing when that was set but i dont remember to be honest
Ah, interesting.
but since the default is off_session can this whole property be omitted?
You should be able to omit it server-side and let the mobile SDK set it to the correct value, especially if you're able to set it at the top-level of the Payment Intent server-side.
If Klarna is an issue you can set this to none: https://stripe.com/docs/api/payment_intents/create#create_payment_intent-payment_method_options-klarna-setup_future_usage
wouldn't it default to that since its the only value?
No, what I'm saying is, when you create the Payment Intent, set setup_future_usage to off_session at the top-level of the Payment Intent: https://stripe.com/docs/api/payment_intents/create#create_payment_intent-off_session
Then, to work around the issue of Klarna not liking that setting (if that's an issue) you can override the top-level setup_future_usage to none only for Klarna by setting it here: https://stripe.com/docs/api/payment_intents/create#create_payment_intent-payment_method_options-klarna-setup_future_usage
It boils down to telling the API, "For this Payment Intent I want to set up the payment method for future off-session use, unless it's Klarna."
yea gotcha
sweet so omitting it from the params completely makes it all work 😉
with klarna as well
params := &stripev72.PaymentIntentParams{
Params: stripev72.Params{
Context: ctx,
IdempotencyKey: stripev72.String(orderID),
},
CaptureMethod: stripev72.String(string(stripev72.PaymentIntentCaptureMethodManual)),
Amount: stripev72.Int64(amount),
Currency: stripev72.String(string(stripev72.CurrencyUSD)),
Customer: stripev72.String(stripeCustomerID),
Description: stripev72.String(description),
PaymentMethodTypes: []*string{
stripev72.String(string(stripev72.PaymentMethodTypeCard)),
},
StatementDescriptor: stripev72.String(descriptionShort),
TransferGroup: stripev72.String(orderID),
}
You should test to make sure cards and whatever else you want to be set up for future use are indeed set up for future use the way you want with this configuration.
yea, we just wanted all cards saved as off_session so i think we are ok but will do
If that's the case you should do what I advised above, set setup_future_usage at the top level and disable it for Klarna specifically.
ok
params := &stripev72.PaymentIntentParams{
Params: stripev72.Params{
Context: ctx,
IdempotencyKey: stripev72.String(orderID),
},
CaptureMethod: stripev72.String(string(stripev72.PaymentIntentCaptureMethodManual)),
Amount: stripev72.Int64(amount),
Currency: stripev72.String(string(stripev72.CurrencyUSD)),
Customer: stripev72.String(stripeCustomerID),
Description: stripev72.String(description),
PaymentMethodTypes: []*string{
stripev72.String(string(stripev72.PaymentMethodTypeCard)),
},
PaymentMethodOptions: &stripev72.PaymentIntentPaymentMethodOptionsParams{
Klarna: &stripev72.PaymentIntentPaymentMethodOptionsKlarnaParams{
SetupFutureUsage: stripev72.String(string(stripev72.PaymentIntentPaymentMethodOptionsKlarnaSetupFutureUsageNone)),
},
},
StatementDescriptor: stripev72.String(descriptionShort),
TransferGroup: stripev72.String(orderID),
SetupFutureUsage: stripev72.String(string(stripev72.PaymentIntentSetupFutureUsageOffSession)),
}
Is that approach working as expected?
Happy to help!
❤️
Random question, but are the people helping in this discord just stripe employees that just chill in here? lol
or do you guys rotate using the same accounts?
The people with the Stripe Staff role are people who work at Stripe. Some of us, like me, are engineers who staff this channel and help developers with questions like yours. We don't share accounts; I'm always Rubeus, for example.
ah kinda cool and random lol
🙂
Cheers @somber spire !
This thread has been archived. If you need help with anything else please ask in #dev-help or contact Stripe Support: https://support.stripe.com/contact
Find help and support for Stripe. Our support center provides answers on all types of situations, including account information, charges and refunds, and subscriptions information. Get your questions answered and find international support for Stripe.
Hi @storm arrow! Are you around by chance? I have an update about this issue.
First, I wanted to let you know that we've determined this is a bug in our mobile SDKs and we're going to work on getting it fixed. Can't give you a timeframe for a fix, but wanted to let you know we're working on it.