Portreeve
explainer · 3 Sept 202612 min read

Chargeback fraud in SaaS: three kinds, one repeat offender

Chargeback fraud in SaaS: true fraud vs friendly fraud vs first-party abuse, Stripe fees, network thresholds, evidence that wins, and stopping repeats.

A $29 subscription gets disputed. Stripe debits $29 and a $15 fee, and then offers you a form. Whether you should fill in that form, and what you should do about the person on the other end, depends on which of three things just happened. All three get called chargeback fraud, and most advice treats them as one problem.

One is a stolen card. One is your real customer lying to their bank. One is a person who was never going to pay and will do it again next month under a different email.

Three things called chargeback fraud

The card networks only care about reason codes. Visa files card-not-present fraud as 10.4 and a cancelled recurring charge as 13.2; Mastercard uses 4837 and 4841 for roughly the same claims, per Stripe's reason code mapping. The reason code describes what the cardholder told their bank, though, and from your side there are three distinct situations.

True fraud. Someone bought your product with a card that was not theirs. The real cardholder saw the charge and disputed it. They are telling the truth, you will lose the dispute, and you should. The interesting question is why a stolen card was used on your product at all. For a SaaS it is usually card testing that happened to succeed, or someone buying compute, API credits, or email sends they intend to resell.

Friendly fraud. Your actual customer, paying with their own card, disputed a charge they authorized. Stripe's definition covers both halves: it "can either be accidental, because they didn't recognize the transaction on their statement, or deliberate (for example, due to buyer's remorse)," per Stripe's fraud types guide. The accidental version is a statement descriptor problem. The deliberate version is a person using the dispute button as a cancel button because it is faster than finding yours.

First-party abuse. A person who never intended to pay. They start a trial, extract the value, and either dispute the conversion charge or refund-and-rejoin under a new identity. Stripe's March 2026 first-party fraud analysis describes it as legitimate users who "abuse policies by setting up multiple accounts, cycling through free trials, or exploiting refunds," and reports that 62% of merchants saw disputes from it rise over the prior year.

Your response is different for each. True fraud is a front-door problem: stop the stolen card at checkout. Friendly fraud is an evidence problem: you had a real relationship with this person and can prove it. First-party abuse is a memory problem: this person will be back, and nothing about your dispute response affects that.

The fees and thresholds that hurt

Stripe's US dispute schedule since June 2025 is two fees, both $15: one when the dispute arrives, one more if you counter it, per Stripe's dispute pricing page. The received fee is never returned outside Mexico. The countered fee comes back only if you win outright; a partial win returns neither. In the UK it is £20 and £20, in the EU €20 and €20, in Australia A$25 and A$25.

So a lost $10 dispute costs you $40 if you fought it and $25 if you did not. One commenter in a Hacker News thread on SaaS chargebacks, joshstrange, put it flatly: "when someone charges back on a $10 you immediately lose $15." Another in the same thread, skwee357: "If the cost of the transaction is less than the two fees, it's better to let chargeback settle in customers favor."

That is the per-dispute cost. The cost that can end your business is the rate.

Visa's Acquirer Monitoring Program counts disputes plus fraud reports against your monthly transaction count. Under the thresholds Stripe documents, an account with 5 or more disputes-plus-fraud-reports and a ratio of 0.5% is non-compliant; 1,500 and 1.5% is "excessive" and draws fees, per Stripe's monitoring programs page. Mastercard's Excessive Chargeback Merchant tier starts at 100 chargebacks in a month at a 1.5% rate, with fines of $1,000 a month from the second month and $5,000 from the fourth.

Two things about those programs catch small merchants off guard. They count disputes received, not disputes lost, so winning changes nothing. And the ratio uses your transaction count, so a business with 1,000 charges a month is at Visa's non-compliant line at five disputes.

Refunds do not reduce the count either. A full refund issued before the dispute keeps the dispute from happening. A refund issued after does not remove it from the ratio.

Evidence that wins for subscription merchants

Stripe says outright that "even in the most favorable cases, it's very difficult to overturn a disputed payment," and publishes its own win-likelihood scale where the top rank wins 60% of the time and the bottom wins 5%, per Stripe's evidence best practices. Plan for that. Evidence moves you up the scale. It does not make disputes a good business.

For a subscription product, the evidence that moves you up is usage. Stripe's dispute evidence object has an access_activity_log field for exactly this: server or activity logs showing the customer accessed the product, with IP addresses and timestamps. A user who logged in fourteen times during the billing period they now say they didn't authorize is your whole case.

For the fraud reason code specifically, Visa's Compelling Evidence 3.0 rule turns history into a defense. If you can show two prior undisputed transactions with the same cardholder, each 120 to 365 days before the disputed one, and matching on at least one of email, delivery address, device fingerprint, or IP, the dispute qualifies for CE 3.0, per Stripe's CE 3.0 FAQ. Stripe searches your history and pre-populates the form when a dispute qualifies. Visa also excludes fraud reports that qualify for CE 3.0 from its monitoring count, which makes this the one defense that changes your standing with the network.

Record device identifiers and IP at signup, at login, and at each payment, and store them next to the user record rather than only in a log file that rotates. The device fingerprint is the strongest matching element. A person's IP changes and their address might be missing on a SaaS invoice, but their laptop is their laptop.

For the cancelled-subscription reason code, the fields are cancellation_policy, cancellation_policy_disclosure, and cancellation_rebuttal. What wins here is a screenshot of the checkout page with the recurring terms visible above the pay button, plus the timestamp of the customer's terms acceptance, plus the renewal reminder email you sent. If you did not send a renewal reminder, you are mostly going to lose these. The founder who opened the Hacker News thread on Stripe chargebacks, gtech1, submitted activity logs showing the service was still in use and lost anyway; the bank's reply was that "THE CARDHOLDER IS NOT REQUIRED TO PROVIDE PROOF OF CANCELLATION."

Keep the response short. Stripe's guidance is one file per evidence type, relevant sections only, no full terms of service. A reviewer at an issuing bank is going to read your submission for a minute or two.

Refund or fight

Stripe's docs give the arithmetic for one case, the early fraud warning. An EFW is an issuer telling you a card was reported stolen before a dispute arrives. Stripe reports that 80% of them become fraud disputes if you do nothing, and recommends refunding when the charge is at or below your dispute fee, and not bothering when it is more than 35% above it, per Stripe's dispute lifecycle page. On a $15 fee that puts the crossover near $20.

That is the rule for true fraud, where the refund is a certainty against a probable loss. For friendly fraud and first-party abuse there is no EFW, and the question is different: fight the dispute, or refund the moment the customer complains so the dispute never files.

Refund the first complaint on any charge under about twice your dispute fee. You save the $15 received fee, the dispute never enters your ratio, and you keep the option of not serving this person again. Above that, fight if and only if you have usage logs and a terms-acceptance record for that user, because without those the expected value is negative once you add the countered fee.

Fight anyway when the dispute qualifies for CE 3.0. The evidence is pre-populated and the fraud report drops out of your Visa count.

Never fight to make a point. A commenter in the SaaS chargebacks thread, tortilla, reported "We've won about 50% of the chargebacks disputes" after building an admin tool that packages evidence. Half is a good outcome. It still means half your countered fees are gone, and none of it stops the next dispute.

Chargeback fraud prevention for the repeat offender

Every piece of advice above is about a single dispute. The person who costs you money disputes, comes back under a new email with a new card, trials again, and disputes again.

The standard fix is a stricter policy: require a card for trials, shorten the trial, no refunds after day seven. This is wrong for most SaaS, and wrong in a specific way. A stricter refund policy cannot stop a dispute, because the dispute goes to the bank. Requiring a card at trial start increases your dispute count, because now there is a charge to dispute. And none of it touches the person's ability to sign up again, which is the actual problem.

The Stripe analysis linked above found that 7.4% of signups at AI companies were "implicated in suspected multi-account abuse." Those are not 7.4% distinct people. They are a smaller number of people, each present many times.

So prevention is identity linking with memory. When a dispute lands, the chargeback should be recorded against every identity key on the account: the email, the device fingerprint, the card fingerprint from the processor, the phone number if you collected one. The next signup that shares any hard key with a charged-back account is the same person, and it should be blocked at signup or held for review before a trial starts. Use hard keys rather than IP. Shared office and mobile carrier egress makes per-IP matching unreliable enough that a block on IP alone will hit real customers.

This is what I built Portreeve to do. When a dispute arrives, you report chargeback on the original verdict through the feedback API, and the whole linked cluster is marked, so the next signup or trial_start verdict from the same device, card, email, or phone comes back block or review with the history in its reason codes. The device link needs the browser snippet installed, which is covered in the device fingerprinting guide.

The wiring is one call in your Stripe webhook handler, if you stored the verdict id next to the payment:

// Stripe webhook: charge.dispute.created
const dispute = event.data.object;
const payment = await db.payments.findByStripeCharge(dispute.charge);
await portreeve.feedback(payment.portreeve_verdict_id, "chargeback");

Feedback is idempotent per event and outcome, so retried webhooks are safe.

You should also mark the account in your own system and revoke access, whatever tool you use. A commenter in the Stripe chargebacks thread, theamk, made the case: "If this was an honest mistake - then unlock is one email away. If it's not, you are not messing up your chargeback rate." Lock first, restore on request.

Then the part that separates memory from a blocklist: the same cluster marking should run for false_positive too. If you lock someone and they email you and turn out to be a real customer with a forgotten renewal, report it. A system that only learns from abuse drifts toward blocking too much.

A dispute playbook for a small team

Most of this can be done in a week by one engineer, and most of it does not involve the dispute form.

  • Fix the statement descriptor so it reads as your product name, not your legal entity. This kills the accidental half of friendly fraud outright.
  • Send a renewal reminder before every annual charge and a receipt after every charge. Stripe's prevention advice is seven days before annual renewals and two to three days before monthly ones.
  • Put the cancel button one click from the billing page. Every person who cannot find it disputes instead.
  • Store terms acceptance with a timestamp, the IP, and the device identifier at signup and at every plan change. Store it in the user table, not the request log.
  • Log usage per user per billing period in a shape you can export as a single PDF. If you can generate the file in one click, you will fight the disputes worth fighting.
  • Respond to every early fraud warning within a day. Refund at or below your dispute fee. Otherwise let it ride.
  • On every dispute, before anything else, report it against the identity cluster and lock the account. Fighting is optional. Remembering is required.
  • Watch your monthly dispute count against your transaction count, and treat four disputes in a month as a fire drill if you process under a thousand charges.

The dispute you are handling this week is a sunk cost of somewhere between $15 and $40. Whether the same person costs you that again next month is the decision you still get to make.

Portreeve's free tier screens 1,000 events a month with no card required. Start with signup and trial_start, then add the feedback call on your dispute webhook.

← Back to all posts