#seth_unexpected
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1287775090137632778
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- seth_code, 6 hours ago, 77 messages
Hi ๐ this sounds expected, we don't automatically deduplicate payment methods for you.
You would need to use the card.fingerprint value on the Payment Method objects to try to spot duplicates and delete the copies:
https://docs.stripe.com/api/payment_methods/object#payment_method_object-card-fingerprint
As noted in the description of that field, that may not work with wallets if we're provided the tokenized card number and that fluctuates between tokenizations (whereas without wallets we get the card number which remains consistent).
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
Ok, I will look into this. While I have you, can I ask a separate question?
Yup
I cannot get Apple Pay to show as "done" in the UI if the clientSecret passed back from my server is of manual validation type and status pending_approval. I am useing customFlow for the payment sheet, which is the suggested way to create payment intents before confirming them. Credit cards work just fine because once the payment is selected, no payment sheet is presented, but the apple pay flow shows me this message every time
However, the payment intent is successfully created and the sheet closes. The messaging is just wrong, because the payment did not fail it was created it just hasn't been confirmed yet.
Did you fully set up Apple Pay for your React Native app?
https://docs.stripe.com/payments/accept-a-payment?platform=react-native#react-native-apple-pay
Can you share the ID of a Payment Intent where you saw that behavior?
Yes apple pay is set up correctly. If I change the validation to automatic, I get the success messaging. I don't want to immediately confirm the payment intent though, as users are able to deny services that are requested (or confirm, if they choose).
Here is the ID: pi_3Q2CzTBghRV4WpFM1JIMxmSQ
๐ stepping in, catching up
When you say "change the validation to automatic' what do you mean exactly?
What specifically in your code are you changing
When I create the payment intent on my server, here, you can see ConfirmationMethod is set to manual. That means the paymentIntent has to be confirmed on the server side as well, later.
Ah okay. Hmmm not sure that is compatible here with this flow, but let me check
Ok
Yes
It seems that client side when I pass the clientSecret into the intentCreationCallback, it registers the payment intent as a failure because it is not complete yet. That isn't really true though, because it was created and is to be validated later.
However, when it's just a regular credit card it works just fine (no errors, etc)
I see
Well you are technically using our legacy integration here for server-side confirmation
Our recommended server-side confirmation integration is detailed at https://docs.stripe.com/payments/finalize-payments-on-the-server?platform=react-native&type=payment
Overall I'm not sure the Custom Flow was designed to be compatible with server-side confirmation in the first place since you already are indicating a Custom Flow when you set confirmation_method: 'manual'...
Why are you using both exactly?
It's the business logic of the app. Essentially, there are two users: clients and service providers.
- A client requests a reservation for a service, and we collect the payment from them without confirming it immediately.
- the service provider recieves a notification that they have been reuqested for a booking, and can either confirm or deny that request.
- If the request is confirmed, the payment intent is confirmed. If it is denied, we cancel the payment intent. That way the user isn't charged until the service provider agrees to providing the service.
In my eyes this seems to be a very standard business case (think a hair dresser cutting your hair) but I agree that Stripe seems to not allow for this type of implementation?
I've looked into this and it does not satisfy the business case. It requires to confirm the payment intent immediately (regardless of if it is done on the server side). It cannot come back to the client in status "Incomplete" -- otherwise the client will not properly update or indicates a failure.
Yep okay thanks for clarifying
Can you try this with the flow we outline at https://docs.stripe.com/payments/finalize-payments-on-the-server?platform=react-native&type=payment&integration=paymentsheet-flowcontroller ?
Unfortunately since you are using our legacy integration we aren't going to do anymore development work on that.
However, if the same issue occurs with this new integration then I'd be happy to file a bug report internally for us to get this fixed.
Can you explain to me exaclty how my implementation is legacy? It is done by following the docs.
Looking at this documention, I do it exactly this way.
confirmation_method: 'manual' is a legacy API.
With the above docs you render Payment Element before you create a PaymentIntent
So no, it isn't quite the same flow
Yes that is currently what I am doing. I render the payment element before I create the PaymentIntent.
Hmm I'm confused then... you should have two different buttons in this flow: one for presentation and one for confirmation?
Yes, I do
So why do you need to set confirmation_method: 'manual' here? You control when you confirm the PaymentIntent already so you can wait for the approval from your service provider before you do that. You are already confirming on the server and the Payment Sheet should have already dismissed at this point, no?
If confirmation_method is set to "automatic" (which is the default) then the payment is confirmed by the client when we hit intentCreationCallback:
const confirmHandler = async (paymentMethod: any, shouldSavePaymentMethod: any, intentCreationCallback: any) => {
if (user && selectedRide) {
await bookRide(user, selectedRide, paymentMethod.id)
.then((response) => {
console.log("secret is: ", response.clientSecret);
** intentCreationCallback({clientSecret: response.clientSecret});**
})
.catch(error => {
// intentCreationCallback({error: {
// code: 500,
// message: error,
// localizedMessage: error.message
// }});
})
}
}
That is not waiting for the server to confirm later, it is being done automatically. I just ran this scenario removing the manual confirmation, and you can see the payment intent is now "Succeeded" which is not the state it needs to be in: pi_3Q2DYBBghRV4WpFM0tju9bMm
Right but don't you wait to call that until your customer hits the second button? Sorry... I haven't tested this flow in a minute -- am I misremembering?
My understanding is that when using customFlow: true then the sheet dismisses after you call presentPaymentSheet() and then later on you call your confirm handler when you customer actually hits your "pay" button?
That is correct, but that works for physical credit cards (not apple pay or digital wallets).
Scenario 1 (Credit Cards): when I use a credit card, then we select the payment method (first button) and the sheet dismisses. Then I hit the "pay" button and all is great -- I create the intent on my server and there is no sheet to dismiss so I don't need to worry about intentCreationCallback. I can direct the user as I please.
Scenario 2 (Apple Pay): the Apple Pay sheet pops up when you hit the "pay" button (aks to use biometrics, password, etc) and the sheet does not dismiss unless we either hit intentCreationCallback (which is failing because of the state of the payment intent). If we don't hit intentCreationCallback it just times out and fails. Both scenarios present a failure to the user, even if it isn't one. The payment intent is still created like in scenario one, but the user experience is presenting an error.
Ah okay -- I was not aware that the Apple Pay sheet pops up again when you hit "pay" here... I'm surprised it does that...
So you get the Apple Pay sheet twice?
Once initially to collect the PM and then again when you hit "Pay"?
No only once, I can send some screenshots one second
I am just using a basic screen right now. This is before the payment method is selected
Apple pay is now selected
Press book with apple pay, there is the new sheet
Ah! Okay I see
Right because the Apple Pay modal doesn't actually present when you select Apple Pay within Payment Sheet as an option there
Okay thanks for clarifying
Of course!
I wasn't aware that is how it worked with Apple Pay in this flow.
Alright I'll file a ticket about this
I think for now the only workaround here is going to be to use a SetupIntent instead
Thank you SO much! I appreciate it
So basically you check in your backend what type of PaymentMethod you are handling
Then if it is Apple Pay you can use a SetupIntent to close the Payment Sheet
Then you can immediately create a PaymentIntent and confirm it using that new PaymentMethod to charge
Can you try that and see if it works as a workaround for now?
Yes I can try that, I won't have time right now to do it but I can give it a shot. The business logic is pretty set in stone so it will be pretty complex to change how we are doing things...so I might have to just wait and see if this flow can be resolved and re-integrate apple pay once it is.
That makes sense. You'll want to watch the React Native SDK Changelog (https://github.com/stripe/stripe-react-native/blob/master/CHANGELOG.md) which should have a note when there is a new version released with a change in this behavior.
If I create a SetupIntent, do I have to use it? I am already creating the PaymentIntent and I know that path works just fine. So if I pass a "dummy" setupintent back to the client just to close the apple pay sheet, would that be considered okay?
Hmmm good question -- I think client-side it is going to check the status of the SetupIntent, but not positive. You'll want to test it
Okay, I will test and mess around with the options. I appreicate you putting in the ticket for me, hopefully it can get fixed