#brandontrytn
1 messages ยท Page 1 of 1 (latest)
126.25: pi_3NRIfwLunEUcvTyc17nqFWKr
575.70: pi_3NRIfwLunEUcvTyc17nqFWKr
315: ch_3NRIcELunEUcvTyc1ytKjeaW
So the overall confusion is around the $315 charge, correct?
Like you aren't expecting that charge?
correct, we deal in payment intents, so the two payment intent charges are correct. our system doesn't make charges and the customer got charged that 315 but we don't know where it came from
it has since been refunded so just trying to figure out where it came from
Alright well to be clear Charges are created from confirming a PaymentIntent. And that Charge is associated to a PaymentIntent (it wasn't created directly). https://dashboard.stripe.com/logs/req_rnMv0lzSxrDpCl is the creation request and https://dashboard.stripe.com/logs/req_EpQvIDB7tARDRP is the confirmation request.
Comparing to one of the other PaymentIntents, I can see that this one was created using the same IP as the other -- so it does seem like it was deliberately created from your server (if it was a different IP then that could indicate your key was leaked or something).
Overall nothing looks amiss to me here. I think the two options are either that something failed with the data ingestion on your end for this Charge and thus it is "unexpected", or there is some sort of bug that caused it to be created/confirmed though to me that seems more unlikely
so to understand the workflow we have a pending payment intent. when we call confirmPayment from the JS SDK it creates the charge record and then confirms the payment intent?
we do utilize webhooks for some data ingestion, like recording gateway processessing fees and sending meta data over to stripe to attach to the payment records
How do you record Charges on your end?
we get the charge succeeded webhook from stripe and then store a record of it with our payment record on our end
Gotcha okay that seems fine.
So why is this Charge "unexpected"?
The customer just said they didn't make that purchase?
we don't have a record of the charge and the customer complained to the operator they got an erroneous charge
Got it
Yeah I mean we have pretty limited insight here
So nothing really looks weird from my perspective
Is this the first time this has happened?
this is the first time I've heard of it happening
I can see that your Webhook handler responded successfully to the Webhook: https://dashboard.stripe.com/events/evt_3NRIcELunEUcvTyc19sL4HfM
So I would mostly be concerned for why you don't have the data on your end.
I think adding some logging to capture each step of that data ingestion process is the way to go. Then if this happens again you can look at those logs to try and debug what happened.
we log a ton of stuff, let me see what I have in the way of logs around that area. the event link didn't seem to work for me but all the others have
that one works
so we do have logging for this. I see 3 webhooks with that charge ID in it. the only way we have to tie a transaction on our side to the data sent from your side is by looking up the pi_ ID. it looks like this charge was a different pi_ than the two other charges
I'm not positive what you mean by that. Each successful Charge will be associated to a unique PaymentIntent
A PaymentIntent is a state-machine object. So if a Charge attempt fails then you can have multiple Charges associated to a PaymentIntent. But once there is a successful confirmation, then there would just be one successful Charge for each PaymentIntent
So what do you mean by "the two other charges"?
earlier the 575 and 126 charges both appear to have the same pi_ id
oh nevermind, I was looking at the wrong thing
๐
ok, tracing things back, it appears when it came back from stripe from the confirmPayment call it was in a semi-error state. meaning there was an error object of payment_intent_unexpected_state but the payment_intent.status field shows as succeeded. since it was an error state our system does not continue with the purchase on our end. should we not look flatly at the error object but also the status for this?
currently if we receive anything for an error object we fault and do not continue
Ah okay I do see that there were multiple confirmation attempts here -- there were 3 confirmation attempts after the initial successful one.
Are you disabling the button on click?
Also yeah you shouldn't really care about this error object at all when it comes to data ingestion
You should rely on the Webhook itself
disable it as well as pop an overlay, but on error we re-enable so they could try again with a different payment method to self-correct
Ah okay so you'll want to do some amount of debugging here on your frontend for how the customer was able to confirm the PaymentIntent again even though there was a successful attempt
Looks like these confirmation attempts happened 10 seconds apart
yeah I believe they hit an error state and we allowed them to submit again, but seems like even though there was an error it really wasn't
I see the first attempt. stripe came back with error incomplete_number
That is validation of the Element itself
There was no error/decline with the PaymentIntent
so we can't currently rely on the webhook to determine success as we need to create the payment record after succes in order to tell the user the payment was successful. the entire time we've used the payment element we've looked at the response from confirmPayment to determine if it was successful. to continue this path we can't look at only the error object but also the payment intent status, would that be a fair statement?
Yeah you should certainly check the PaymentIntent status and that is how I would determine to show the customer a success message.
That all said, I would recommend not tying this process to your data ingestion. You should have a separate process for data ingestion based on Webhooks since your customer could drop off at any point after starting the confimration flow and before you get to that promise actually resolving
yeah it's in the backlog. just a very large undertaking
is there a support doc that gives the various status that could be returned for this?