Portreeve
explainer · 5 Sept 202613 min read

Stripe chargebacks: what happens after the dispute lands

How Stripe chargebacks run from early fraud warning to lost funds, what the $15 fee covers, when evidence is worth it, and how to keep the disputer out.

A charge.dispute.created webhook is the middle of a story, not the start of one. By the time it fires, the cardholder has already talked to their bank, the bank has already paid them, and the card network has already pulled the money out of your Stripe balance. Most of what Stripe chargebacks cost you was decided before you opened the evidence form, and the part you can still influence is smaller than the Dashboard makes it look.

This post walks the lifecycle end to end, then covers the part Stripe cannot help with: the person who just disputed your $29 plan will sign up again next month with a new email.

The lifecycle, with the clock

The cardholder calls their issuer and says they do not recognize the charge, or did not get the product, or cancelled and were billed anyway. The issuer credits them and files a chargeback through the network. Stripe's role from here is relay: it notifies you, debits the disputed amount plus a fee, and forwards whatever you submit, but the outcome is at the sole discretion of the cardholder's bank.

Three clocks run, and Stripe controls none of them.

The first is the filing window. Networks typically allow cardholders to dispute within 120 days of the payment, and for prepaid services the window starts on the service date rather than the charge date. A subscription renewal from four months ago is still in play.

The second is your response window. After the chargeback is created you usually have 7 to 21 days depending on the network, and if you miss it you lose automatically. The deadline is on the Dispute object as evidence_details.due_by. It is a network rule, so Stripe support cannot extend it.

The third is the issuer's decision window, usually 60 to 75 days after you submit. Stripe puts the whole lifecycle at two to three months and says you cannot accelerate it except by accepting the dispute. The funds are held throughout.

What you get from the issuer is a category (fraudulent, product_not_received, subscription_canceled, and so on), the network reason code, and sometimes a copy of the bank's claim document. What you do not get is a rationale. Stripe's responding guide says the bank explains its decision only "in some cases". Plan on never learning why you lost.

Visa and Mastercard no longer use the inquiry phase, so for most of your card volume the first thing you hear is the chargeback itself. Amex and Discover still send inquiries first, and an unanswered inquiry there escalates to a chargeback Stripe describes as likely unwinnable.

What a chargeback costs on Stripe

Since June 2025 Stripe splits the fee in two. In the US it is $15 for receiving a dispute and another $15 if you counter it; in the Eurozone and the UK both fees are €20 and £20 respectively. The received fee is never returned outside Mexico. The countered fee comes back only if you win outright. A partial win returns neither.

So the cheapest possible chargeback is the disputed amount plus $15, which is the bill for a dispute you accept on day one. Fighting and losing costs the amount plus $30. Fighting and winning costs $15 and the hours you spent assembling a PDF.

There is no fee waiver for being right. Stripe's best-practices page says accepting a dispute "doesn't affect your dispute fee" and that dispute activity is calculated on disputes received, not won or lost. The fee and the count are locked in the moment the issuer files.

One exception: if Stripe's Smart Disputes product counters the dispute for you, the countered fee is waived. That does not touch the received fee.

Early fraud warnings are the cheap exit

Before most fraud disputes there is an early fraud warning. Issuers on Visa, Mastercard, and JCB must report suspected fraud to the network (Visa's TC40 report, Mastercard's SAFE report), and Stripe surfaces those reports as a radar.early_fraud_warning object with a radar.early_fraud_warning.created event. The reporting requirement is separate from the decision to file a chargeback, which is why the warning arrives first.

Stripe's number for what happens next: 80 percent of EFWs turn into a fraud dispute if you do nothing, unless the payment carried 3DS liability shift. If you refund the charge while the warning is still actionable, there is nothing left to charge back. No dispute, no $15, no entry in your dispute count.

Be precise about what the refund does and does not undo. The fraud report stands. Stripe says a proactive refund does not affect the fraud warning, and Visa's VAMP program counts TC40 reports whether or not a dispute follows. Refunding on EFW removes the dispute, the fee, and the dispute count. It does not remove the fraud count.

Stripe's guidance is to refund EFWs on charges at or below your dispute fee, and that it is likely not worthwhile above about 35 percent more than the fee. That math is right for a retailer optimising expected value per transaction. It is wrong for a small SaaS, because what hurts you is the ratio, and Stripe says as much in the same section: refund more aggressively if the dispute itself threatens your account. With a few hundred charges a month, refund every actionable EFW at any amount you would not miss.

The webhook handler is short. Stripe SDK for Node, Express, raw body already verified:

app.post("/stripe/webhook", async (req, res) => {
  const event = stripe.webhooks.constructEvent(
    req.body, req.headers["stripe-signature"]!, process.env.STRIPE_WEBHOOK_SECRET!
  );

  if (event.type === "radar.early_fraud_warning.created") {
    const efw = event.data.object;
    if (efw.actionable && typeof efw.charge === "string") {
      await stripe.refunds.create({ charge: efw.charge, reason: "fraudulent" });
      await revokeAccessForCharge(efw.charge); // your side: kill the seat, the key, the trial
    }
  }
  res.sendStatus(200);
});

actionable is false once the charge has a dispute or a full refund, so the handler is idempotent by construction. The revoke call matters as much as the refund: an EFW means the cardholder says they did not make this purchase, so whoever is logged in on that account is not the cardholder.

When to submit evidence and when not to

The "fight every dispute" advice comes from retailers with tracking numbers and signatures. For a digital product it is mostly a way to spend the second $15 and an afternoon.

Look at what the issuer reads. Stripe's best-practices page says issuers manually review thousands of responses a day, will not comb through long files, and will not follow links or open videos. Your response is one PDF under 4.5 MB, submitted once, with no chance to amend. Stripe's own win-likelihood model tops out at 60 percent for the strongest possible case, and 5 percent for the weakest, with the note that "even in the most favorable cases, it's very difficult to overturn a disputed payment".

Stripe analysed which evidence shifts outcomes on product_not_received disputes, and the digital-goods result is thin: activity and usage logs added about 10 percentage points, provisioning records about 8. The strongest predictor of winning a digital-goods dispute in that dataset was having already issued a full refund through Stripe, at 63 points. The evidence that wins is evidence that the dispute should never have been filed, not evidence that the customer used the product.

A public example of the ceiling: gingerlime on Hacker News lost a dispute on a small physical product despite DHL delivery proof and Stripe support agreeing the case was clear. Their conclusion, in the thread: "Stripe support encouraged me to file a dispute and submit evidence but next time I prob won't bother." That is the easy case. Digital goods are harder.

So the rule for a software business:

  • Fight fraudulent disputes that Stripe flags as Visa CE 3.0 eligible. Stripe pre-fills the prior-transaction evidence and says eligibility "typically translates to a significantly higher likelihood" of winning. Do not edit the pre-filled fields.
  • Fight subscription_canceled and credit_not_processed when you have a cancellation log, the terms-acceptance timestamp, and login records after the alleged cancellation. These are the categories where your own data is the evidence.
  • Fight product_not_received only when you have the refund, or session logs tied to the cardholder's own IP and device. Usage from a different device than the one that paid proves nothing to the issuer.
  • Accept everything else the same day. The fee is gone either way, and accepting is not an admission of anything.

The time you save goes into the two things that change the number: the EFW handler above, and not letting the person back in.

The count matters more than the money

A chargeback on a $29 plan costs you $44. The network does not care about the $44. It cares about the ratio.

Visa folded its old dispute and fraud programs into one, VAMP, and Stripe's monitoring-programs page gives the merchant thresholds: a VAMP count of 5 and a ratio of 0.5 percent puts you in the non-compliant band, and 1,500 with 1.5 percent is excessive. The ratio is disputes plus TC40 fraud reports over all captured payments in the same month. A transaction that appears in both reports counts twice.

Run that against a small SaaS. A thousand card charges in a month and five events, disputes or EFWs, is 0.5 percent. Three hundred charges and five events is 1.7 percent. A single attacker running a few stolen cards through your checkout can put you over the line in a week, and refunds do not help because the TC40 has already been filed.

Mastercard's Excessive Chargeback Program needs both a count of at least 100 and a rate of 1.5 percent, calculated as this month's chargebacks over last month's transactions, so the count floor keeps most small merchants out. Watch Visa.

Stripe's own line for what the industry treats as excessive is 0.75 percent, with the warning that a sudden spike can trigger placement before you reach it. Once you are in a program, Stripe relays monthly to the network, may ask for a written remediation plan, and passes along whatever fines the network assesses. Mastercard lets you out after three consecutive months under threshold. Failure to remediate ends with the network refusing your payments at all.

Winning disputes does nothing for the ratio, because programs count disputes received. A withdrawn dispute still counts, so the "ask the customer to withdraw" advice helps your balance, not your standing.

The disputer comes back

Everything above is about the dispute you already have. The expensive version is the one you get again next month from the same person.

Nothing in a chargeback closes the account. The lost status lands on a Dispute object, the Customer object in Stripe is untouched, and your own users table still has an active row unless you wrote code to change that. Stripe Radar scores the payment, not the account. A subscriber who disputed in August and signs up in September with a fresh Gmail address and the same laptop looks like a new customer to every system you have.

The mechanism to catch it is identity linking, and the pieces are already in your data. Stripe gives you a stable fingerprint on every card PaymentMethod, so a new email paying with a disputed card is one join away. A browser fingerprint from your signup page ties the new account to the device that made the disputed purchase even when the card changes; we wrote up what device fingerprinting can and cannot see. Email normalisation catches dots and plus-aliases. The IP is the weakest of these and should never be the sole link, because one office or one carrier egress covers thousands of honest users.

The linking has to happen at signup and checkout, not at the bank. By the time a second dispute arrives you have paid another $15 and added one to the count.

This is the tool I built for that problem. Portreeve is an abuse firewall that returns allow, review, or block at signup, trial_start, trial_convert, checkout_attempt, and login, and links accounts across hashed email, device fingerprint, and card fingerprint so that a confirmed abuser's whole cluster is marked rather than the one email. Reporting chargeback through the feedback API on the original checkout event is what convicts the cluster. Card numbers never reach Portreeve, only the processor's card fingerprint and funding type. It is in open beta with a free tier of 1,000 screened events a month.

Whatever you use, the feedback loop is the point. A dispute that only updates a Stripe status is wasted. A dispute that marks the card fingerprint, the device, and every account they touched is the one thing that makes the next dispute less likely. More on the repeat-offender pattern in chargeback fraud in SaaS: three kinds, one repeat offender.

Turning on 3DS for everything is not the answer

The other reflex after a losing streak is to require 3D Secure on every payment. It does less than it sounds like.

Liability shift on an authenticated 3DS payment covers disputes filed as fraudulent. Product not received, subscription cancelled, and credit not processed all follow the standard dispute process regardless. For a SaaS those are the categories filling your Disputes tab.

It also does not travel. 3DS runs on the customer-present checkout. The renewal charge four months later is off-session, cannot be authenticated, and is exactly the charge a customer disputes as "I cancelled this". And the EFW still arrives on an authenticated payment, so the fraud count moves even when the dispute does not.

What it does cost is completion: every challenge is a redirect to the issuer's page, and some fraction of legitimate customers do not come back. Use Radar's dynamic 3DS rules to request it on risky payments and leave the rest alone.

What to do this week

In order.

  1. Wire radar.early_fraud_warning.created to an automatic refund and revoke, using the handler above. This is the only step that removes a dispute before it exists.
  2. Add a charge.dispute.created handler that revokes access and flags the user, the card fingerprint, and the device, before anyone looks at evidence.
  3. Triage the open dispute by category. CE 3.0 eligible or subscription with logs: counter. Digital product not received without matching logs: accept today.
  4. Report the outcome back into whatever links your identities, so the next signup from that device or card is scored against it.
  5. Pull your Visa dispute and EFW counts for the month and divide by charges. Near 0.5 percent, stop reading and refund the actionable EFWs now.

The dispute you are holding is mostly already lost or already won. The next one is the one you can still do something about. Start with the free tier, follow the quickstart, and report your first chargeback against the event that caused it.

← Back to all posts