Skip to content
Insights · Engineering

Which intent did that charge open?

Name the intent that charge opened: id, status, and amount. Another intent can name a different charge, and another account does not list it.

Scroll
EngineeringOct 30, 202612 min readBy Salman Naqvi, Founder & CEO
Which intent did that charge open?

A customer says they paid, or says the card was never charged. Tonight, three proofs, in a console you administer. Name the intent that charge opened: the payment intent id, the status, and the amount. If the latest charge is still null, write null, and write the status that is actually stored. Show a different intent whose id, or whose charge, is not this one. Show another account's list that does not contain this intent. If any of the three needs the person who wired checkout, you have not named the intent. You have a receipt and a guess.

This is the intent on one charge. It is not the invoice. Which invoice did that charge pay? is the invoice id, the status, and the total. An intent can be succeeded while the invoice field on a different object is a different id, and an invoice can exist while this intent's customer is still null. It is not the quote. Which quote did that customer accept? is a quote id, a status, and a total. A quote can be accepted while no payment intent stores that total. It is not the card. Which card did that charge use? is the card on a charge. A card brand is not a payment intent id. It is not the check on a commit, and it is not the message a run appended. Those are different objects, and they are not this id.

None of what follows is a rate for this product, and none of it is legal advice. The fields below are one processor's current description of a payment intent, and the two samples are not the same object. The counts below that are a 2025 paper about one processor's authorization experiments. An amount on an example is not a census of your buyers. A model that never opened your intent cannot name the status on the intent you opened tonight. They do tell you which numbers people mix up when they try to sound precise about a charge they have not opened.

Stripe's create response prints id pi_3MtwBwLkdIwHu7ix28a3tqPa, object payment_intent, amount 2000, amount_capturable 0, amount_received 0, and created 1680800504. The id is 27 characters. Status is requires_payment_method, 23 characters. capture_method is automatic, 9 characters. confirmation_method is automatic, also 9. currency is usd, 3 characters. customer is null. latest_charge is null. payment_method is null. cancellation_reason is null. canceled_at is null. livemode is false. A null charge is not a missing intent. payment_method_types lists card and link. Two names. card is not link. The client_secret is pi_3MtwBwLkdIwHu7ix28a3tqPa_secret_YrKJUKribcBjcG8HVhfZluoGH, 60 characters. 60 is not 27. The secret begins with the id, then _secret_, which is 8 characters, then 25 more. 27 plus 8 plus 25 is 60. The addition matches the length, and it does not turn a secret into a status. The create request on the same page sends amount 2000, currency usd, and automatic payment methods enabled. The version header is 2026-10-28.endive. That string is 17 characters. It is not the integer 1680800504 (Stripe, Create a PaymentIntent).

The status names are seven, and the create sample is only the first. The object page lists requires_payment_method, requires_confirmation, requires_action, processing, requires_capture, canceled, and succeeded. Seven names. requires_payment_method is not succeeded. succeeded is not canceled. The spelling on that page is canceled, one l, not the two-l spelling a git host uses for a check. Seven names are not 2000, and seven names are not 23 characters. The cancellation reasons are a second list: abandoned, automatic, duplicate, expired, failed_invoice, fraudulent, requested_by_customer, and void_invoice. Eight names. The sample's cancellation_reason is null. Null is not abandoned, and eight is not seven. automatic on the reason list is not automatic on capture_method. The same word sits in two enums. Copying it from the wrong list is how a cancellation gets invented (Stripe, The PaymentIntent object).

The amount rules are not the sample's 2000. The object page says the minimum amount is $0.50 US or the equivalent, and that the amount supports up to eight digits, for example 99999999. 2000 is not 50. 2000 is not 99999999. Eight digits are not two names in payment_method_types. The page does not print a dollar sign next to 2000. Do not rewrite 2000 as twenty dollars because the division by 100 is tidy, and do not rewrite it as the minimum because the minimum is the only dollar figure on the page. amount_received 0 on a create sample is not a refund. It is the stored fact that this sample has not collected the amount. 2000 minus 0 is 2000. The subtraction matches the amount, and it does not make the status succeeded. capture_method on the sample is automatic. The same attribute says automatic_async is the default, 15 characters, and that it is recommended over automatic. 15 is not 9. The sample is not sitting on the default the attribute names. statement_descriptor, when you set one for a non-card charge, has a 22-character limit, and setting it for a card charge returns an error. The sample stores null. Null is not 22 characters.

The confirm call is a second page, and it is not the create sample. The confirm response prints id pi_3MtweELkdIwHu7ix0Dt0gF2H. Also 27 characters, and not pi_3MtwBwLkdIwHu7ix28a3tqPa. Status is succeeded, 9 characters. 9 is not 23. amount is again 2000. amount_received is 2000, not the create sample's 0. created is 1680802258. The confirm sample's created minus the create sample's created is 1754 seconds, which is 29 minutes and 14 seconds. 1754 is not 1680800504. latest_charge is ch_3MtweELkdIwHu7ix05lnLAFd, 27 characters, the same length as a payment intent id, and a different prefix. A charge id is not an intent id. payment_method is pm_1MtweELkdIwHu7ixxrsejPtG, also 27 characters. The confirm request sends payment_method=pm_card_visa, 12 characters, and a return URL. 12 is not 27. pm_card_visa is not pm_1MtweELkdIwHu7ixxrsejPtG. The request string and the stored id are not the same fact. customer is still null. A succeeded status with a null customer is the sample's stored fact. It is not a reason to paste a customer id from a different object. The client_secret is again 60 characters, and it is not the create sample's secret. cancellation_reason is still null. Succeeded is not a cancellation (Stripe, Confirm a PaymentIntent).

The study people reach for when they want an authorization rate did not open this console. Akhila Vangara and Alex Egg, at Adyen, test contextual bandits on payment authorization. The logged dataset is 180 million samples over 30 days, each with 56 features, and the table says the imbalance is 90% positive. 90 is not 0.1. 56 is not 2000. 30 days is not four weeks. Four weeks is 28 days, and the paper does not print 28. The best SquareCB variant achieved a +0.1% uplift over epsilon-greedy in the four-week test, which they translate to an estimated 9 million incremental authorized transactions per year. 0.1 is not 9 million, and 9 million is not 180 million. The paper does not print the multiplication that turns the tenth of a percent into the 9 million. A 95% interval is not the 75% interval the same section also says they calculated (Vangara and Egg, Contextual Bandits in Payment Processing).

The exploration rates do not land on the policy names. The 1% epsilon-greedy policy was exploring 0.7% of the time. 0.7 is not 1. The most exploitative SquareCB variant they compare there explored 1.2%. 1.2 is not 0.7, and 1.2 is not 1. A later figure caption says epsilon-greedy 6% is 3.45% effective, and SquareCB 10k is 3.6%, which they call essentially the same, and then they write equal exploration rates of 3.5%. 3.45 is not 6. 3.6 is not 3.45. 3.5 is not 3.45, and 3.5 is not 3.6. On the exploration traffic they report +11%. On the exploitation traffic they report a reduction of 0.33%. 11 is not 0.33, and 0.33 is not the overall 0.1. The action set is described as between 2 and 15 actions, median 4. 4 is not 2, and 4 is not 15. None of these percents is status succeeded, and none of them is amount 2000.

The table of durations does not match the sentence that says the tests ran for four weeks. Oracle 1 is 4 weeks at 5% of traffic. Oracle 2 is 1 week at 5%. Oracle 3 is 1 week at 5%. The epsilon-greedy row is 4 weeks at 5%, and its learning-rate cell is N/A. 1 is not 4. Two of the three oracles are not the four-week period the prose names. The learning-rate column prints 1%, 4%, and 6% on the oracle rows, which are the same three numbers the prose uses for epsilon-greedy exploration. The digits match. The rows do not. A 1% learning rate on Oracle 1 is not the 1% exploration policy, and the epsilon-greedy row does not store a learning rate. 5% of traffic is not 90% positive, and 5 is not 56 features.

Do the three proofs on one real intent, in the console that actually holds it. First, the binding. Copy the payment intent id, the status, the amount, the currency, the amount_received, the latest_charge, and the customer. If latest_charge is null, write null. If customer is null, write null. If the status is requires_payment_method, write that. Do not paste succeeded onto it because a confirm sample succeeded. Do not paste pm_card_visa onto a stored payment method whose id is 27 characters. Do not infer 2000 because two samples print it. Second, the other intent. A different intent, with a different id, or a different charge, is not this one. The create id and the confirm id are already two examples, and stitching them into one history is how a 1754-second gap becomes a story about your customer. A chart of authorization uplift is not that second intent. Third, the other account. A list that belongs to someone else does not contain this intent id. If the only list is a single shared table and you cannot say whose intent it is, write that. A tenant you cannot name is the finding.

Three moves feel like the proof and are a second problem. Confirming the intent, or canceling it, because the status was embarrassing, before you have copied the id. Confirm can move requires_payment_method toward succeeded and can create a charge. Cancel writes a cancellation. Neither call tells you which intent you were looking at if you have not copied the id first. Quoting +0.1% or 9 million because one of them looks precise, while the intent you were asked about is one row, and the 180 million samples that produced those phrases had not opened your customer. Asking a model which of the seven statuses it was. The model will pick a plausible name. It will not open the intent. A card you have not kept, while the customer is arguing about a brand, is which card did that charge use?. Opening that screen does not name the intent id.

The path is ordinary when an operator can open one merchant's payment without opening the next merchant's payment as the way to prove it. PayOrch is a payment orchestration dashboard: wallets, providers, merchants, fees, and fraud controls in one view. The shape that matters here is one merchant you can point at, in an account you administer, distinct from the next merchant. That case is not a payment-intent ledger. Nothing in that sentence is a headcount, a duration, or a result figure. If the only control on the screen changes every merchant's volume together, you do not have this proof. You have a totals page.

There is a version of this afternoon where hiring the path is the wrong purchase. Nothing is for sale, because the product does not take money yet. You have no product. You are still choosing who will build, and the document in front of you is a term sheet. The criteria for that choice sit on the page written for a top SaaS development company. That page is criteria. It does not rank anyone, including us. The only fact in the room is a paper about someone else's authorizations. 0.1% is not your intent, and 2000 is not your intent, and 9 million is not your intent. A customer has already seen another customer's payment. Naming a status does not close a leak. Or you wanted a lawyer to say whether a succeeded intent is a contract. Hire the lawyer.

When the intent is real and the console cannot name it, the missing object is specific. An admin action, in an account you administer, that shows one intent id, one status, and one amount, shows a different intent that is not that one, and shows another account's list without it. A startup software development company that expects this will have put that action next to the rest of the billing screen, before a stranger's complaint is the way you discover the vendor owns the intent. One that needs a call in order for you to see which intent is stored is telling you who holds the charge. If the first slice is a fixed capability, an AI integration sprint is the shape where the acceptance sentence can include the three proofs. If you do not yet know which system stores the intent, a two-week AI readiness assessment maps the systems. The findings are yours. They are not a promise that a paper's uplift applies, and they are not 2000.

The check a commit reported, and the message a run appended, are different objects: which check did that commit report? and which message did that run append?. Do not record either on this page. A check-run id is not a payment intent id. A message id is not a status.

Before you tell them the charge went through, do the three proofs and write the status. Name the intent, the status, and the amount, or write that the latest charge was null. Show a different intent that is not that one. Show another account's list that does not hold it. Do not confirm an intent to avoid reading the status, and do not ask a model which of the seven it was. A paper can tell you how far an authorization rate moved on someone else's traffic, including the 0.1 that is not the 11 and is not the 0.33. The binding is the intent you can defend.

Questions

Three records, in a console you administer. The payment intent id, the status, and the amount, or a written line that the latest charge is still null. A different intent whose id or charge is not this one. Another account's list that does not contain this intent. If any of the three needs the person who wired checkout, you do not have the proof.

No. A tenth of a percent on someone else's processor is not the id on this intent. An intent you can defend is the id, the status, and the amount, or a written line that the charge field was null. 0.1% in one paper is not status succeeded, and 2000 on a sample is not your customer's amount.

When nothing is for sale, when you have no product, when you are still choosing a firm, when the only fact in the room is a paper's authorization uplift, when a customer has already seen another customer's payment, or when you wanted a lawyer.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→