#alexzada - error

1 messages · Page 1 of 1 (latest)

waxen river
#

Can you send me the snippet of your code that is throwing this error?

storm void
#

paymentIntentClientSecret comes from my server

waxen river
#

Can you send me the entire function?

storm void
#

`const handlePay = async () => {
setLoading(true)

const { paymentMethod, error: createPaymentMethodError } = await createPaymentMethod({
  paymentMethodType: 'Card',
})

if (createPaymentMethodError) {
  Alert.alert('Error', 'Houve um erro ao executar o pagamento. Por favor, tente novamente.')
  return
}

await createPaymentIntent({
  createPaymentIntentParams: {
    paymentMethodId: paymentMethod.id,
  },
  onSuccess: async (data) => {
    const { error: createIntentPaymentError, status, paymentIntentClientSecret } = data

    if (createIntentPaymentError) {
      Alert.alert('Error', 'Houve um erro ao executar o pagamento. Por favor, tente novamente.')
      return
    }

    if (status === 'active') {
      Alert.alert('Success', 'Pagamento efetuado com sucesso!')
    }
  
    if (status === 'incomplete') {
      await handleNextActions(paymentIntentClientSecret)
    }
  },
  onError: () => console.log('error'),
})

setLoading(false)

}`

#

export const createPaymentIntent = async ({ createPaymentIntentParams, onSuccess, onError, }:{ createPaymentIntentParams?: { paymentMethodId?: string, paymentIntentId?: string, }, onSuccess: (data: { paymentIntentClientSecret: string, status: string, error?: string, }) => void, onError: () => void }) => { try { const { data } = await axiosInstance.post('http://192.168.0.131:4242/pay', createPaymentIntentParams) onSuccess(data) } catch (error) { onError() } }

waxen river
#

Hey apologies that I dropped off this thread for a bit. Can you try using just handleNextAction? As far as I can tell, we actually do not have a function defined that is called handleNextActions

storm void
#

`const handleNextActions = async (paymentIntentClientSecret: any) => {
const { error: requiresActionError, paymentIntent } = await handleNextAction(paymentIntentClientSecret)

if (requiresActionError) {
  Alert.alert(`Error code: ${requiresActionError.code}`, requiresActionError.message)
  return
} 

if (paymentIntent.status === PaymentIntent.Status.RequiresConfirmation) {
  await createPaymentIntent({
    createPaymentIntentParams: {
      paymentIntentId: paymentIntent.id,
    },
    onSuccess: (data) => {
      const { error: requiresActionResponseError } = data

      if (requiresActionResponseError) {
        Alert.alert('Error', requiresActionResponseError)
        return
      } 
      
      Alert.alert('Success', 'Pagamento efetuado com sucesso!')
    },
    onError: () => Alert.alert('Error', 'Erro ao efetuar pagamento!'),
  })
} else {
  Alert.alert('Success', 'Pagamento efetuado com sucesso!')
}

}`

worthy gulch
#

Sorry about the delay, been busy here, taking another look at this

civic basin
#

👋 stepping in. Can you confirm you are importing handleCardAction in that file?

#

And what version of the React Native SDK are you using?

storm void
#

const { createPaymentMethod, handleNextAction } = useStripe()

civic basin
#

You don't initialize handleCardAction from useStripe

storm void
civic basin
#

You import it directly

#

So add it to your import list there

storm void
#

there is no handleCardAction there so I tried importing handleNextAction but it keeps giving the same error

civic basin
#

Ah I misread before and thought you were attempting to use handleNextAction. Yes, handleCardAction is not a method in our SDK.

#

You would need to use handleNextAction

#

Let's back up a moment

storm void
#

ok

civic basin
#

I assume you are attempting to handle 3DS if it is required, yes?

civic basin
#

Okay and you look to be using CardField

storm void
civic basin
#

Is there a reason you aren't confirming client-side using confirmPayment?

storm void
#

basically our flow is, the customer puts the card information, I make a call to the route that creates a subscription in the backend and this route returns the status

civic basin
#

Ah okay you are following our docs for manual confirmation

#

That flow wouldn't really be the same here for a Subscription... though it could work

#

The typical flow would be to create the Subscription with status: incomplete and pass the client_secret client-side to confirm with confirmPayment

storm void
#

what could i do for my case then?

civic basin
#

I'll get that fixed up in the docs

storm void
civic basin
#

The screenshot you provided isn't an error?

#

It is just showing you how the method works

#

Unless you are talking about the original error that you started the thread with?

storm void
civic basin
#

Which makes sense because you didn't have handleNextAction imported

#

Sorry I was referring to the most recent one

civic basin
#

Yeah you need to import handleNextAction

storm void
#

import { CardField, useStripe, initStripe, PaymentIntent, handleNextAction, } from '@stripe/stripe-react-native'

civic basin
#

Where are you seeing that error exactly?

#

In your emulator?

storm void
civic basin
#

What do you see in Metro?

storm void
#

` const { error: requiresActionError, paymentIntent } = await handleNextAction(paymentIntentClientSecret)

if (requiresActionError) {
  Alert.alert(`Error code: ${requiresActionError.code}`, requiresActionError.message)
  return
} `
#

since requiresActionError is true it puts an Alert on the screen

civic basin
#

Thanks that helps

#

Actually I think I know the issue.... pretty sure this flow doesn't work if you don't have confirmation_method: manual set on the PaymentIntent. That is a weird error for us to throw though.

#

Can you try using confirmPayment instead of handleNextAction here and let me know what happens?

storm void
civic basin
#

Yep

storm void
#

just change where there is handleNextAction by confirmPayment?

#

would it be this? const { error: requiresActionError, paymentIntent } = await confirmPayment(paymentIntentClientSecret, { paymentMethodType: 'Card', })

civic basin
#

Yeah I think thats right except it would be const {paymentIntent, error} = await confirmPayment()

#

I don't think the error will specifically be a requiresActionError

storm void
civic basin
#

Ah right right

storm void
#

nothing happened, neither on the emulator nor on the Metro

civic basin
#

What test card are you using?

storm void
civic basin
#

Can you provide the PaymentIntent ID that you are testing with?

civic basin
#

It declines on charge

storm void
civic basin
storm void
#

can i use this 4000 0025 0000 3155?

civic basin
#

Yeah that should work too

storm void
#

nothing happens yet

civic basin
storm void
#

I tested it on my fixed cell phone and it gave an error

civic basin
#

Okay can you log out the client_secret that you are using with confirmPayment?

storm void
#

I had changed the wifi and forgot to change the url in the api call...

#

this error appears now

civic basin
#

lol glad we figured that out

storm void
#

` const { error: requiresActionError, paymentIntent } = await confirmPayment(paymentIntentClientSecret, {
paymentMethodType: 'Card',
})

console.log('paymentIntent', paymentIntent)`
#

this log paymentIntent undefined

civic basin
#

Cause you hit an error above

#

About paymentMethodType

#

But paymentMethodType looks right to me there.... 🤔

storm void
civic basin
#

Can you try just setting type: 'Card'

civic basin
#

Yeah okay that's right... it should be paymentMethodType so that should error

storm void
#

but putting type works, I'm confused

civic basin
#

Oh okay

#

Ah okay okay

#

I think your Android version is behind

#

For the Stripe Android SDK

#

Wonder if that is why you saw the error previously about the method not existing as well

storm void
#

how can we check this?

civic basin
#

Yep one sec

#

Figuring that out cause don't remember off top of head

storm void
#

ah, ok

civic basin
#

Okay so open your gradle.properties

#

Should be in your android/src directory I believe

storm void
civic basin
#

lol ah didn't realize you are using expo

#

That is the issue

#

Okay so Expo is tied to a specific Stripe React Native version

#

So it sounds like you tried to install the latest Stripe RN SDK (0.9.0) while using Expo

#

As opposed to using expo install @stripe/stripe-react-native which will install the correct version for your Expo SDK

storm void
#

so i remove the dependency i installed earlier and install using expo install @stripe/stripe-react-native?

civic basin
#

Yes

storm void
#

ok, one moment

#

ok, one moment

#

installed this version "@stripe/stripe-react-native": "0.2.3",

civic basin
#

Yep okay

#

That's the latest version of our SDK supported on Expo

#

Okay so now back to the beginning.

#

The recommended route here is to just use confirmPayment

#

I think you can also use handleCardAction if you so desire, and want to then confirm the PaymentIntent later (though I haven't tested this on a Subscription flow so you would need to test).

#

But if you want to charge immediately upon the customer completing 3DS then you should just be using confirmPayment

storm void
#

what is the difference between handleCardAction and confirmPayment?

civic basin
#

handeCardAction is designed to allow you to control when you actually complete the payment.

#

So with the manual confirmation flow a server-side confirmation is still required after handleCardAction is resolved successfully

#

We really don't recommend this flow.

#

It just adds complexity

#

There are a few use-cases that require it, so we support it. But really you should just confirm the payment when the card details are entered and handle it all client-side without needing to re-confirm on your server thereafter

storm void
#

While we're at it, let me ask you a question, we're currently using this synchronous stream that ends in the backend. Since our app connects customers with drivers who can transport objects and the main flow is, a customer requests a ride, pays for it, and this payment can be made in installments, and after payment confirmation the driver goes to the customer and takes his order, what would be the recommended flow for this type of app that needs payment confirmation right away?

civic basin
#

I'm confused, why does that flow require backend confirmation?

#

The payment is up front for the ride, no?

storm void
civic basin
#

Ah okay so you aren't using Webhooks then

storm void
storm void
civic basin
#

Gotcha

#

So yeah the recommended route here is to use Webhooks

#

That said... this synchronous flow does function as a workaround to ensure you aren't missing reconciling payments

#

But it is pretty limiting

storm void
civic basin
#

You either handle the result of confirmPayment or you could wait for the webhook.

#

It depends on what you need to do on your frontend.

storm void
civic basin
#

Sure so confirmPayment will resolve into a paymentIntent when successful.

#

You can test this out right now

#

I don't remember exactly what we return via the SDK

#

That will give you full details on the PaymentIntent

#

This isn't foolproof though, which is why we recommend Webhooks.

#

It is possible that the client drops off after completing 3DS and the promise doesn't resolve client-side. In this case you want your Webhook to catch that payment

#

And also in this case your client dropped off so you don't need to worry about displaying anything client-side in that case.

storm void
#

there are so many buts haha, but ok, I'll try to absorb it all and give the guide another read

civic basin
#

Really you should ignore the guide you were looking at before.

civic basin
#

Since you are using Subscriptions

#

In that flow, replace any time it discusses Elements with using the CardField with React Native

storm void