The returnEasier audit log is an append-only record of everything that happens with your requests: every time one is created, approved, marked as received or refunded, a new row is added, and the app offers no way to edit or delete it. Each event is sealed with a SHA-256 hash chained to the previous one, which you can check against the hashes in your earlier exports; the confirmation PDF also carries the hash of its request. When you need to provide evidence —to an auditor, to the authorities or to your adviser— you go to Compliance → Export audit and download a ZIP with the entire history and an integrity file to verify it.
Why is the record append-only?
The events table is append-only: rows are only ever added. Through the app's normal path, a PostgreSQL trigger rejects UPDATE and DELETE on it, and the app offers no way to edit or delete an event.
On top of that foundation the hash chain is built:
- The content of each event (
payload) is converted to a canonical JSON (sorted keys, no ambiguity) and a SHA-256 is computed for it. - That hash is computed including the previous event's hash (
hash_anterior). The first event of each chain is the 'genesis'. - If someone changed a single value in the content (
payload) of a past event, its hash would change and would no longer match thehash_anteriorof the following event: an isolated modification of the content breaks the chain. Each event's date is stored separately and is not part of the hash. To check the history against a complete rewrite, keep your earlier exports.
The requests (return_requests) also carry their own hash and previous hash, which are included in the export so that they can be verified outside the app.
How do I export my auditable history?
The export lives in Compliance → Export audit (route /app/settings/compliance/export) inside the app, in the Shopify Admin.
- Open Compliance in the side menu; the export is the Export audit block.
- Set a date range: 'from' and 'to' (date format). You can leave both empty to export all your history. Dates are interpreted in your store's time zone (Europe/Madrid by default).
- Click Generate export. Depending on the number of requests in the range, returnEasier does one of two things (see below).
Instant download or by email, depending on volume
returnEasier generates the ZIP in both cases; what changes with the volume is whether it also emails it to you:
| Requests in the range | What happens |
|---|---|
| 1 – 100 | The ZIP is generated and you have the download link on screen. |
| 101 – 1200 | It is generated just the same: you have the download link on screen and we also email it to you (if your store has no email address in Shopify, on screen only). |
| More than 1200 | The export is rejected: narrow the date range. |
In both cases, the link expires after 7 days. If there are no requests in the range, the app tells you and generates nothing.
The hard limit is 1200 requests per export. If your history is larger, split it into several date ranges (for example, quarter by quarter) and export each one.
When it finishes, the screen shows you the count of requests, events and PDFs, whether the event chain is 'Verified' and how many PDFs were unavailable. On the same page you can generate the DPA.
What is inside the ZIP?
The file is named returneasier-auditoria-<your-store>-<date>.zip and contains:
README.txt— a plain-language guide: what each file is and how to verify integrity.solicitudes.csv— one row per request, with columns such aspublic_id,tipo,estado,creada_en_utc,resuelta_en_utc,pedido,cliente_email,cliente_nombre,importe,moneda,motivo,resolucion_preferida,notas_cliente,hash,hash_anteriorandrefund_id.eventos.csv— the complete append-only record:public_id,return_request_id,evento,actor,actor_id,fecha_utc,hash,hash_anteriorandpayload_json.pdfs/— the withdrawal confirmation PDFs of each withdrawal, one per request.INTEGRITY.json— the integrity file: algorithm (SHA-256), counts, the hash of each file in the ZIP and the verification of each event chain.
How do I verify the integrity of the export?
The INTEGRITY.json is the key piece for checking that the files in the ZIP have not changed since the export was generated —as long as you compare it against a copy of the manifest kept elsewhere, because it travels unsigned inside the same ZIP— and it carries the result of recalculating each request's event chain:
- It carries the SHA-256 hash of each file in the ZIP. Recompute the hash of, for example,
eventos.csvwith any standard tool and compare it with the one listed there. - It includes the verification of each event chain: for each request it indicates whether its chain is
okorbroken(on the app screen: 'Verified' or 'N chain(s) with issues') and, where applicable, the reason (forked chain, cycle, hash that does not recompute…). - If any PDF could not be retrieved (for example, because it was deleted by a GDPR request, or because the confirmation of a withdrawal was never generated), it is noted in the list of unavailable PDFs with its reason, instead of failing the entire export.
The INTEGRITY.json itself cannot contain its own hash, so it is the only file that does not self-check; everything else does.
Relationship with other features
The audit log is the foundation of the legal templates and of the withdrawal confirmation PDF (see 'What does the withdrawal confirmation PDF contain?'): every withdrawal confirmation sent to the customer is anchored to the hash chain. To understand which emails generate those events, see 'What emails does returnEasier send and to whom?'. And before uninstalling or cancelling, it is worth exporting your history: it is covered in 'What happens to my data if I uninstall or cancel returnEasier?'.