Skip to content
Insights · Engineering

Which refund did that charge get?

Name the refund on that charge: the id, the status, and the amount. A different refund can sit on another charge, and another account does not list it.

Scroll
EngineeringOct 30, 202615 min readBy Salman Naqvi, Founder & CEO
Which refund did that charge get?

A customer says the money came back, or says it did not. Tonight, three proofs, in a console you administer. Name the refund on that charge: the refund id, the status, the amount, and the charge it points at. Show a different refund whose charge, or whose amount, is not this one. Show another account's list that does not contain this refund. If any of the three needs the person who wired checkout, you have not shown the refund. You have a receipt total and a guess.

This is the method on one refund. It is not the card. Which card did that charge use? is the brand and the last four. A refund can succeed while the brand is still the one they dispute, and a brand is not a refund id. It is not the figure on the screen. Show the price they accepted is the amount they were shown and the amount that was taken. A price can be right while no refund exists, and a refund can exist while the screen they remember is a different number. It is not the subscription. Which status is that subscription in? is one of the names a subscription stores. A charge can be partly refunded while the subscription is still active, and succeeded on a refund is not active on a plan. It is not a second charge. Stop the retry that landed twice starts after a correct action happened again. A second refund is a second id. A second id is not a duplicate charge.

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 refund. The counts below that are a preprint of interviews with merchants and platform workers, plus numbers those interviews cite from other documents. A status enum is not a census of your customers. An interview that never opened your charge cannot name the refund on the charge you opened tonight. They do tell you which numbers people mix up when they try to sound precise about a refund they have not opened.

Stripe's refund object says the status can be pending, requires_action, succeeded, failed, or canceled. Five names. succeeded is not a reason, and failed is not a failure_reason. The sample object prints status succeeded, reason null, and receipt_number null. A null reason is not the word duplicate. A null receipt is not a missing refund. The sample's id is re_1Nispe2eZvKYlo2Cd31jOCgZ. That string is an identifier. The sample's amount is 1000, its currency is usd, and its created value is the integer 1692942318. 1000 is an integer in the smallest currency unit. The page does not print a dollar sign next to it. Do not rewrite 1000 as a price you prefer. 1692942318 is a timestamp on an example. It is not an expiration year, and it is not a count of refunds. The sample's charge is ch_1NirD82eZvKYlo2CIvbtLWuY. The sample's payment_intent is pi_1GszsK2eZvKYlo2CfhZyoZLp. Two identifiers. A charge id is not a payment intent, even when both sit on the same refund. The balance_transaction is txn_1Nispe2eZvKYlo2CYezqFhEx. A balance transaction is not the refund id (Stripe, The Refund object).

The reason you may set, and the reason a failure carries, are not the same list. The reason enum is duplicate, expired_uncaptured_charge, fraudulent, or requested_by_customer. Four names. The sample prints null, so the example did not pick one of the four. failure_reason, which appears after a failure, is lost_or_stolen_card, expired_or_canceled_card, charge_for_pending_refund_disputed, insufficient_funds, declined, merchant_request, or unknown. Seven names. pending_reason, which explains a pending refund, is processing, insufficient_funds, or charge_pending. Three names. insufficient_funds is on both the failure list and the pending list. The same string is not the same field. A pending refund whose reason is insufficient_funds has not failed. A failed refund whose reason is insufficient_funds is not still pending. unknown as a failure_reason is not a null reason, and it is not the brand unknown on a card. fraudulent as a reason you set is not lost_or_stolen_card. expired_uncaptured_charge is not expired_or_canceled_card. One is a reason on a refund you created. The other is a reason a bank or a partner refused one.

The destination is a second object, and the examples do not share one reference. On the object page, destination_details.type is card, and the card hash prints type refund, reference_status available, reference_type acquirer_reference_number, and reference 123456789012. 123456789012 is twelve digits on an example. It is not your customer's card, and it is not the last four. The guide's trace example prints a different id, re_1234, and a different reference, 123456. 123456 is six digits on a second example. It is not 123456789012. re_1234 is not re_1Nispe2eZvKYlo2Cd31jOCgZ. A reversal is a third string in the same slot: destination_details card type equals reversal, not refund. The sample's type is refund. Do not call the sample a reversal because a nearby paragraph explains reversals. A blik example on the failure section prints id pyr_1234 and a network_decline_code whose text is the words decline_code. That is a placeholder. It is not an acquirer reference number, and pyr_ is not re_.

The guide's clocks do not collapse into one wait. A customer sees the credit approximately 5 to 10 business days later, depending on the bank. A failed refund can take up to 30 days from the post date for the bank to return the amount to Stripe. An ARN can take up to 7 business days after you initiate the refund. 5 to 10 is not 7, and 7 is not 30. Business days are not the Unix integer on the sample. An ARN is not available when the movement was a reversal, because the original charge is not processed. A reference_status of available on the sample is not a promise that every refund has an ARN in seven days. You can issue more than one refund against a charge, and you cannot refund a total greater than the original charge amount. Two refunds are two ids. Their amounts, added, still cannot pass the charge. A partial refund's curl passes amount=1000 against payment_intent pi_Aabcxyz01aDfoo. That 1000 is the same integer as the sample object's amount, on a different example, with a different payment intent. Do not merge the two examples into one refund. Refunds go back to the original payment method. You cannot send one to a different card. A different card is the other article. Canceling a PaymentIntent is a different verb. You can cancel one only in requires_payment_method, requires_capture, requires_confirmation, requires_action, or processing when the method is a US bank account. A PaymentIntent cannot be canceled after it has succeeded. Refunding a payment that succeeded is not canceling it (Stripe, Refund and cancel payments).

requires_action is a status, and it is not a next step you invent. For some methods without a native refund, the guide names Konbini, PromptPay, Boleto, and bank transfers. Four examples. The refund enters requires_action, and Stripe emails the customer. next_action.type in the description is display_details. display_details is not a status. The transition table is specific. Created and emailed is requires_action. The customer submits bank details and Stripe starts processing is pending. Expected to arrive is succeeded. The bank returns the funds is requires_action again. The customer does not respond before expiration is failed. Canceled while it is still requires_action is canceled. requires_action appears twice in that table, for two events. A return to requires_action is not the first email. failed is not canceled. Card refunds, separately, can be canceled from the Dashboard for a short period, and only if the refund has not been processed as a charge reversal. The API and the Dashboard can both cancel the kind that is still collecting bank details. Dashboard-only is not API-and-Dashboard. A canceled refund still carries failure_reason and failure_balance_transaction, because the guide calls a cancellation a type of refund failure. A failure_reason on a canceled refund is not the status canceled. The status is canceled. The reason is a different field.

Connect does not use one debit for every charge type. Stripe debits the connected account for a refund of a direct charge. Stripe debits the platform for a refund of a destination charge, or of a separate charge and transfer. A platform debit is not a connected-account debit. If the platform uses destination charges, funds from a failed refund, and funds from a canceled refund, deposit to the platform balance. The event list is another set of names. refund.created, refund.updated, and refund.failed are the refund object. charge.refunded fires for a partial refund as well as a full one, and the guide tells you to listen to refund.created for the refund itself. review.closed carries a reason of approved, disputed, canceled, refunded, or refunded_as_fraud. Five names. canceled on a review is not refund status canceled. refunded on a review is not a refund id. approved on a review is not a pull-request approval. charge.refund.updated is deprecated on that page. A deprecated event is not a missing refund.

The study people reach for when they want a refund-fraud rate is a different document, and it did not open a processor console. Shuning Zhang, Eve He, Xiao Zhan, Shijing He, Robert Xiao, Xin Yi, and Hewu Li interviewed merchants and platform workers about generative tools used to fake product defects. The abstract says merchants N=17 and platform workers N=13. The method says they recruited 29 participants, 17 with merchant experience and 13 with platform experience, and that one person had both. 17 plus 13 is 30. They print 29, and they print the overlap. Do not replace 29 with 30, and do not drop the overlap to make the addition match. Merchant-side, 7 male and 10 female. 7 plus 10 is 17. Platform-side, 3 male and 10 female. 3 plus 10 is 13. Those 10s are not the same ten people. Merchant platforms they name: Taobao 9, Pinduoduo 7, Douyin 4. 9 plus 7 plus 4 is 20, which is more than 17, so the sentence is not one platform per person. Do not cite 20 as a headcount they printed. Platform-side they name Pinduoduo 7, Taobao 2, Meituan 1, and Dewu 2. That addition is 12, and they also say the platform group is 13. The page does not print the missing one. Do not invent it (Zhang et al., Generative AI-Enabled Refund Fraud).

The clocks and the money in that paper are not one unit. Interviews averaged 48.3 minutes, with a standard deviation of 13.1 minutes, and a range of 25 to 82 minutes. 48.3 is not 13.1. 25 is not 82. 13.1 is a spread in minutes. It is not the 13 platform workers. Each participant was paid 100 RMB. A merchant's example of profit on one fruit order is about one CNY. A different sentence says if they want ten CNY, you can just give it. 100 RMB is not 10 CNY, and neither is 1 CNY, and none of them is the sample refund's 1000. The introduction says the platforms it names generated 1.7 trillion RMB in the 2025 Double 11 festival. 1.7 trillion is not 100 RMB, and 2025 is not a minute count. The same introduction attributes approximately 50% of merchant appeals to inappropriate refunds, as a news report, and 57% of surveyed merchants reporting more refund and policy abuse, as a global fraud report. 50% is not 57%. Neither is 12 of 17, and neither is 11 of 17. 12 of 17 merchant-side participants talked about the cost of listing evidence. 11 of 17 talked about paying to avoid a bad review. 12 is not 11. Both denominators are 17. They are not 29, and they are not 13.

The percentages they cite from other papers are a third pile. They say Zhu and Viswanath each achieved over 94% anomaly detection. They say reputation scoring can reach up to 84.6%, then fall to 60% to 80%, with recall as low as 0.65 in a different citation. 94% is not 84.6%. 84.6% is not 60%. 0.65 is not 60%, and it is not a Stripe status. They cite a measurement that 35% of fraudulent accounts are terminated prematurely and 90% are closed within four days. 35% is not 90%. Four days is not 48.3 minutes, and it is not 5 to 10 business days. The page header also prints a placeholder DOI and a template conference line dated 2018 in Woodstock. The introduction prints 2025. Do not cite 2018 as the year of the interviews, and do not cite the placeholder DOI. The identifier on the preprint is the one in the link. Four threat phases — transaction, dispute, logistics, and communication — are not four refund statuses, and they are not the five status names on the object.

Do the three proofs on one real refund, in the console that actually holds it. First, the binding. Copy the refund id, the status, the amount, the currency, and the charge id. If the status is requires_action, write that, and write the next_action type if the object has one. If the reason is null, write null. Do not infer duplicate because the customer sounded annoyed. Do not infer 1000 because a sample prints it. Second, the other refund. A different refund, with a different id, or a different charge, is not this one. A chart of appeals is not that second refund. If you cannot show a refund that is not this one, you have a counter, not a record. Third, the other account. A list that belongs to someone else does not contain this refund id. If the only list is a single shared table and you cannot say whose refund it is, write that. A tenant you cannot name is the finding. It is not a reason to tell the customer the status was succeeded.

Three moves feel like the proof and are a second problem. Canceling the PaymentIntent because the status was embarrassing, after the payment has already succeeded. The guide says that cancel is refused. Quoting 50% or 57% because one of them looks precise, while the refund you were asked about is one row, and the interviews that printed those shares had not opened your charge. Asking a model which status it was. The model will pick a plausible name from the five. It will not open the refund. A price you have not kept, while the customer is arguing about the amount, is show the price they accepted. Opening that screen does not name the refund id.

The path is ordinary when an operator can open one sale without opening the next sale's tender as the way to prove it. Orbix 365 is a point-of-sale system with sales, purchases, and returns, and a customer and supplier ledger that links payments, balances, and dues. The shape that matters here is one sale you can point at, in an account you administer, distinct from the next sale. That case is not a refund ledger. Nothing in the description is a headcount, a duration, or a result figure. If the only control on the screen changes every order's balance, you do not have this proof. You have a payment form.

There is a version of this afternoon where hiring the path is the wrong purchase. Nothing has been charged, 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 share from a paper. 50% is not your refund, and 1000 is not your refund. 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 network rule applies. Hire the lawyer.

When the charge is real and the console cannot name the refund, the missing object is specific. An admin action, in an account you administer, that shows one refund id, one status, one amount, and one charge, shows a different refund 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 refund. One that needs a call in order for you to see which refund is stored is telling you who holds the money. 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 refund, a two-week AI readiness assessment maps the systems. The findings are yours. They are not a promise that a paper's share applies, and they are not 1000.

The review that blocked a merge, the batch a request joined, and the dispute a charge opened, are different objects: which review blocked that merge?, which batch did that request join?, and which dispute did that charge open?. Do not record any of them on this page. A review state is not a refund status. A batch id is not a refund id. A dispute status is not a refund status.

Before you tell them the money came back, do the three proofs and write the status. Name the refund, the status, the amount, and the charge, or write that no refund was stored. Show a different refund that is not that one. Show another account's list that does not hold it. Do not cancel a succeeded payment to avoid the status, and do not ask a model which of the five it was. A paper can tell you what merchants said after someone faked a photograph. The binding is the refund you can defend.

Questions

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

No. A percentage is a share of someone else's disputes, and the interviews that print 50% and 57% did not open your charge. A refund you can defend is the id, the status, and the amount on this charge, or a written line that the console does not store one. 1000 on a sample object is not your customer's amount, and 17 merchants is not a status.

When nothing has been charged, when you have no product, when you are still choosing a firm, when the only fact in the room is a paper's percentage, 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→