This policy covers the customer personal data the Shopify app stores in the abandoned_checkouts
table (packages/db/src/schema.ts:575-617):
customer_name, customer_phone (the personal data)recovery_url (a deep link back to the customer's cart; can be considered personal in context)Abandoned-checkout records are retained for a maximum of 90 days from the time the checkout was
abandoned (abandoned_at), after which the entire row is deleted.
Records are deleted before 90 days in these cases, which already work today:
shop/redact deletes all of a store's rows
(recovery.ts:729-741).customers/redact deletes a specific customer's rows by phone
(recovery.ts:744-759).The 90-day purge is the backstop for records that reach neither of those events (the common case: a customer who abandons a cart, is or is not recovered, and never triggers a deletion webhook).
There is currently no automatic purge for abandoned_checkouts. The worker's scheduled cron
(workers/webhooks/src/index.ts:2096-2107) runs
only: CRM conversion retries, ad-connection token refresh, web-form rate-row purge, and expired
session cleanup. None of these touch abandoned_checkouts.
A purge job must be added for this policy to be real. Do not treat the 90-day statement as enforced until it ships.
The scheduled handler already exists; this is a few lines inside it. In the daily branch (the
else branch that already runs DELETE FROM sessions):
DELETE FROM abandoned_checkouts WHERE abandoned_at <= ?1
-- bind ?1 = Date.now() - 90 * 24 * 60 * 60 * 1000
Notes for whoever builds it:
abandoned_at is stored as epoch milliseconds (timestamp_ms mode), so compare against
Date.now() - 90d in milliseconds.recovery_message_id link points forward to messages,
which is unaffected.)abandoned_at older than the
threshold and asserts the purge removes it, and one within the window and asserts it survives.If you later want to keep anonymised recovery statistics beyond 90 days, null out
customer_name, customer_phone, and recovery_url at (say) 30 days after a row reaches a
terminal status, while retaining the non-personal amounts and timestamps for reporting. This is a
larger change and is not needed to satisfy the retention commitment; the whole-row purge above is
the baseline.
This policy is reviewed whenever the recovery data model changes, and at least annually.
Update (16 July 2026): the automatic 90-day purge described in section 3 has since shipped. Abandoned-checkout records older than 90 days are now deleted by a scheduled job in the platform, so the retention period above is enforced, not only stated.