#dpelkey98
1 messages ยท Page 1 of 1 (latest)
Forgot to mention; there is one difference between now and before. Now, I am trying to re-create cards that have been previously detached from a customer.
I'm pretty sure I tested this and was able to re-add them, though. So don't think this is what's causing it.
hey there, i don't fully understand the flow you're describing here:
I create a paymentMethod using createPaymentMethod and then pass the id along with a customer ID to a setupIntent endpoint. This returns a client_secret that I pass to confirmSetupIntent.
Are you creating a payment method then confirming client side?
Now, I am trying to re-create cards that have been previously detached from a customer.
If its the same PM id, you won't be able to do that
You'd need those card details to be recollected / a new PM created
Right, sorry, I can clarify further.
I'm using createPaymentMethod and confirmSetupIntent provided by stripe-react-native.
I create the payment method client-side, send the paymentMethodId and customerId to backend which creates a setupIntent and return the client_secret
From there I call confirmSetupIntent on client with the returned secret.
I am not trying to re-attach a detached PM. Card is collected and a new PM is created.
ok, thanks for clarifying
Can you share an example setup intent ID where you're seeing this?
Sure, one sec
"id": "seti_1NdebfHuV3Y4v6TI49FwZWDe",
Both endpoints seem to be working. It is failing at confirmSetupIntent
This is while testing using your 4242 test card for consistency purposes. All cards we save are set up for off-session use as well.
Ok thanks, let me take a look ๐
Ok, and what does your client side code look like?
Typically we'd expect the setup intent to be created first, with the payment sheet then presented to collect payment details and confirm: https://stripe.com/docs/payments/save-and-reuse?platform=react-native&ui=payment-sheet#collect-payment-details
Right, that was my original flow until I found out that Stripe doesn't automatically catch duplicate cards per-customer. Reference here: https://discord.com/channels/841573134531821608/1138858751919657070
Ah, are you trying to follow this flow? https://stripe.com/docs/payments/finalize-payments-on-the-server?platform=web&type=setup#create-pm
Yes, but using stripe-react-native
Would you still like me to paste my save-card logic?
Yes please if you can. Can you also try your flow again and see if any errors crop up in your developer console? I am not seeing an API request to confirm that SetupIntent on our side, so it sounds like the issue is preventing the request from even being sent to us
I'm not sure how I would debug that. The error I get comes directly from confirmSetupIntent. Code incoming..
const onSaveCard = async () => {
if (!account.stripe) return
setLoading(true)
const billingDetails: BillingDetails = {
email: account.email,
address: {
...account.address
}
}
const pmRes = await createPaymentMethod(
{paymentMethodType: 'Card', paymentMethodData: {billingDetails}},
{setupFutureUsage: 'OffSession'}
)
if (!pmRes.paymentMethod || !pmRes.paymentMethod.id) return console.error(pmRes.error)
const res = await stripe.setupIntent({customerId: account.stripe.customerId, paymentMethodId: pmRes.paymentMethod.id})
.catch(err => {
if (err.message === 'Duplicate card') {
return addCardSheetRef.current?.close()
}
Alert.alert('Something went wrong', err.message)
})
if (!res) {
return setLoading(false)
}
const {setupIntent, error} = await confirmSetupIntent(res.data.client_secret, {
paymentMethodType: 'Card',
paymentMethodData: {
billingDetails
}
})
setLoading(false)
if (error || !setupIntent || !cardProg) {
if (error) {
console.log(error)
Alert.alert('Oops!', error.localizedMessage)
} else {
Alert.alert('Oops!', 'Something went wrong while saving your card')
}
} else {
updateDoc(doc(accountCollRef, account.id), {
[`stripe.cards.${setupIntent.paymentMethodId}`]: {
id: setupIntent.paymentMethodId,
brand: cardProg.brand,
exp_month: cardProg.expiryMonth,
exp_year: cardProg.expiryYear,
last4: cardProg.last4
}
})
.then(() => {
addCardSheetRef.current?.close()
})
.catch(console.error)
}
}
const {setupIntent, error} = await confirmSetupIntent(res.data.client_secret, {
paymentMethodType: 'Card',
paymentMethodData: {
billingDetails
}
})
My code reaches here, res.data.client_secret exists per a console log I had earlier. However, error is always what I sent above.
Gotcha, so nothing else shows up in the console, just this error?
Can you try making a page that is just the confirmSetup function on an existing SetupIntent and see if that call succeeds?
What is the const res = await stripe.setupIntent function that you are calling? I am not familiar with it and not seeing it in our js reference. Did you define that yourself or is that from a certain doc?
That's a grouped firebase function. The endpoint I use to check for duplicate cards and returns client_secret
This would essentially have to be exactly what I've already created? It won't proceed without <CardField>
{"code": "Failed", "declineCode": null, "localizedMessage": "Card details not complete", "message": "Card details not complete", "stripeErrorCode": null, "type": null}
Apologies I meant confirmSetupIntent, I think you should be able to call it while hard-coding the billing details.
const {setupIntent, error} = await confirmSetupIntent(res.data.client_secret, {
paymentMethodType: 'Card',
paymentMethodData: {
billingDetails
}
})
Is it the billing details that are required?
Trying to think of what else it could be. You may need to pass in the payment method ID again in confirmSetupIntent though I don't think you should ahve to.
Good point, I think you can even just avoid the billing details altogether and call confirmSetupIntent with just a client secret
const onConfirm = async () => {
const {setupIntent, error} = await confirmSetupIntent('seti_XXX_secret_XXX', {
paymentMethodType: 'Card'
})
console.log(setupIntent, error)
}
This is what returned that error
Full log:
undefined {"code": "Failed", "declineCode": null, "localizedMessage": "Card details not complete", "message": "Card details not complete", "stripeErrorCode": null, "type": null}
Like I said earlier, this was all working literally yesterday. It's seemed to randomly start giving this error. The only change on the app has been a page which lists previous paymentIntents, and a page which creates a payment intent, and confirms it using confirmPayment. Both pages using {initStripe} in a useEffect
Gotcha, thanks for trying that. Will try digging in to this error to see what can throw it.
Do you have source control on this project to where you could try temporarily reverting to the previous version of the code and see if that still runs properly?
Sure, one sec
Silly of me to not have tried that yet actually
Same thing ๐
And this app is barebones. It is literally a Stripe testing environment. The version I just tested on only lists saved cards, and allows adding. Verified working yesterday by myself and someone else
Interesting, even the older version of the code gets this error. Do you know what else may have changed in your environment that would be affecting the code when running now?
Nothing
However, I just tried again and it works
Randomly. I have not changed a single line of code for adding a card, and now it just worked on every version since I added the feature
I haven't even shut down my dev server since we started talking. So it isn't some kind of caching issue
It isn't firebase. And I just ran into a culprit
Trying to add your test card 4000002760003184 listed here https://stripe.com/docs/testing?testing-method=card-numbers#authentication-and-setup. My app wasn't (currently) able to handle the redirect. I revisit my app, try to add another card, and the issue occurs again.
Still don't know how to resolve other than wait and hope it starts working again
So to be clear, this only happens when you get back to your app after the redirect from completing 3DS?
Right, it directs me to a browser page where I hit the button to verify the card. It prompts that it couldn't direct back to my app (exp://safepay) even though that is the correct urlScheme
To add clarification. It looks like it was handled correctly with stripe because the card is attached to the stripe customer. However, now on my app (the card never made it to the code to save to firebase) I can't add any more cards. Failing with that same error
Hi ๐
Unfortunately this is a bit too complex of an issue for us to be able to help here. I recommend you write in to Support https://support.stripe.com/?contact=true with all the details about your Firebase integration and we can dig into this async.
Alrighty ๐
Just updating; that fixing the return url scheme following Expo's guide here https://docs.expo.dev/versions/latest/sdk/stripe/ prevents the issue from happening again. Just in case it comes up again. I still plan on submitting a report that it bugs out the SDK somehow. Thanks for your help
Thanks for circling back! We appreciate the two way knowledge sharing
In your honest opinion, would it be better to submit this to support via website, or an issue on the stripe/stripe-react-native github repo?
Personally I think the GH issue would be a better option