How fraudsters reuse addresses after a chargeback (and what your store can do about it)
Three weeks after a customer files a chargeback on a $340 order, a brand-new account places an order shipping to the exact same apartment number. Same building, same zip, same provincial code. The new account has zero return history. Every customer-keyed risk signal returns clean.
This is the canonical identity-pivot attack. It works because customer history is keyed on the customer ID, and a new customer ID resets every counter your store keeps.
Real addresses are scarce. Most fraudsters can name two or three usable ones. Customer accounts are free. Banks and email providers throw them around. So the rational play is to recycle the address and burn the account.
The pattern in the wild
A merchant we work with pulled six months of chargebacks alongside their AddressFingerprint table. The data was clear. About 12% of addresses that had received a chargeback also received an order from a different customer account within the next 90 days. Of those, just over a third produced a second chargeback or a confirmed-fraud return label within the following 60 days.
That is not a coincidence. The base rate of repeat-fraud-at-address across all addresses on the platform is below 1%. A prior chargeback at an address is one of the strongest precursors of a future fraud event we have ever measured, stronger than any customer-side signal except a direct merchant fraud confirmation.
Why customer-history signals miss this
The standard return-fraud playbook scores the customer. Look at their return rate, their order frequency, their average value, how long they have been with you. These signals are durable and well-tuned, and they catch the lone serial returner cleanly.
Identity-pivot fraud breaks the assumption that the customer is the unit of analysis. The customer is the disposable wrapper. The address is the thing that persists.
When a fraudster spins up a new Shopify customer account, they are deliberately discarding all customer-side history. Account age resets. Return rate resets. Order count resets. From a customer-history perspective, the new account is indistinguishable from a real first-time shopper having a great day.
The signal that does not reset is the shipping address. Hash it, store the hash, count the chargebacks at that hash, and you have a signal that survives the customer ID rotation.
What the signal actually looks at
RefundSentry's priorChargebackAtAddress signal evaluates three things on every return:
- The shipping address fingerprint of the return being scored
- The lifetime count of
CHARGEBACK-type dispute events that landed at that fingerprint, scoped to your shop - A graduated tier mapping: 1 prior chargeback contributes about 18 base points, 2 contributes about 27, and 3 or more contributes about 36
The points before clamping interact with the rest of the engine, so a return at a triple-chargeback address combined with even mild customer-history signals will reliably resolve into the high-risk zone. A single-chargeback address typically lands the score in medium-risk territory unless the rest of the return looks normal, in which case it stays at the elevation but does not falsely max the score.
The address fingerprint is a SHA-256 of the normalized address line, city, province code, postal code, and country. Same hashing logic the rest of the risk engine uses for shared-address clustering. There is no plaintext address stored in any general-purpose table.
How the data gets there
For the signal to work, two things have to be in place.
The first is the AddressFingerprint table itself, which gets populated as orders and returns flow through the pipeline. Every return upserts an AddressFingerprint row keyed on (shopId, fingerprint) and pushes the customer GID into the row's customerIds array. The customer count at an address is therefore a count of distinct accounts that have shipped there.
The second is the chargeback denormalization. RefundSentry stores ChargebackEvent rows for every dispute Shopify raises, but the FK to AddressFingerprint did not exist until recently. We added it as a nullable column and ran a per-shop backfill job that walks every existing chargeback, resolves the originating order's shipping address, and writes the fingerprint id back to the chargeback row. The backfill runs once on install and once on deploy of the new code, and the signal stays NOT_AVAILABLE for a shop until that backfill completes. We would rather miss a few weeks of detection than emit a wrong score from a partially populated dataset.
The two related signals that ship alongside
Address-reuse rarely shows up alone. Two companion signals pick up the variants we kept seeing:
recentChargebackVelocityAtAddressflags an in-flight cluster: 2 or more chargebacks at the same address within a rolling 90-day window. The lifetime signal would also fire here, but the velocity signal catches the early-cluster case where the chargebacks are recent enough that the cumulative count has not yet crossed the strong-tier threshold. For more on velocity-based detection, see the role of fraud-ring detection beyond the obvious signals.priorFraudAtAddresspropagates merchant-confirmed fraud across customer accounts at the same address. When a merchant labels a return as fraudulent, that label was previously trapped on the customer record. Now it propagates through the address pivot to any new customer shipping to the same fingerprint. This is the highest-precision signal we have, because merchant-confirmed fraud has a much lower false positive rate than any algorithmic detection.
What this changes for your store
If you have ever investigated a chargeback and felt the suspicion that the same warehouse was burning your store under multiple customer names, this signal is what closes that loop.
Concretely, three things shift when this signal is live:
- New customer accounts shipping to addresses with prior chargeback events get flagged the moment they request a return, before any customer history accumulates. The score elevation gives you the option to hold the refund, request additional verification, or block the return entirely depending on your policy.
- Velocity at an address is detected weeks earlier than it would be by lifetime count alone. A small cluster forming at one address now reads as a cluster on the second chargeback rather than the third or fourth.
- Merchant fraud confirmations on one customer become useful for every other customer at the same address. The signal uses your existing fraud labels, no extra labeling work is required.
For a dive into how the email and phone pivots work in parallel to the address pivot, see email and phone recycling in return fraud. The full picture of why Shopify's chargeback data alone is not enough to surface this is in why your Shopify chargeback data is not enough.
Common questions
Does this signal flag legitimate household members who happen to live at an address that previously had a chargeback?
In theory, yes. In practice, the base rate of legitimate repeat shopping at a fraud-flagged address is low enough that the signal is well above the noise floor. The signal is also additive rather than absolute. A clean customer history at a previously chargeback-flagged address gets a score elevation but rarely a max-zone score. Merchants retain the ability to confirm-not-fraud on a return, which records a positive label that the engine learns from.
Why is the signal scoped per shop instead of cross-shop?
Privacy. Cross-shop chargeback data could leak PII or business intelligence between merchants. The address fingerprint is a hash, but a hash is still a stable identifier. Per-shop scoping ensures the signal only ever uses your store's own dispute history.
What happens if Shopify stops surfacing the order on a chargeback (purged orders)?
The chargeback row stays, the address fingerprint comes through null, the signal returns NOT_AVAILABLE for that specific dispute's contribution, and the engine continues. The backfill logs the gap so it is auditable rather than silent.
Can I tune the weight on this signal?
Yes. The default weight is 18 base points multiplied by the tier scale (1.0x, 1.5x, or 2.0x). You can zero the weight in Risk Settings to disable the signal entirely, or scale it up if your store has a particularly fraud-prone profile. Tuning happens through the standard Risk Settings page, same as every other signal in the engine.
Does the signal ever produce a false positive on shared warehouse addresses (3PLs, package consolidators)?
If a 3PL or consolidator address has received a chargeback through your store, the signal will fire on subsequent returns at that address. We treat that as a feature: a 3PL address with a chargeback history is genuinely riskier than a residential address with no history. Merchants who use a known 3PL legitimately can confirm-not-fraud on the first return at that address, which records a positive label and reduces the signal's contribution on future returns to that same fingerprint.
Closing thought
We built this signal because the merchants we talk to kept describing the same scenario in different words: the chargeback was followed by a clean-looking order to the same address, and the existing tools had no way to connect the dots. Shopify gives you the chargeback. RefundSentry adds the connective tissue.
If you want to see this signal flag something on your own store, RefundSentry is free during the private beta. The address pivot signals are live for every shop on the platform from day one, and you can audit which returns trigger them via the Risk Settings page. See pricing for plan details and docs for setup.
For deeper reading on related identity-pivot patterns, the anatomy of a repeat return fraudster walks through a real merchant case study.