returnEasier
For your store
For your storeMerchant7 min read

How does returnEasier comply with the GDPR for your customers' data?

returnEasier stores all personal data on servers in the European Union and responds to Shopify's GDPR webhooks: the access request exports the customer's data, the customer redaction anonymises their personal information and the shop redaction deletes everything 48 hours after uninstalling. In addition, a weekly task automatically anonymises personal data older than 5 years. The audit log is kept as legal proof of compliance with Article 11 bis.

returnEasier is built for the GDPR from the ground up: all personal data lives on servers in the European Union and the app responds correctly to Shopify's three privacy webhooks (access request, customer erasure and shop erasure). The only data kept after an erasure is the event audit log, and it is kept precisely because it is the legal proof that you complied with Article 11 bis.


Where is the data? (EU residency)

All providers holding personal data are in the European Union:

Service Provider Region / note
Database Neon eu-west-2 (AWS, London)
Files (PDF, photos…) Cloudflare R2 EU jurisdiction (.eu)
Transactional email Brevo France (no Schrems II)
Rate limiting Upstash EU
Errors Sentry EU instance, with PII scrubbing
Product analytics PostHog EU instance

In addition, your store's access token and the Sendcloud keys are stored encrypted (AES-256-GCM), and all webhooks are validated with HMAC before being processed. Emails and personal data are never recorded in the logs: to correlate, a fingerprint is used (the first characters of a hash of the email).

The three GDPR webhooks

Shopify requires every app to respond to three privacy webhooks. returnEasier implements them like this:

1. Access request (customers/data_request)

When a customer exercises their right of access, returnEasier gathers all the personal data it holds for them —orders, requests, events, confirmations and portal verifications— and sends it to you, the data controller, in a JSON export by email. The app does not keep a copy of the export: it generates it and delivers it. If they ask for their data again, it is generated again.

2. Customer erasure (customers/redact)

When a customer requests the erasure of their data, returnEasier:

  • Anonymises the email (to a neutral value) and deletes the name in their orders.
  • Deletes the customer notes in the requests (the structural fields —quantities, reason— are kept).
  • Immediately invalidates their portal verification.
  • Removes the withdrawal confirmations and their R2 PDFs.
  • Keeps the event audit log: it is immutable and is maintained as proof of legal compliance.

3. Shop erasure (shop/redact)

Shopify triggers this webhook 48 hours after you uninstall the app. returnEasier does a deep cleanup: it anonymises the whole store's customer data, deletes the R2 files (PDF, photos, labels), clears the configuration (legal settings, branding, Sendcloud), redacts the token and leaves the plan on Free. The store row and the audit log are kept (the log references the store) as a tombstone so that the record remains attributable.

How is erasure reconciled with an immutable log?

This is the key question. The audit log is append-only: the database rejects any UPDATE or DELETE on the events. When an erasure arrives, the mutable tables are anonymised (orders, notes, verifications) and the files are deleted, but the events are kept under the legal basis of legal obligation (proving compliance with Article 11 bis).

Transparency note: the specific legal basis for keeping PII inside the immutable log is pending review by a lawyer. As a next step, a layered retention of the log itself is planned (keeping only the hashes past a longer deadline); in the meantime, the event rows are kept protected by the immutability trigger.

Automatic anonymisation after 5 years

In addition to the erasures triggered by Shopify, returnEasier runs a weekly task (every Monday in the early hours, in UTC) that applies the 5-year retention: each record runs its own clock from its creation and, once the deadline has passed, the task:

  • Anonymises the email (to a neutral value) and deletes the name in old orders.
  • Deletes the customer notes in the requests (including the per-item notes); the structural fields —quantities, reason— are kept.
  • Anonymises the expired portal verifications.
  • Removes from R2 the associated files: the confirmation PDF, the shipping label and the customer's photos.
  • Leaves a record in the audit log with an anonymisation event (containing no personal data), which also prevents repeating the work.

If deleting a file fails, the task does not consider the record anonymised: it retries the following week until it confirms the file is gone. You do not have to configure anything: retention works on its own on all plans.

What can you do?

  • Handle your customers' requests: Shopify's webhooks do the work automatically; you receive the access export by email.
  • Export your history before uninstalling (see 'What is the audit log and how do I export my auditable history?').
  • Understand what happens when you uninstall or cancel: it is detailed in 'What happens to my data if I uninstall or cancel returnEasier?'.
Was this article helpful?