#jeffreycao-no-such-payment_intents

1 messages ยท Page 1 of 1 (latest)

hollow flame
#

hey there! This is usually related to connect requests not being made the same way when creating payment intents and trying to use them in Stripe.js with the client_secrete

#

Are you creating direct charge payment intents on connected accounts?

#

The other possibility is mixing up API keys and you might be using the wrong publishable key for the secret key that was used to create the payment intent

#

If you share the full payment intent ID i can take a look ๐Ÿ™‚

fluid arrow
#

This is the payment intent pi_3JuNkSCcHSz1vOxb1MXnE5OL

#

yeah I'm trying to create a payment intent that charges immediately and is connected to another account

hollow flame
#

(with the account matching the one you created the payment under)

fluid arrow
#

It was working before when I used the on_behalf_of field on the payment intent instead of creating a new paymentmethod connected to another organization's stripe account

hollow flame
#

yes, because when you were using destination charges, the payment intents existing on your paltform account

#

using direct charges the payment intent exists in the connected account

fluid arrow
#

Oh, so I shouldn't use the useStripe hook then?

hollow flame
#

so if you try to confirm as your platform is an invalid payment intent

#

You can still use useStripe but when you initialize Stripe.js (say with loadStripe ) you need to supply the connected account

fluid arrow
#

Would I just do something like this then?
const stripe = useStripe() const stripePromise = loadStripe('pk_test_xxxxxxxxxx');

#

and then continue using stripe.handleCardAction() as I was before?

#

Oh no I see, I just call loadStripe in whatever function I need it in

hollow flame
#

You'd need to do stripePromise = loadStripe('pk_test_123_platform', {stripeAccount: 'acct_456_connected'});

fluid arrow
#

Now i'm getting errorUtils.ts?4b21:110 IntegrationError: Please use the same instance of Stripe you used to create this Element to create your Source or Token.

#

Is there a way to pass stripeAccount to the useStripe() hook?

hollow flame
#

No, it's not supported to change the connected account dynamically. You can only set it during initialization.

#

If you need to change the stripe account, you need to create a new instance of Stripe.js (loadStripe) and re-mount the Elements provider (and any elements consuming the stripe instance)

fluid arrow
#

How can I mount the elements?

hollow flame
#

If you remount the provider that should happen automatically via react

#

because the provider will be unmounted and remounted, so will anything inside it

fluid arrow
#

Ohhh I see now okay

#

Thanks!

hollow flame
#

NP!

fluid arrow
#

Is there any way to check what stripe account a payment method is attached to?

hollow flame
#

Not explicitly, no, but you can try accessing it using your platform or the expected connected account using the stripe account header to check a single account

fluid arrow
#

I'm getting some issues with the setupIntents now

#

So I use loadStripe(PK_test_123, {.stripeAccount: "acct_1xxxx"})

#

then I create a payment method with the useStripe hook

#

then I create a setupIntent with this
const setupIntent = await StripeClient.setupIntents.create( { confirm: true, customer: await getOrCreateStripeCustomerId(user, paymentMethodId), payment_method: paymentMethodId, payment_method_types: ["card"], usage: "off_session", }, { stripeAccount: "acct_1xxxx" } )

hollow flame
#

Hey there, if you share the details of the issue you have with this, my colleague @tropic siren can give you a hand with it -- i need to step away

tropic siren
#

Hello! Happy to help once I know what the issue is. ๐Ÿ™‚

fluid arrow
#

Hey, thanks!

#

Would there be a problem if I didn't specify a stripeAccount that the customer was connected to?

#

I would like to create a stripe customer on my platform, but have the payment method created on a connected stripe account

tropic siren
#

All of the Stripe objects you use in a given payment flow must exist on a single Stripe account. You can't, for example, attach a Payment Intent on a connected account to a Customer that exists on your platform.

#

Can you tell me more about he funds flow you want to build and why you want the Customers on your platform account?

fluid arrow
#

Yeah so we have users scoped to our entire platform, and then multiple organizations they can a part of

#

So i'd like to only have 1 stripe customer id (if possible) per user

#

payments should also go directly to each organization which will each have their own stripe account, connected to our platform

tropic siren
#

Okay, so what you want to do is create the Customer, Payment Method, and probably the Setup Intent objects on your platform account and handle saving cards to Customers entirely on your platform. Later, when you want to collect payment, you would clone the Payment Method from your platform to a connected account and create a Payment Intent on that connected account for the payment: https://stripe.com/docs/payments/payment-methods/connect#cloning-payment-methods

fluid arrow
#

I see, okay

#

I think I tried doing it this way earlier but ran into some problems. Let me try again

tropic siren
#

Happy to help further if you have more questions! ๐Ÿ™‚

fluid arrow
#

If I create the payment Intent on one stripe account, I'll have to confirm it later with the same stripe account correct?

tropic siren
#

Yep.

fluid arrow
#

Right, okay so the problem I'm encountering is. I use the loadStripe() function with no stripeAccount connected. So when I create my payment method it's connected to my platform.

Then I create my paymentIntent, with a clone of the paymentMethod, and connect that to a connected stripeAccount which returns a paymentIntent object.

Then because I require 3D Secure, I try to handleCardAction(). However because the frontend stripeClient just uses the platform instead of the connected stripe account, I can't handle it

tropic siren
#

Right, you need a separate instance of Stripe.js initialized with your platform's publishable key and the connected account's ID.

fluid arrow
#

I see okay

#

Is it possible to pass 2 stripe clients on the <Elements /> provider?

tropic siren
#

That I don't know, I'm not very familiar with React. Let me see if I can find out though...

fluid arrow
#

Naa, doesn't look like it :/

tropic siren
#

I think you would want to have two different Stripe promises from two different loadStripe() calls (one for your platform, one for the connected account) and conditionally pass the right one to <Elements /> depending on what you're doing.

fluid arrow
#

Okay thanks

#

Ill try that

tropic siren
#

You only need one or the other at a time, right? Meaning you don't need to have <Elements /> for both the platform and connected account at the same time?

fluid arrow
#

Errr, I think it's actually easier to just have both at the same time rather than switching between 2

tropic siren
#

Why do you need both at the same time though?

fluid arrow
#

Well I need a stripe client for the platform when creating the payment method, then stripe client for the connected account for confirming it

tropic siren
#

I found this internally, which is an early version of some new documentation we're working on:

Once you pass a stripe or clientSecret to the <Elements> provider, you cannot pass a new value (React Stripe.js will warn and ignore the prop). If you need to update either value, you can tear down the entire Elements instance and create a new one.

In React this is achieved by passing the key prop to the <Elements> provider. The key represents the identity of the component instance. If you change the key, then the component instance will be destroyed and a new component instance will be created.

In plain HTML + JS, this would be equivalent to destroying Element instances, creating a new stripe.elements() group, and mounting new elements.create(``'``payment``'``) instances.

      const key = `${clientSecret} ${publishableKey} ${stripeAccount}`
    
      // A new Elements group will be created from scratch whenever the `key` changes
      return (
        <Elements key={key} stripe={stripePromise} options={{ clientSecret }}>
          <CheckoutForm />
        </Elements>
      );
#

You can ignore the parts about the client secret if you're not using the Payment Element.

fluid arrow
#

Oh, I'll need some state to know when to split between the 2 though so it would be easier to just keep both in state