#dpelkey98

1 messages ยท Page 1 of 1 (latest)

zealous dockBOT
frozen nymph
#

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.

keen briar
#

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

frozen nymph
#

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.

keen briar
#

ok, thanks for clarifying

#

Can you share an example setup intent ID where you're seeing this?

frozen nymph
#

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.

zealous dockBOT
keen briar
#

Ok thanks, let me take a look ๐Ÿ‘€

#

Ok, and what does your client side code look like?

frozen nymph
azure wing
frozen nymph
#

Yes, but using stripe-react-native

#

Would you still like me to paste my save-card logic?

azure wing
#

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

frozen nymph
#

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.

azure wing
#

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?

frozen nymph
#

That's a grouped firebase function. The endpoint I use to check for duplicate cards and returns client_secret

frozen nymph
#
{"code": "Failed", "declineCode": null, "localizedMessage": "Card details not complete", "message": "Card details not complete", "stripeErrorCode": null, "type": null}
azure wing
#

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
            }
        })
frozen nymph
#

Is it the billing details that are required?

azure wing
#

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

frozen nymph
#
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

azure wing
#

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?

frozen nymph
#

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

azure wing
#

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?

zealous dockBOT
frozen nymph
#

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

azure wing
#

Wow sometimes firebase is evil.

#

So it is working consistently every time now?

frozen nymph
#

It isn't firebase. And I just ran into a culprit

azure wing
#

Nice catch! Glad you were able to solve that

#

And my apologies to Firebase

frozen nymph
#

Still don't know how to resolve other than wait and hope it starts working again

azure wing
#

So to be clear, this only happens when you get back to your app after the redirect from completing 3DS?

frozen nymph
#

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

proven marsh
#

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.

frozen nymph
#

Alrighty ๐Ÿ‘

frozen nymph
#

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

proven marsh
#

Thanks for circling back! We appreciate the two way knowledge sharing

frozen nymph
#

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?

proven marsh
#

Personally I think the GH issue would be a better option