---
title: "The chargeback evidence pack: the dispute is decided by what you kept, not by what you write"
subtitle: "Every sale quietly files its own proof - the address, the connection it was ordered from, the delivery, the terms that were live that day - so when a bank pulls the money back months later, the answer assembles itself into one dated PDF with the deadline on the front page"
url: "https://rxed.ai/blueprints/chargeback-evidence-pack.html"
id: "chargeback-evidence-pack"
version: "1.0"
published: "2026-08-26"
kind: "workflow"
setup_effort: "A weekend"
setup_hours: "6-14"
running_cost_usd_per_month: "0-12"
paid_software_usd_per_month: "0"
time_saved: "not a weekly time saving - it is the difference between answering a bank inside seven days and losing by silence"
time_saved_basis: "saves two to four hours per dispute answered, but at a handful of disputes a year that is not the case for building it; the case is that a missed deadline is an automatic loss with no appeal, and that Visa's Compelling Evidence 3.0 route needs an IP or device id recorded 120 to 365 days before the dispute existed"
runs_by: "unattended"
data_location: "your-server"
data_location_note: "The sale register, the documents and the assembled packs stay on your own server. Your payment provider already holds the transaction itself; nothing new is sent out, and the finished pack goes to the provider only when you submit it by hand."
first_to_break: "the capture at checkout stops recording the IP address or the device id - a plugin update, a new CDN or a proxy in front of the site, and every sale from then on logs your own server's address"
failure_signal: "silent"
problem: "A customer tells their bank they never bought it, and the money is taken straight back out of your account. You get a few days to prove otherwise, and the proof is spread across four different places, if you kept it at all."
fix: "Every sale quietly files what it would take to defend it: what was ordered, where it went, when it arrived and what the customer agreed to that day. When a claim lands, all of it comes back as one file with the deadline on the front page, and you send it yourself."
tools: ["n8n", "NocoDB", "Baserow", "Paperless-ngx", "Gotenberg", "Docker"]
tech: ["n8n", "NocoDB", "Paperless-ngx", "Gotenberg", "Docker"]
repos:
  - name: "n8n"
    url: "https://github.com/n8n-io/n8n"
  - name: "NocoDB"
    url: "https://github.com/nocodb/nocodb"
  - name: "Baserow"
    url: "https://github.com/baserow/baserow"
  - name: "Paperless-ngx"
    url: "https://github.com/paperless-ngx/paperless-ngx"
  - name: "Gotenberg"
    url: "https://github.com/gotenberg/gotenberg"
categories: ["Payments", "Documents & archive", "Reporting", "Self-hosted", "n8n"]
source: "RXed AI News — https://rxed.ai"
---
# The chargeback evidence pack: the dispute is decided by what you kept, not by what you write

> Every sale quietly files its own proof - the address, the connection it was ordered from, the delivery, the terms that were live that day - so when a bank pulls the money back months later, the answer assembles itself into one dated PDF with the deadline on the front page

## Before you start

- A payment provider that fires a webhook when a dispute is opened and exposes the evidence deadline - Stripe and Mollie both do
- Access to your checkout or booking code, or a plugin that can pass the customer's IP address and a device or session id through to the payment record
- One place where delivery or completion is already recorded - a carrier tracking number, a collection signature, or a job close-off
- Your terms and refund policy kept as dated versions, not as a page that gets edited in place
- A named person who reads the pack and presses submit, because nothing here submits by itself

## What breaks first

the capture at checkout stops recording the IP address or the device id - a plugin update, a new CDN or a proxy in front of the site, and every sale from then on logs your own server's address. Nothing complains, because the sale still completes and the register still fills with rows. You find out during a dispute, a year later. Add a weekly check that counts sales recorded with a missing or duplicate IP and alerts you when it is not zero.

A customer's bank takes the money back, and you get seven days to answer with one submission that cannot be edited. The pack that wins is not written in those seven days. It is assembled automatically at the moment of the sale, months earlier, out of records most small businesses never bother to keep.

 

### The problem

 The clock is the whole story. Stripe's own documentation puts it plainly: when a dispute lands you have "a limited window to respond (usually 7 to 21 days, depending on the card network)", and "if you don't respond before the deadline, you automatically lose the dispute and can't retrieve the disputed funds". Seven days is the common case, not the generous one. There is one submission. There is no edit, and there is no appeal.

 The money is already gone while you decide. The disputed amount is pulled from your balance the moment the claim is filed, and in the euro area Stripe charges €20 for receiving the dispute at all. Since 17 June 2025 it charges a second €20 if you counter and lose, refunded if you win. So a €60 dispute you fight and lose costs €100. The same dispute won costs €20. That arithmetic decides which ones are worth answering, and you cannot do the arithmetic if assembling the answer takes you half a day.

 Published win rates sit somewhere between 12% and 30% depending on who is counting and what they are selling. Treat the spread as the honest signal: most merchants lose most disputes, and a large share of those losses are silent — nobody replied. The response is not hard. It is scattered. The order sits in the shop system, the delivery proof sits on a courier's website behind a login, the conversation sits in a mailbox, and the terms the customer accepted sit on a web page that has been edited twice since.

 Then there is the rule that makes this a build-it-early problem rather than a write-it-fast problem. Visa's Compelling Evidence 3.0 lets you kill a fraud claim outright if you can produce two prior undisputed transactions from the same cardholder, processed between 120 and 365 days before the disputed one , with at least two matching data elements across all three — from customer account or login ID, delivery address, device ID or fingerprint, and IP address — where at least one of the matches is the IP address or the device ID . Qualify, and liability moves to the issuer. From 18 April 2026 the same route also covers fraud reports that never became chargebacks, and Visa now charges a fee per successful qualification, so on very small amounts it is a case-by-case call rather than a free win.

 Read that requirement again and notice what it is really asking for. It is asking whether, a year ago, you stored an IP address and a device fingerprint against a sale. Stripe's dispute evidence object has had a customer_purchase_ip field all along. Most small merchants find out it is empty at the exact moment it would have been worth money. That is the failure this blueprint fixes. The pack is not the product. The record is.

 

### The architecture

 
 AT THE SALE — runs every day, quietly 
 [ shop / booking / invoicing system ] → payment succeeded 
         ▼ 
 [ n8n — the recorder ] 
         ├─ one row per sale → NocoDB : charge id, customer, amount, IP, device id, terms version 
         └─ artefacts → Paperless-ngx : invoice, delivery or collection proof, signed docs, message thread 
 
     … four to twelve months pass. Nothing happens. This is the boring part that pays. … 
 
 AT THE DISPUTE — runs a handful of times a year 
 [ payment provider ] webhook: dispute created 
         ▼ 
 [ n8n — the assembler ] 
         ├─ find the sale row by charge id, read evidence_details.due_by 
         ├─ find two prior undisputed sales, same customer, 120–365 days back 
         ├─ cover sheet → Gotenberg → merge everything into ONE dated PDF 
         └─ open a dispute row with the deadline, alert you with the pack attached 
         ▼ 
 [ you ] read it, correct it, submit it yourself in the provider dashboard. 
 Nothing is ever submitted automatically. One attempt, no appeal. 
 

 Two workflows, one box. The recorder is the one that matters and the one nobody builds, because it does nothing visible for a year. The assembler is thirty minutes of work that only looks impressive. Keeping them separate is the design decision: change payment provider and you rewrite the assembler, while the record you have been building since last spring survives intact.

 

### Tool choices — and why

 n8n (Sustainable Use License, free for internal business use, 201.9k stars, pushed 23/08/2026) is both halves. It has the webhook trigger, the HTTP nodes for your provider's API, and the scheduling to retry a failed capture. If you already run it for invoice chasing or inbox triage from the other blueprints here, this is two more workflows on the same instance, not a new machine.

 NocoDB (Sustainable Use License since 29/01/2026, free for internal business use, 64.7k stars, release 2026.08.1) holds the sale register and the dispute register. A spreadsheet-shaped database is right here because you will look at these rows by hand, filter them by customer, and sort disputes by deadline. Baserow (5.7k stars, pushed 25/08/2026) does the same job if you prefer its licence; Grist is the third option and is already used elsewhere in this library.

 Paperless-ngx (GPL-3.0, 44.2k stars, active) stores the documents, with OCR so a scanned delivery note is searchable three years later. Its own README carries the warning worth repeating: it stores content unencrypted, so run it on a box you control, with backups.

 Gotenberg (MIT, 12.4k stars, pushed 19/06/2026) turns the cover sheet into a PDF and merges the artefacts behind it. One file, in the order a bank reviewer reads, is the entire deliverable. Card issuers are not going to click a link into your systems.

 Monthly cost. Software: €0, all four. Hosting: nothing new if you already run an automation box; otherwise a small VPS at roughly €5–12/month carries the whole stack, and this is not a workload that needs a big one. There is no model in the loop and no per-dispute service fee. Compare that against what a managed chargeback service charges: typically a share of every dispute recovered, which is fine at volume and absurd at four disputes a year.

 

### Setup outline

 1. Build the sale register first and leave the dispute half for later. It is worthless the day you build it and valuable in month five, which is exactly why it gets skipped. 
 2. Capture at checkout what the rules ask for: customer IP, device fingerprint or session id, account or login id, delivery address, the amount, the charge id, and which version of your terms was shown. Your provider may already collect the IP — check whether it is actually stored against the charge, do not assume. 
 3. Pass the IP through if you sit behind a proxy or CDN, or you will log your own server's address on every sale and discover it a year later. 
 4. Wire delivery proof in at the moment of delivery: carrier tracking number, carrier name, delivery date, and for collected or in-person work, who signed and when. File it into Paperless-ngx against the same charge id. 
 5. Version your terms and refund policy. Store the text that was live on the day of the sale, not a link to today's page. A screenshot of the current page proves nothing about last March. 
 6. Now build the assembler. Subscribe to the dispute-created webhook, read evidence_details.due_by , and open a register row with the deadline, the reason code and the amount. 
 7. Build the cover sheet to map each artefact onto the provider's own evidence fields — shipping_documentation , shipping_tracking_number , service_documentation , customer_communication , customer_purchase_ip , refund_policy_disclosure , receipt . Field-by-field beats a narrative essay, because a reviewer is checking boxes under time pressure. 
 8. Add the prior-transaction lookup: same customer, two undisputed sales, 120 to 365 days before this one, with the matching identifiers listed side by side in a small table on page one. 
 9. Alert yourself the way you will actually see it, with the deadline in the first line and the pack attached. Then add a second alert at half the remaining time if the row is still open. 
 10. Test it on a real dispute before you trust it. Both Stripe and Mollie let you trigger dispute events in test mode; run one end to end and read the PDF as if you were the bank.

 

### Pitfalls — the real ones

 Never let it submit. One attempt, no appeal, and a machine cannot tell that the delivery photo shows the wrong address. The automation's job ends at "here is the pack and here is the deadline". Same rule as the inbox-triage blueprint, for the same reason. 
 Fighting is not always right. With a €20 counter fee at stake, a €25 dispute is close to break-even before you have spent a minute on it, and a weak case is worse than break-even. Put the amount and the fee on the cover sheet so the decision is made on the number, not on annoyance. 
 SEPA Direct Debit is a different animal, and the honest answer is that you cannot win. Mollie's own documentation is blunt: the customer has up to 8 weeks from the purchase date to reverse a direct debit, no reason required, and "once a customer requests a chargeback, you cannot dispute it". There is a €10 chargeback fee, and some banks add around €4.50 on top. Between 8 weeks and 13 months it can still be reversed if the mandate was never valid. So for direct debit the whole game is prevention, and Mollie names the prevention itself: keep the customer informed of when they will be charged and for what. A pre-notification a few days before every collection, with your name as it appears on their statement, costs one n8n workflow and removes the most common cause — the customer genuinely not recognising the line. 
 You are now storing personal data on purpose. IP addresses and device fingerprints are personal data. Write down the purpose (defending payment disputes), set a retention period long enough to cover the dispute window and no longer, keep it in the record you would show a regulator, and resist the temptation to reuse the same table for marketing. The lawful basis you are relying on evaporates the moment you repurpose it. 
 The dispute rate matters more than any single case. Stripe treats dispute activity above 0.75% as excessive, and a rate that stays high costs reserves and eventually the account, which dwarfs anything you recover. The cheapest dispute is the one that became a refund after a reply on the same day. Build the pack, and also answer your messages. 
 Do not confuse this with the job evidence pack. That one answers a customer complaint about work done. This one answers a bank, to a deadline, in the bank's own field names. Different reader, different clock.

 

### Verified repos

 
 [n8n](https://github.com/n8n-io/n8n) — Sustainable Use License (free self-hosted internal use), 201.9k stars, pushed 23/08/2026 
 [NocoDB](https://github.com/nocodb/nocodb) — Sustainable Use License since 29/01/2026 (free for internal business use), 64.7k stars, release 2026.08.1 
 [Baserow](https://github.com/baserow/baserow) — open-source core with a paid edition, 5.7k stars, pushed 25/08/2026 — alternative to NocoDB 
 [Paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) — GPL-3.0, 44.2k stars, active (August 2026) 
 [Gotenberg](https://github.com/gotenberg/gotenberg) — MIT, 12.4k stars, pushed 19/06/2026
 

 
 Get the next blueprint as it publishes — free, practical, verified tooling only.

 [Subscribe](https://subscribe.rxed.ai) · Want this audited or extended for your business? DM [@RXed_EU](https://x.com/RXed_EU)
