#dhew_api
1 messages ยท Page 1 of 1 (latest)
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.
- dhew_best-practices, 1 day ago, 27 messages
๐ 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/1240383512016588820
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Hi there
You basically just need two Events here
checkout.session.succeeded
And checkout.session.async_payment_succeeded
If you want failures for async then you could also listen for checkout.session.async_payment_failed
Hi. But wont checkout.session.completed fire even with an async authorization?
What is the foolproof way of separating the sucessful card payments from a successful async authorization, but not succeeded yet?
Yeah sorry
If you want to separate that out then you can either look at the payment_status on the Checkout Session (https://docs.stripe.com/api/checkout/sessions/object#checkout_session_object-payment_status) or you can expand or retrieve the PaymentIntent and look at its status
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
The PaymentIntent will be in processing for async payment methods
Ok, but I dont want to query for the status--I'd like to know if there is an event I can look for. Working backwards, I understand I can use the checkout.session.async_payment_failed (or succeeded) event, if I know the payment is async. But I'm not clear on which event to monitor for the card success/fail exclusively (i.e., the checkout session success would 'fool' me into thinking everything is paid, even if there is a async payment still pending).
- back up one step: what event should I pay attention to to know which payment type (card v some async method) the customer is using?
(I am fairly sure the checkout session does not specify the payment mehtod used)
Yeah mostly you do need to write out some of your own logic here -- Events are always going to overlap in some senses. There aren't individual Events for every specific scenario.
What you want to do is:
Sure--just looking to make sure I'm doing that properly/looking at the right events to make decision on
I assume I start with checkout.session.completed--that will give me a paymentintent ID, but then I get a bit lost
- listen for the
checkout.session.completedEvent. When you receive it you then immediately retrieve the Checkout Session and you can expand whatever you want -- it sounds like you do care about things like the payment method used so you would want to expand thepayment_intent.latest_chargewhen you receive that Event.
That latest_charge will be a Charge object: https://docs.stripe.com/api/charges/object
So it will have properties like payment_method_details
From which you can see info about the PaymentMethod
At this point you can also check the PaymentIntent's status -- if succeeded then you know it was synchronous (card) and you are done. If processing then you know async and you wait for the checkout.session.async_payment_succeeded Event
Do I need to monitor the charge object or just the payment intent object?
Maybe this is where I'm getting a little confused--is watching for payment_intent.payment_succeeded/failed not sufficient for a card payment?
Yep it is. That is another way to go if you want
The reality is that there isn't one single "right" way here.
Ok, so a safe way to do this is monitor these events: 1) Checkout session succeeded 2) Look at paymentintent ID and find the payment method there to set a flag in my system for that order--its sync or async 3) wait for either payment_intent.payment_succeeded or checkout.session.async_payment_succeeded to ship the product?
Yep
Or should I just monitor for any payment_intent.created? I do set a transfer group on checkout of teh uique orderID.
Though that is why I recommended not listening for payment_intent.succeeded since that will fire in both sync and async cases as well.
Versus just checking on the initial checkout.session.completed
(Which fires in both cases too)
Ok. So checkout.session.completed, in either payment method, is largely a 'payment started/authorized" verification. At that point, the actual payment confirmation/event where we are 'safe' to ship product is going to come from the payment_intent.payment_succeeded OR checkout.session.async_payment_succeeded.
For an async payment method, will payment_intent.payment_succeeded fire at all? Or is it safe to consider all payment_intent.payment_succeeded events solely related to sync payment methods?
No, for sync payment methods (cards) the checkout.session.completed Event will indicate that the Charge was successfully authorized, not just started.
Yes, it will also fire.
Really the best thing to do here is to test this stuff out!
Then you can see all the relevant Events
Yeah, I've done a bit of that, but I'm just trying to make sure I don't overlook something and think "X only happens when Y"...but that not actually be the case!
I hear ya ๐
I think you are in a pretty good place here.
Use checkout.session.completed and check what you need to check -- update your database accordingly. Then use checkout.session.async_payment_succeeded for async payment methods moving to succeeded
That is the simplest and most straightforward way to go
Got it. And for card payments, as long as the payment intent "payment_method_types" is NOT one of the async types, payment_intent.payment_succeeded is the event to mark successful payment?
Can you confirm that this "payment_method_types" on the payment intent should always resolve to a single type? I think I grabbed a very similar variable from a checkout session and it had several items in it.
Haha--glad I asked
That is why above I said you should look at the payment_intent.latest_charge
That will be the Charge object
Which will indicate the actual payment method used for that Charge
For card payments you don't really need to look at the PaymentIntent at all!
If you receive a checkout.session.completed Event and it is paid then you know it was a Card as it was synchronous
If you do want to double check you do the same thing as above -- you retrieve the Checkout Session and expand payment_intent.latest_charge
Are you familiar with expansion?
I'm receiving the API via a 3rd arty tool, so I'm limited on what I can do.
So I think the only Q remaining is when the specific payment_method used is first sent
Its not in the checkout session completed, is it?
Hmmm it is mostly just adding an options parameter: https://docs.stripe.com/expand
You should be able to still do that with a 3rd party tool
The specific payment method will be included with the Charge which is created as soon as the Checkout Session is completed.
The Charge will be in pending for async payment methods
Ok--so I do need to look at the Charge item then. The specific method isnt pushed up into the payment intent at some point?
In that case, do I even really need the payment intent event? Or just look for the charge.pending one?
(again, given ive got a transfer group, so I can relate all these things together)
The ID will be presnt on the PaymentIntent, yes (https://docs.stripe.com/api/payment_intents/object#payment_intent_object-payment_method). But you would need to expand that to see the details, which is why it is easier to look at the Charge imo.
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
I understand.
Yeah up to you -- as I noted above I would only use the checkout.session.completed Event and then retrieve that Checkout Session object and expand as necessary from there.
But if you want to go another route then that works
Yeah I cant expand directly--Id have to have another outbound query to stripe for that.
I'm going to monitor for the checkout.session.compelted, but I just need some bulletproof way to say the customer is using this exact payment method for this checkout session.
From what I'm hearing, a solid way to check this is monitor for some sort of charge.pending or similar event
Without retrieving any of the corresponding objects that doesn't really work...
Ah you are using transfer_group for your order ID
So that should get carried down to the Charge as well
Sorry, most folks use metadata for their order ID
Which would not get carried down to the Charge
I'm using both. Haha.
Yeah I mean this is a bit of a weird use for transfer_group -- it isn't what it was designed for -- but it totally works for this
Whats it for then? I thought it was to ensure all payments for a single order were related to each other? So if there was an order that needed 3 payments over time or something, we could reconcile them all otgether before sending on to the Connect user?
Yes it is designed to link PaymentIntent's/Charges to Transfers in a Connect set up
So that you associate them together
Sorry for the sidebar. Back to the main issue: Can I just monitor for charge.succeeded to get all the basic info I need for sync payments? If that payment method is a card, I'm good to go. If its async type, then I need to wait for checkout.session.async_payment_succeeded.
checkout.session.completed is then not really necessary? Maybe to use as a signal the async method, if I've already determined the charge is async, is in fact in a pending state?
sorry, I guess I should watch for charge.pending, not succeeded, as the first event
Yes you could just listen for charge.succeeded
But that will still fire in both cases (when an async payment method's Charge is successful and when a Card is successful)
Ok. I think I have a workable solution. One more question: when can a payment intent have multiple "payment_method_types"? In my limited testing all of the paymentintents from my checkout sessions have only said the type actually being used. So the checkout session shows card and us_bank_account, but the paymentintent that follows only shows one or the other.
Ah that may be true at this point. In the past we would create the PaymentIntent at the beginning of the Checkout Session (so it would have all listed payment method types), but to enable more features we now create it on the actual submission so now I'd assume we create it with just the relevant payment_method_type set.
So yeah there likely will just be one. However, that's somewhat brittle to rely on -- no guarantee it will always stay like that.
Ha, ok, got it.
To be sure I'd look at the actual PaymentMethod itself
By this you mean the charge object?
Yep if you are going to listen to charge.pending and/or charge.succeeded then it will be indicated within those Events
Ok. Great, thanks for all the help!
Sure thing
Super valuable to be able to chat directly
Glad to hear it ๐