0
votes

I'm using Stripe with Standard accounts.

I'm saving Customers and PaymentMethods on the Platform, so, in client side the customer choose a Payment Method and it is sent to the server. So, in the server side I clone the PaymentMethod to the Connected Account that will receive the payment. My server side code looks like this

RequestOptions requestOptions = RequestOptions.builder()
    .setStripeAccount("{{CONNECTED_STRIPE_ACCOUNT_ID}}")
    .build();

PaymentMethodCreateParams paramsClone = PaymentMethodCreateParams.builder()
    .setCustomer("cus_1")//Id of the customer in the platform
    .setPaymentMethod("payment_method_id")//One of the payment methods of the cus_1
    .build();

PaymentMethod newPaymentMethod = PaymentMethod.create(paramsClone, requestOptions);

At this point I assume that this new newPaymentMethod is in the connected account, right?

Well, then I create a PaymentIntent

PaymentIntentCreateParams params = PaymentIntentCreateParams.builder()
    .setAmount(100)
    .setPaymentMethod(newPaymentMethod.getId())
    .setCurrency("usd")
    .setApplicationFeeAmount(10)
    .build();

PaymentIntent paymentIntent = PaymentIntent.create(params, requestOptions);

Everything seems good at this point. The Payment Intent is returning the stripe client secret like 'pi_1Ipfl3Bf0KWukpZWQdbAzoz1_secret_RAKsPMLpyhkDJ7q8N1VvSmaoR' and the status is 'requires_confirmation'. So, when I try to confirm in the client side it throws an error saying: No such payment_intent: 'pi_1Ipfl3Bf0KWukpZWQdbAzoz1'.

I think that it is something related to switching things between my platform and the connected account, but I can not figure out what is the exact problem. I'm following this https://stripe.com/docs/connect/cloning-customers-across-accounts and this https://stripe.com/docs/payments/payment-methods/connect#cloning-payment-methods but still I can not figure out how to get it work.

Can someone explain this? Regards!

2

2 Answers

1
votes

Your server-side steps are correct, you are creating a PaymentIntent on the Connect account.

What you are missing client-side is, since the PaymentIntent lives on the Connect account, your Stripe.js/mobile SDK also needs to be authenticated as the Connect account.

You basically need to specify this on your client-side:

var stripe = Stripe('{{PLATFORM_PUBLISHABLE_KEY}}', {
  stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
});

https://stripe.com/docs/connect/authentication#adding-the-connected-account-id-to-a-client-side-application

Since I presume you already have Stripe.js authenticated as your Platform publishable key (in order to create the first PaymentMethod on the Platform, to clone), you would have to create a second instance of Stripe.js on your client, one authenticated as the Connect account.

0
votes

Well, at the end I solved it in the client side. I just had to tell stripe to confirm on behalf of the Connected Account. Using tipsi-stripe in react native is something like this:

stripe.setStripeAccount('acct_XYZ');//Set the connected account
stripe.confirmPaymentIntent({ clientSecret: stripeClientSecret })
.then((cofirmResponse) => {
    stripe.setStripeAccount(null);//Reset the connected account
    ...
}).catch((e) => { 
    stripe.setStripeAccount(null);//Reset the connected account
    ...
});