#benkass
1 messages ยท Page 1 of 1 (latest)
Hi, are you able to provide the summary of the issue?
So to recap :
I generated an ephemeralKey on the server
I generate a paymentSheet:
initPaymentSheet({
merchantDisplayName: 'xxx',
customerId: user?.stripe?.customer,
customerEphemeralKeySecret: ephemeralKey,
intentConfiguration: {
mode: {
amount,
currencyCode: 'USD',
},
confirmHandler,
},
returnURL: 'xxx://xxx',
});
I then presentPaymentSheet <<<< I am currently here in my implementation
When the customer clicks on pay, confirmHandler will run and should call the server to:
generate a setupIntent
clone it on the connected account
create a paymentIntent
Do I generate a new ephemeralKey for setupIntent, or should I use the same I generated for initPaymentSheet?
Can you share the integration document you're following here?
I see, it sounds like you're cloning payment methods so you can create direct charges on your connected accounts. Also, you're looking to show the total details first and surface any saved payment methods of the customer. I think this deferred PaymentIntent flow, https://stripe.com/docs/payments/accept-a-payment-deferred?platform=react-native&type=setup is what you're looking for. You would not use SetupIntent here instead you'll defer to create the PaymentIntent, https://stripe.com/docs/payments/accept-a-payment-deferred?platform=react-native&type=payment. Finally, you'll want to add this section, https://stripe.com/docs/payments/accept-a-payment-deferred?platform=react-native&type=payment#ios-enable-saved-cards to show the saved PaymentMethod details.
Looking... Yes, I already implemented ios-enable-saved-cards by creating an ephemeralKey and then passing it and the customer id to initPaymentSheet.
Going to look at the link you sent me
wait, you sent me the same link as I sent you above
ok so looking at your second link now
they are the same link
so hang on... from my first message above, you see where I have "<<<< I am currently here in my implementation"?
Until there I am doing it right, correct?
I believe you are giving me contradicting instructions to what @tropic cloak did
I chatted with Rubeus on your use case. Let me write out the steps
hang on, let me give you a link to our last conversation...
Oh ok
Say hi to him ๐
I believe our last thread ID with Rubeus was 1154547398287306894
From further discussing your use case, here are the steps for your integration:
1/Display the PaymentSheet using an ephermeral key for the Customer
2/Get a Payment Method
3/If a new Payment Method is provided use a SetupIntent on the platform to set up the Payment Method for future use and make sure it's attached to the Customer
4/Clone the Payment Method to a connected account
5/Create and confirm a Payment Intent with the cloned Payment Method
6/If any next actions are required, handle those on the client with the Payment Intent's client secret
7/Repeats steps 4โ6 for each connected account/payment
Thanks! OK, so I did step 1 and 2. I am now at step 3. If you don't mind, I'll follow your instructions and send you questions relevant to each step if I have any.
Now, for step 3 - do I need to create a new ephemeral key or should I use the one from the first step?
Essentially I do await stripe.setupIntents.create({ customer, description })
hang on, there's no ephemeral key here
This is the link to your previous conversation, #1154547398287306894 message
On your follow up question, why do you think you need an ephemeral key here?
'Thanks! OK, so I did step 1 and 2. I am now at step 3. If you don't mind, I'll follow your instructions and send you questions relevant to each step if I have any.
Now, for step 3 - do I need to create a new ephemeral key or should I use the one from the first step?'
Yeap!
ok cool. so now, how do I clone the payment menthod to the connected account? Have a link?
Yes, here is how you can clone the payment method: https://stripe.com/docs/payments/payment-methods/connect#cloning-payment-methods. Create a Payment Method (via /v1/payment_methods endpoint) using the Stripe Account Header and by passing the object ids both the customer id and the payment method id from step 3. It creates a new payment methods id on the Connected Account
oh right...
Now about "Create and confirm a Payment Intent with the cloned Payment Method". How exactly? Is it like so?
const clonedPaymentMethod = await stripe.paymentMethods.create({
customer,
payment_method,
}, {
stripeAccount: connected_account_id,
});
const paymentIntent = await stripe.paymentIntents.create(
payment_method: clonedPaymentMethod.id
);
Oh, I think you need to pass the amount and currency eventhough it was passed into the cloned pm
const paymentIntent = await stripe.paymentIntents.create(
{
amount,
currency: 'usd',
payment_method: clonedPaymentMethod.id
}
);
When you create the PaymentIntent, you would also need to pass the in the Stripe Account Header to create the PaymentIntent on the Connected Account and pass in the amount/ currency:
{
stripeAccount: connected_account_id,
});
No, that step I already did:
const clonedPaymentMethod = await stripe.paymentMethods.create({
customer,
payment_method,
}, {
stripeAccount: connected_account_id,
});
I am on the next step
That is right, that step is to create the PaymentMethod on the Connected Account. Now, the PaymentMethod is on the Connected Account so you need to specify that the request to create the PaymentIntent is being made on the Connected Account
Sorry, it's a bit complicated. I previously used amount and currency to show the payment sheet
I see...
Otherwise, you'd get an error saying that object does not exist on the Platform Account
right, but you're talking about paymentMethods.create, not paymentIntents.create
Oh, you need to pass the connected account to paymentIntent
let me try
Oh I see
Sure!
So this is the call:
const paymentIntent = await stripe.paymentIntents.create(
{
amount,
currency: 'usd',
payment_method: clonedPaymentMethod.id
}, {
stripeAccount: connected_account_id,
}
);
right?
Yes, did you try?
still writing code. Haven't yet tried any of it ๐
WHat do you mean by "Create and confirm" My call is below. That's all I need to run it, right? Not sure what confirm means
const paymentIntentObject = {
currency: "usd",
amount,
customer,
description,
payment_method: clonedPaymentMethod.id
} as {
currency: string;
amount: number;
customer: any;
description: string;
receipt_email?: string;
payment_method: string;
};
if (receipt_email) {
paymentIntentObject.receipt_email = receipt_email;
}
const paymentIntent = await stripe.paymentIntents.create(
paymentIntentObject, {
stripeAccount: connected_account_id,
}
);
Also, about step 3 "If a new Payment Method is provided use a SetupIntent on the platform to set up the Payment Method for future use and make sure it's attached to the Customer".
I have:
// Set up the Payment Method for future use and make sure it's attached to the Customer
const setupIntent = await stripe.setupIntents.create({ customer, description });
// Clone the Payment Method to a connected account
const clonedPaymentMethod = await stripe.paymentMethods.create({
customer,
payment_method,
}, {
stripeAccount: connected_account_id,
});
Do I need to use setupIntent in the paymentMethods,create call somewhere?
I highly recommend that you try this on your end as we are unable to review your entire code here. You can either confirm automatically by passing confirm: truewhen you create the PaymentIntent, https://stripe.com/docs/api/payment_intents/create#create_payment_intent-confirm or make a separate call to confirm the Intent, https://stripe.com/docs/api/payment_intents/confirm
Oh ok. And what about this? At the moment I seem to create the setupIntent, but I don't see where I actually use it
That confirm parameter would be passed on the PaymentIntent creation at step 5.
Yes, I know. Got that. I'm asking about step 3. I shared my code above. I am creating const setupIntent = await stripe.setupIntents.create({ customer, description });, but I don't actually use it anywhere. SHould I? if so where?
๐ hello again! hopping in here since pgskc has to head out
give me a minute to catch up
Hey welcome ๐
For your latest question - the expectation would be that BEFORE you clone the payment method to the connected account you'd use the setup intent to setup it up properly on the customer
You'd onyl need to do that for new payment methods though, not if a saved one is used
So it's simply done on the customer object so Stripe knows a payment with the attached source will be performed?
As in - run the call, prior to cloning the payment method, but no need to use any of the returned values
So it's simply done on the customer object so Stripe knows a payment with the attached source will be performed?
Not exactly - it's done on the customer (on the platform) so that it only needs to be set up once on the platform and not for every single connected account
What do you guys mean by "on the platform"? on stripe? Isn't it exactly what I do with await stripe.setupIntents.create({ customer, description });?
Also, how would I know whether the customer is using a new payment method? Is that the value we get via shouldSavePaymentMethod from confirmHandler?
When I mean "on the platform" I mean that you have a platform account and a bunch of conencted accounts. When you create the initial payment method it's being created on the platform account, and that's the same account you should be creating the setup intent on
oh ok, so "on our app's stripe account. Not on the connected account's of the merchants", which really means my call await stripe.setupIntents.create({ customer }); is correct since I don't pass a stripeAccount, so it's created on the platform. right?
yup!
ok and Also, how would I know whether the customer is using a new payment method? Is that the value we get via shouldSavePaymentMethod from confirmHandler?
Let me check on that one - I'm less sure and want to double check something
k
Okay so you can look at the PaymentMethod you get back from the confirmHandler and check if it has customerId set (https://stripe.dev/stripe-react-native/api-reference/interfaces/PaymentMethod.Result.html#customerId)
That'll tell you whether that payment method has already been attached/setup on the customer
oh ok
ehhhh hang on
Yeah, that will not work
I am getting the paymentMethod via initPaymentSheet. It's a method that returns a callback confirmHandler which receives paymentMethod, shouldSavePaymentMethod, and intentCreationCallback. Are you saying I should inspect paymentMethod to see if it has a customerId?
oh, yeah, it contains customerId
Yup - the link I sent you has the shape of the PaymentMethod you'd receive in the confirmHandler (https://stripe.dev/stripe-react-native/api-reference/interfaces/PaymentMethod.Result.html