Cart Shield — Privacy Policy
Last updated: 18 October 2026 · Effective: 18 October 2026
This policy covers Cart Shield, the Shopify app built and operated by Edwin Guo (ABN 20 938 499 163), a sole trader in New South Wales, Australia, trading as Sushinet ("we", "us").
Published at https://sushinet.fyi/cart-shield/privacy. It is hosted separately from Cart Shield itself, deliberately: you should be able to read what we do with your data even at a moment when the app is down.
Summary — the short version
- We do not sell anyone's data, and we do not use it for advertising, marketing or profiling for anyone else. Cart Shield contains no ad pixel, no data broker and no third-party analytics SDK, and no error-reporting service.
- For your shoppers' data, you are in charge and we act on your instructions. You are the controller and we are your processor. For your own account, settings and support messages, we are the controller.
- Cart Shield scores storefront visits and orders for fraud signals. The score comes from fixed rules — lists, ranges, counts and fixed weights. It uses no machine-learning model. It mostly keeps counts, true/false findings and codes. Its database holds no shopper's street address, time zone or IP address in readable form; it does keep an order's id, name and total, and two unkeyed hashes of the buyer's email. §1 lists every item, including the one place a shopper's readable IP address can be kept: our web server's access log, in the headers of the checkout check's requests (§1.10). The web pixel's requests are logged without it.
- What leaves our server. We write results back into your Shopify store (§5). Beyond that, one piece of shopper data leaves: an order's IP address, sent to IP lookup services (§5) after Shopify has already been told the order arrived. A storefront visit's IP address is never sent to an outside service.
- Some windows are short and some are not. IP codes are kept 72 hours (30 days on a Strong order); address codes 30 days. Order records have no time limit while the app is installed. §7 has every window, and the honest limits on how two of them are enforced.
- Cart Shield can act on an order or a checkout, but only if you turn that on. Every action is off when you install. §8 explains each one, and how a person can review it.
- Where it lives: Sydney, Australia, with the providers named in §5.
- Any question or request about data: support@sushinet.fyi. A real person reads it.
Which app this policy covers, and where the others are
One app per policy, so nothing here describes a product you did not install:
- Cart Shield's own processor terms — DPA. This policy is the notice; the DPA is the contract.
- Ruleproof (checkout rules) — privacy policy.
- Rules2Tag (auto-tagging) — privacy policy.
- Undo History (product change history) — privacy policy. It holds no customer data at all.
- This website, and our dealings as a studio (analytics, email, LinkedIn) — website privacy policy. Separate because the roles differ: there we are the controller in our own right; here you are the controller and we are your processor.
The apps share a server but hold separate databases and separate data. Each app's DPA is linked from its own policy.
1. What data we collect, and why
1.1 Storefront visits (the web pixel)
In short: five fields per event, plus three on particular events. Nothing from the page, the cart or the buyer.
Cart Shield connects a Shopify web pixel to your storefront when you open the app. It is declared to Shopify as analytics, so
where your store asks visitors for consent, Shopify runs it only for visitors who allow analytics. It listens to these Shopify
standard events: page_viewed, collection_viewed, product_viewed, search_submitted, product_added_to_cart,
product_removed_from_cart, cart_viewed, checkout_started, checkout_completed, alert_displayed and payment_info_submitted.
For each event the pixel sends exactly these fields:
- your shop's domain;
- Shopify's
clientIdfor the browser; - the event's name;
- the event's timestamp;
- the order id, on
checkout_completedonly (otherwise empty).
Three fields are added only on particular events:
alert_displayed: the kind of alert only, eitherpaymentorform. Never its message, the field it was about, or what was typed. Other alert types are not sent.product_added_to_cart: the quantity added, as one whole number. Never which product, its title or its price.page_viewed: the browser's time-zone name, for exampleEurope/London, when the browser reports one.
The pixel sends nothing else — not the page URL, referrer, screen size, product data, prices, the cart, or the buyer's email or address.
What our server does with it:
- Visit key. The
clientIdbecomes a visit key: a SHA-256 hash of your shop domain together with theclientId. The hash is not keyed, so anyone who already knew aclientIdcould compute the same value. Because the shop domain is part of it, one browser shopping at two of our merchants cannot be linked in our database. - Counters. Each event updates counters on that visit and is then discarded:
- page, product and collection views, searches, and the total number of events;
- cart adds, and cart adds made before any product was viewed;
- how fast events follow each other (a running average and spread);
- first and last seen times;
- checkout starts, and when checkout started;
- Pay presses, form-error counts and payment-error counts;
- the largest quantity added to the cart, capped at 1,000,000;
- the number of unfinished checkouts from the same connection.
- Device class. A label —
pointer,touchorunknown. Today every visit is recorded asunknown. - Order id. The order id from
checkout_completedis stored as it is, with the time the visit was linked to its order. - Time zone. The server looks up the country of the request's IP address in an IP-to-country table held on our own server. Nothing is sent out for this. It compares that country with the time zone and stores one true/false value: whether they disagree. The time zone itself is not stored.
- The request's IP address. We use the last address in the
X-Forwarded-Forheader, which our own web server sets.- Our database does not store the readable address. It stores a keyed code (an HMAC) of the "connection": the whole address
for IPv4, the
/64network prefix for IPv6. The key is the app's Shopify client secret (§9). - The code is used to count unfinished checkouts from one connection, and is kept for 72 hours from the visit's most recent event (§7).
- Inside our server the address is also compared, in memory, with the IP lists we download (§5), to check for crawler and assistant addresses.
- The visit's IP address is never sent to an outside service, and our web server logs the pixel's requests without it (§1.10).
- Our database does not store the readable address. It stores a keyed code (an HMAC) of the "connection": the whole address
for IPv4, the
- The request's User-Agent (the name the browser gives itself) is checked and then discarded. We keep three true/false answers: whether it names automation software, whether it says it is a bot, and whether it claims to be a search-engine crawler that it is not.
The visit also holds the score, band and signals Cart Shield worked out from the above, including each signal's value.
Cart Shield does not record mouse movement or keystrokes, and stores no device fingerprint.
1.2 Orders (the orders/create webhook)
In short: we read the order, score it, and keep the result together with references and codes. Order records have no time limit.
When an order is created, Shopify sends it to Cart Shield. For each order we store:
- The order id and order name, as they are.
- The order total, as it is.
- The buyer's email, as two codes. One is a SHA-256 hash of the email. The other is a SHA-256 hash of the email after common alias forms have been folded together, so variations of one address count as one buyer. Neither hash is keyed: anyone with a list of candidate addresses could check whether one matches. We also keep a true/false value for whether the email's domain is a disposable-email provider.
- The order's IP address (
browser_ip).- We store a keyed code of its connection, as in §1.1.
- We store eight true/false verdicts — Tor, hosting/server network, VPN, compromised network, country mismatch, residential proxy, crawler and assistant — and the two-letter country code of the IP.
- We store the counts worked out when the order arrived: orders from this connection, buyers from this connection, small orders from this connection (and the threshold used for "small") and unfinished checkouts from this connection — plus one true/false value for whether this connection placed a flagged order before.
- To work these out, the address is matched in memory against the IP lists we download and keep, and sent to the lookup services in §5. The readable address is then discarded.
- The shipping address, as a keyed code. We store a keyed code (HMAC) of a standardised form of the address, a count of how many different buyers sent orders to it, and a true/false value for whether the billing and shipping addresses differ. The billing and shipping country codes are compared in memory. The address itself is never stored.
- Line items: for each line, the product id, the quantity and the alias-folded email code. No titles and no line prices. We also store the largest quantity on any one line.
- Time since publish. We read the product's publish time from Shopify and store only the number of seconds between that and the order.
- The User-Agent of a storefront order (
client_details.user_agent): the same three true/false answers as in §1.1, and nothing else. - Card attempts. We read the order's transactions from Shopify, which include the card's BIN, masked number, expiry and card company. We keep only two counts: how many payment attempts failed, and how many different cards were tried. No card detail is stored.
- First order: we read the customer's order count from Shopify and keep only whether this is their first order.
- The assistant an order came through, when something names one: the assistant's web address the buyer arrived from (for
example
chatgpt.com, from a fixed list — never the full referring URL), the name of the app that placed the order, or the channel name Shopify's own reports give it (asked hourly for 48 hours after the order, then never again). It is shown as a fact on the order and in its risk panel and never changes the score. Most orders have none. - Shopify's own risk verdict and any cancellation, from the
orders/risk_assessment_changedandorders/cancelledwebhooks: Shopify's risk level, the cancellation reason, and the times an order was held, released or cancelled. - The cart it came from. The order's
cart_tokenis compared, in memory, with the carts the checkout check failed in the last two hours (§1.3), so Cart Shield can count an order it would have refused. It is not stored. - Score, band and signals, with each signal's value; whether the order met the strictest bar (§8); the link to its storefront visit and the state of that link; and a frozen copy of the visit's findings, so the order's explanation stays complete after the visit is pruned.
- Action status: when the verdict was written to Shopify's risk panel, when a hold failed and why, and when the order was tagged (§8).
What goes back into Shopify: Cart Shield writes its verdict to the order's risk panel in your Shopify admin — a risk level and up to 20 short explanations.
1.3 The checkout check (storefront script, off by default)
In short: if you turn it on, a small script on your storefront counts interactions and sends them to our server, which writes a pass, skip or fail mark onto the cart. The mark and daily counts are all that is kept.
This runs only when you set the checkout check to Monitor or Enforce on the Protection page and switch on Cart Shield's app embed in your theme. Then, on each storefront page:
- What the script counts. Only interactions the browser marks as made by a person: pointer presses, touches, key presses, scrolls and clicks (five numbers), and whether a click came before any pointer, touch or key. It does not record where, when or on what, and it records no keystroke content.
- What it reads. The cart token, from your store's own
/cart.js, and Shopify'scartcookie, only to notice that the cart changed. A hidden form field placed by the embed, which a person never sees or fills in. The visitor's consent state (granted,deniedorpending) from Shopify's Customer Privacy API. - Browser tells — only with consent. With Respect EU consent on (the default), these are read only when the visitor has allowed
analytics; with it off, always: whether
navigator.webdriveris set, whether the browser names itselfHeadlessChrome, whether a Chrome browser lackswindow.chrome, an empty language list, a zero outer size for the window, and a notification permission that contradicts itself. Each is one true/false value. - What it sends, and when. Nothing before the first counted interaction. Then the cart token, to get a challenge from our server;
and on add-to-cart or checkout, the cart token, the challenge, the five counts, the click flag, whether the hidden form field was filled (yes or no — never what was in it), the
consent state and (as above) the browser tells. It holds a form submit or checkout click for at most 3 seconds while it does — usually far less; the longest wait is when that click is the first thing done on the page. Requests go
through Shopify's app proxy on your store's own address (
/apps/cart-shield/gate/). The script stores nothing in the browser. - What it adds to the cart. Our server answers each check with a short sealed code — the check's result, encrypted and signed by
our server so that neither the script nor anyone else can read or alter it, valid for 30 minutes — and the script adds it to the
add-to-cart form as the cart attribute
_cs. This is needed because Shopify gives a brand-new cart a new token at its first add-to-cart, so a result for that first add would otherwise be lost; the next check for the cart reads the code back and keeps a fail a fail. It holds no personal data, only the result and its expiry. Shopify hides it from the shopper at checkout, but shows it to you in an order's Additional details in the Shopify admin, as_csfollowed by an unreadable code; it cannot be hidden there.
What our server does with it:
- It checks Shopify's signature on the request and the challenge it issued, judges the counts and tells in memory, and writes one
mark onto the cart —
pass,skiporfail— in an app-reserved cart metafield, through Shopify's Storefront API. Cart Shield's checkout Function reads that mark at checkout (§1.4). The request body is then discarded; nothing in it is stored. - Per-day counts per shop — carts passed, skipped and failed, and orders it would have refused — kept for 90 days.
- Failed carts, in memory only. For up to two hours, a SHA-256 hash of a failed cart's token, so that an order from that cart can be counted as one the check would have refused (§1.2). Lost whenever the app restarts.
- Rate limits, in memory only. A count of requests per shop and, when address-based limiting is configured on our server, per IP address.
- The Storefront API token Cart Shield creates for your store to write the mark is stored encrypted (AES-256-GCM). A new one replaces it each time you turn the check on.
What goes into your store: the mark on each checked cart, the sealed _cs cart attribute described above (which Shopify then keeps
on the order), and an app-owned setting on Cart Shield's own installation holding the
check's mode, the hidden field's name, and — if the decoy is on (§1.5) — a short list of a few of your products (id, title and price)
that includes the decoy. The embed prints that list into the page, out of sight, for a script to find.
1.4 Your rules and the checkout Function
In short: a rule naming a person is stored as a code plus a short hint. Checkout data is compared inside Shopify and never reaches us.
You can create rules about emails, email domains, phone numbers, names, addresses, countries, regions, connection types (Tor, VPN or proxy, server or cloud host, residential proxy, known bad network, crawler address) and the country of a connection.
- Allow and block. Email, phone, address, country, region and connection rules can allow or block. Name rules can only allow: they recognise a customer you trust, and never block anyone. Email-domain rules can only block: a domain matches exactly (the part after the @, in any capitals; a subdomain is a separate rule), so an allow on a large domain would switch off your other blocks.
- How rules are stored.
- Email, phone, name and address rules are stored as an unkeyed SHA-256 hash, plus a short hint so you can recognise the rule —
for example
a•••@domain.comfor an email,•••• 123for a phone,A••• L•••for a name. For an address rule, the hint shows the ZIP/postcode and country in full. - Email-domain, country, region, connection and connection-country rules are stored as you entered them (a domain, such as
mailinator.com, names a mail service rather than a person). - For each rule that refuses at checkout, we record the checkouts it refused, by id only (§1.13).
- Email, phone, name and address rules are stored as an unkeyed SHA-256 hash, plus a short hint so you can recognise the rule —
for example
- Where rules act. Email, email-domain, phone, address, country and region rules act at checkout. Connection and connection-country rules act on the order after it is placed, because they depend on the IP verdicts in §1.2.
- Enforcement at checkout. We publish the rule hashes, your country and region rules, the checkout message you wrote for refused
buyers, your store's public contact email (Shopify's
contactEmail, the address your customers already write to; read when checkout is published, and added to the end of the standard refusal wording only), and — if they are on — the checkout check's switch and the decoy's variant id, into a metafield on Cart Shield's checkout validation in your Shopify store, where Cart Shield's checkout Function reads them. - What the Function sees. The Function receives the buyer's email and phone; each delivery address's name, phone, street, unit, postcode, region and country; the checkout's language; the cart's product variants; and the checkout check's mark, from Shopify. It compares them with your rules inside Shopify's checkout, with no network access, and stores nothing. None of that checkout data is sent to our server by the Function. Separately, Shopify sends our server each checkout as the buyer fills it in, so we can count what was refused (§1.13).
Rules are kept until you delete them.
1.5 The decoy product (off by default)
If you turn the decoy on, Cart Shield creates one product in your store: unlisted (reachable only by its address, never in a collection, search or your sitemap), marked hidden from search engines, with a title and price chosen for your shop, inventory not tracked, and published to the Online Store channel only. The checkout check lists it where only a script would find it (§1.3), and a cart holding it is refused at checkout (§8). It identifies no one; its only purpose is to be taken by a script that reads the page rather than a person who looks at it.
Turning the decoy off archives the product. ⚠️ Uninstalling Cart Shield leaves the decoy in your store: once uninstalled, the app has no access left to remove it. If you used it, delete it from Products in your Shopify admin.
1.6 Data read live from Shopify but not stored
Some shopper details are read from Shopify at the moment they are needed and are not stored:
- Where they are read: when you open an order or the orders table in Cart Shield; when Cart Shield's blocks appear on Shopify's order and customer pages; and when Cart Shield checks your allow list and rules before acting on an order (§8).
- What may be read: the buyer's email and phone number; the shipping country and region; the delivery name, phone, street address, unit and postcode; and the billing name and phone.
- For tagging (§8), the customer's Shopify id is read so the customer can be tagged. It is not stored.
- Disputes. Home's dispute figures read your Shopify Payments disputes when the page opens. Nothing from them is stored.
These details are shown to you or used for the check, and then discarded. Each such read of shopper details is recorded in the access log (§1.10), without the details themselves.
1.7 Activity log
The activity log is the list on the Activity page and on Home ("What Cart Shield did"): one row for each thing Cart Shield did or
noticed to defend your store. Each row holds only ids and closed codes: what kind of event it was (from a fixed list, for example order
scored, order not scored, rule matched, order held, hold failed, hold released, cancelled and refunded, customer frozen, customer unfrozen, freeze ended, rule added or removed, order
tagged, segments created, Shopify Flow trigger sent, risk panel written, plan feature switched off, checkout refused), which defence
did it (a block rule, a freeze, flagged orders, the checkout check, the decoy and so on), who acted (cart-shield, merchant, or
shopify for something done in Shopify's own admin), a short reason code (for example strong-score:70 or rule:email, the kind of
rule and never its value), the Shopify order id, the id of the rule or visit it concerns, and the time. A row that records a refused
checkout also holds a one-way hash of the checkout (the same value as in §1.13), only so that a redelivered notice is listed once.
It never holds a name, email address, phone number, street address, IP address, cart token or the value of a rule. Tagging's own
record is still the time the order was tagged (§1.2). Rows are kept for 90 days and then deleted by the hourly job (§7); they are
erased earlier as described in §10.
1.8 Shop settings and OAuth session
- Shop settings: your choices of detections, thresholds, what to do with flagged orders (§8), whether Strong orders are tagged, the checkout message shown to refused buyers, the checkout check's mode and its EU-consent setting, the decoy's on/off and its product ids, the id of Cart Shield's checkout validation, the encrypted Storefront API token (§1.3), and your shop's time zone as Shopify reports it (read when you open Insights, so its daily totals follow your days, §1.10). None of this identifies a shopper.
- OAuth session: the access token and granted scopes Shopify issues when you install the app. Cart Shield uses offline tokens only, so no staff member's name or email is stored with the session. The session is deleted when you uninstall.
1.9 Support conversations (your messages to us)
If you open a request from the app's Support page, the subject and message you write, its category, your shop's name, your shop's
domain and your shop's contact email are sent to Zoho Desk (Zoho's Australian data centre, desk.zoho.com.au), the help desk where
we answer every support request — the same place an email to support@sushinet.fyi lands. If your shop has no contact email, the
ticket uses support+<your-shop>@sushinet.fyi instead. Each request is its own conversation there.
The app keeps one reference per request — its category, and when it was opened, last written to and closed — so you can see your requests and reply to them. It holds no subject and no message text. (An earlier one-per-shop reference to a single conversation is still held for shops that wrote before October 2026; it is a ticket id, no text, and is removed in the next release.) Erasing your shop's data (§10) removes these references; it does not delete the conversations in Zoho Desk, which are our correspondence with you. We keep them for as long as we need them to support you, and you can ask us to delete them.
Please do not paste your customers' details into a support message. Zoho Desk holds our correspondence with you, not your customers' data, so it is not a sub-processor of it — and it stays that way only if a message carries none.
1.10 Operational records
Access log. A file on our server recording each live read of shoppers' contact details from Shopify (§1.6), and each of Shopify's three compliance requests (
customers/data_request,customers/redactandshop/redact, §10) once Cart Shield has acted on it. Each line holds the time, the reason (for a compliance request, its topic), the shop, the action (a read or an erasure) and a row count, and no shopper data: never the customer's id, email or phone, nor the order ids a request names. Capped at the most recent 20,000 lines. Reading an order's email to hash it when the order arrives (§1.2) is not written to it.Web server access log. Our web server (Caddy) logs every request it receives, in two files:
- The web pixel's requests, which come straight from shoppers' browsers, are logged without the IP address, the connection's port or the request's headers — those are removed before the entry is written. Each entry holds the time, the address requested, the request's method and protocol, and the response's status, size and timing. Kept in a file of its own, rotated at 10 MB with the five previous files kept.
- Every other request — your visits to the app, Shopify's webhooks and the checkout check — is logged with the time, the IP address the request came from, the address requested, the request's headers (including the User-Agent; cookie and authorisation headers are hidden), and the response. Requests for the checkout check reach us through Shopify's app proxy, so their logged address is Shopify's, while their headers may carry the shopper's. This log is used to block repeated abusive requests. It is rotated at 10 MB with the five previous files kept, and shared with our other apps on the same server.
How many days either file covers depends on traffic.
Agent signatures: when an assistant's request to our pixel endpoint carries a signature header, we record the host it names, with counts and first/last seen times. This holds nothing about the shopper and is not tied to a shop.
IP lists and lookup counts. We store the IP lists we download (§5), and a daily count of lookups made to each lookup provider. Neither holds shopper data.
Your shop's lookup count. Each plan includes a number of IP lookups a month (Free 500, Protect 2,000, Pro 5,000). To keep to it we store a monthly count of the orders your shop spent an IP lookup on: your shop domain, the month (UTC) and a number, with no IP address and no order. An answer we already had cached does not count. Past the limit an order is still scored on our own lists; only the lookup service's findings show as not checked until the 1st of the next month. We keep the current month only (an earlier month is deleted at your shop's first lookup of a new one, or within the hour after the month ends if there is none), and the count is erased with your shop's data (§10).
IP lookup cache: see §7.
Insights daily totals. Visits are deleted after 30 days (§7), so for Insights to cover 90 or 365 days we keep, per shop per day, the counts the Insights page shows: visits (scored, not scored, Strong), how many added to cart or reached checkout, orders (scored, Strong, reached checkout unseen, and how many carried a card-testing finding, counted once per order), how often Cart Shield and Shopify flagged the same orders, and how many times each signal fired with its points. An hourly job counts each day before its visits are deleted. These are numbers and signal names only: no visit key, order id, code, IP address or anything else about a shopper or an order.
Server logs. Errors are written to the server's system log. They can include your shop domain, an order id and the error. Some errors are logged as the full error object or its message, so a log line can contain whatever detail that error carried. Cart Shield removes its Storefront token and the cart token from the checkout check's error lines before they are written.
1.11 Freeze, Shopify Flow and email segments
- Freeze (you choose it). Freezing an email address, phone number or delivery address for 24 hours, 72 hours or 7 days stores it exactly like a block rule (§1.4) — a one-way code and a short hint — plus the time it ends. Within an hour of that time Cart Shield republishes your checkout rules without it and deletes it. You can also choose to have a Strong order's buyer frozen automatically (off by default; §8).
- Shopify Flow. When Shopify accepts Cart Shield's verdict on an order and its band or level has changed, Cart Shield tells Shopify Flow ("Order automation scored") — but only if you have a Flow workflow switched on that uses it, on a paid plan. It sends the order reference, the score, the band, the risk level Cart Shield gave the risk panel, whether Cart Shield is certain, and up to three finding labels, and no customer details. We store which Flow triggers your shop has switched on (from Flow's own notice) so nothing is sent to a shop that does not use them.
- Email segments (on your click). If you press "Create email segments", Cart Shield creates two saved customer segments in your
Shopify admin, built from the
cart-shield-strongtag: the flagged customers, and your email subscribers with the flagged customers left out. Cart Shield reads no customer through them and stores nothing about them; it never edits a segment again and never changes anyone's email consent. What an email tool does with a segment is up to you and that tool.
1.12 Billing records
- Promo codes you type. Each code entered on the Plans page, with what you were told (for example "unknown" or "used"). Deleted with your shop's data (§10).
- Codes redeemed, a subscribe in progress, your one free trial, and the period you have paid for, each keyed by a one-way SHA-256 hash of your store's domain rather than the domain itself: which promo codes this store has redeemed and when their discount ends, a short-lived lock while a subscription is being created, the date your free trial was granted, and the date the billing period you have already paid for ends (with the plan it was for), so that cancelling keeps that plan until then. They are kept after uninstall on purpose — otherwise uninstalling and reinstalling would hand out the trial and every code again, or lose a period you paid for. A hash can only confirm "this store has already had this" when that same store asks again; it cannot be used to list or contact anyone.
1.13 Refused checkouts (the checkouts/create and checkouts/update webhooks)
In short: to show you what your block rules, freezes, checkout check and decoy refused, our server repeats the checkout Function's comparison on each checkout Shopify sends us, and keeps only which defence refused it.
The checkout Function cannot tell us what it refused, and a refused checkout never becomes an order. So Cart Shield subscribes to
Shopify's checkouts/create and checkouts/update webhooks, which send the checkout — the buyer's email and phone, the delivery
address and name, the cart token and the product variants — when it opens and each time it changes (a checkout refused on opening,
before anything is typed, sends only the first, with the cart's products and no personal details). The same handler reads both.
- What our server does with it. It compares those details, in memory, with exactly what was published to the Function (§1.4): your rules and freezes, the checkout check's mark on that cart (from the failed-cart memory, §1.3) and the decoy's variant. Then the details are discarded.
- What is kept — the refused-checkout record. For each defence that refuses the checkout: a one-way SHA-256 hash of Shopify's
checkout token, which defence (
rule,freeze,checkordecoy), the rule's id, the day, Shopify's own update time for that checkout, whether it is still refused, and a one-way hash of your own published settings for that defence (so a change you make later never un-counts a refusal that happened). Never the email, phone, name, address, cart token or products. One record per checkout per defence, however many times Shopify sends it. - A checkout that became an order was not refused. When an order arrives, its checkout token is hashed and any record for that checkout is marked as ordered, and no longer counted. Nothing from the order is added to the record.
- Kept for 90 days, then deleted by the hourly job; erased with your shop's data (§10). The record cannot be matched to a customer.
- In memory only, for up to two hours: each checkout's latest update time (keyed by the hashed token), so that an out-of-order delivery from Shopify cannot change a newer answer. Lost whenever the app restarts.
1.14 What we do not collect
Cart Shield's database stores none of the following: the shopper's name, street address or phone number; their time zone; their IP address in readable form; payment card details; product titles or prices (other than the few the checkout check lists in your own store, §1.3); discount codes; marketing consent. It holds no device fingerprint, no mouse or keystroke recording and no raw event stream: events are folded into counters as they arrive and then discarded.
2. Who is in charge of what — our role
In short: for your shoppers' data, you decide and we follow your instructions. For your own account and settings, we decide.
- You (the merchant) are the controller, and we are your processor, for your shoppers' data that Cart Shield handles on your behalf: visit records (§1.1), order records (§1.2), the checkout check (§1.3), rules naming a person (§1.4), live reads (§1.6) and the activity log (§1.7). We use it only to score orders and visits and to carry out the actions you turned on, and for no purpose of our own. Our Data Processing Agreement binds us to that role.
- We are the controller for data about you and your shop: the OAuth session and settings (§1.8), support conversations (§1.9) and the operational records (§1.10) — including the web server access log, which we keep to protect the service.
If one of your shoppers asks to see or delete their data, the request goes to you, and we will help you answer it (§11).
3. Why we are allowed to process it
In short: mostly because you installed an app to spot fraudulent orders, and it needs this data to do that.
Where the GDPR or UK GDPR applies:
| What | Legal basis |
|---|---|
| Running Cart Shield: scoring, rules, the risk panel, keeping you signed in | Performance of a contract (Art 6(1)(b)) |
| Fraud detection on your shoppers' visits, carts and orders | Yours to hold as controller. For you, preventing fraud is commonly a legitimate interest (Art 6(1)(f), recital 47) |
| Security logging, the web server access log, and diagnosing a fault you report | Legitimate interests (Art 6(1)(f)) |
| Answering your support requests | Performance of a contract (Art 6(1)(b)) |
Reading from a shopper's browser. The web pixel and the checkout check's script read from the visitor's device (§1.1, §1.3). Where a law requires consent for that, you decide how your store obtains it. The pixel runs under Shopify's analytics consent; the checkout check reads browser tells only with analytics consent unless you turn Respect EU consent off; its interaction counts are sent regardless of consent. If a law where your shoppers are requires consent for those counts, you must obtain it on your store.
4. Where data lives
Cart Shield's database is on a virtual server we operate in Sydney, Australia, shared only with our other apps, each under its own system account with its own database. Data is encrypted in transit (HTTPS) between Shopify, the app, a shopper's browser and your browser.
If you are in the EEA or the UK: Cart Shield's data is stored in Australia. Australia is not covered by a European Commission adequacy decision, so where the GDPR applies, transfers rely on the safeguards in Article 46 or the derogations in Article 49 (§6).
5. Who we share data with, and who we rely on
We do not sell merchant or shopper data, and we do not share it for anyone else's purposes. We rely on a small number of providers to run the app. Under the GDPR those that hold or receive your shoppers' data on our instructions are sub-processors, listed in Annex III of the DPA:
| Provider | Country | What it does for us | What it can hold |
|---|---|---|---|
| Shopify | Canada / USA | The platform. It runs the checkout Function, the web pixel and the app proxy, sends us orders, and answers our live reads (§1.6). | Everything in §1 comes from Shopify. We write back the risk-panel verdict, the validation metafield (§1.4), the checkout check's cart marks and settings (§1.3), the decoy (§1.5), and the tags, holds, cancellations and refunds you turned on (§8). |
| Oracle Cloud | Australia (Sydney) | The server running the app and its database, and the object storage holding the daily backups (§7). | Everything Cart Shield stores (§1). |
| IP reputation services (three, used in turn) | Overseas; locations not fixed by us | IP lookup: proxy, VPN, hosting and country. Each one after the first is used only if the ones before it are not set up, have used their day's quota, or do not answer. | The order's IP address, at most one lookup per order (answers are cached, §7). |
| A DNS blocklist of compromised machines | Overseas; the list operator's own servers, reached through our resolver | Checked by a DNS lookup of the reversed address under the list's own domain, through our server's DNS resolver. IPv4 only. | The order's IPv4 address, inside the DNS query. Our DNS resolver also sees the query. |
| Zoho Desk | Australia | Our help desk (§1.9). | Your messages, shop name, domain and contact email. Not your customers' data. |
How the lookups run:
- The three IP reputation services are tried in a fixed order. The first one that is set up, has quota left for the day and answers is used; the others are not contacted for that order. If none answers, the verdicts are left uncomputed rather than marked clean.
- The DNS blocklist is also queried, for IPv4 addresses.
- We describe these services by kind rather than by name, as we do the lists below: naming them would tell anyone trying to get round Cart Shield where to look.
- All of these lookups start after Cart Shield has replied to Shopify's order webhook, so they never delay Shopify's receipt of the order.
- The IP address of a storefront visit is never sent to any of them, and nor is anything the checkout check collects.
What we download. Data also flows the other way. We download these lists to our server, sending no shopper data: the Tor exit list; published address ranges of cloud and hosting providers; published ranges of search-engine crawlers and assistants; lists of VPN ranges and of networks known for abuse; a privacy relay's published exit ranges; and an IP-to-country table. We describe them by kind rather than by name: they receive nothing from us, and naming them would tell anyone trying to get round Cart Shield where to look.
Our public website, sushinet.fyi (where this page is served), is hosted by Vercel (USA). No store, merchant or shopper data from
Cart Shield reaches it.
We will update this list before adding any provider that would receive store data. If a legal request such as a court order ever compelled disclosure, we would tell the affected merchant unless the law prohibited us from doing so.
6. Sending data overseas
In short: your data is stored in Australia. An order's IP address goes to the lookup services in §5, wherever they are.
We are an Australian business and Cart Shield's database is in Australia. Shopify (Canada and the USA) and the IP lookup services in §5 are overseas recipients. Under Australian Privacy Principle 8, we remain accountable for what they do with it.
If you or your shoppers are in the EEA or the UK: Australia is not the subject of a European Commission adequacy decision. Where the GDPR applies, transfers to us rely on the safeguards in Article 46 — in practice the Standard Contractual Clauses, which we will sign with any merchant who asks — or on the derogations in Article 49.
7. How long we keep data
- IP code on a visit: 72 hours from the visit's most recent event. Each new event restarts the 72 hours. An hourly job clears expired codes.
- IP code on an order: 72 hours, or 30 days if the order was scored Strong. Cleared by the same hourly job. The order's IP verdicts, country code and counts are not cleared; they stay with the order record (below).
- Address code: 30 days from the order's creation. Cleared by the hourly job.
- Visit records (counters, verdicts, the raw order id, score and signals): 30 days, then deleted by the hourly job, counted from the visit's first event. A visit can outlast its 30 days by up to about an hour, or for as long as the app is down. This holds for every shop, including one whose storefront has gone quiet and one that has uninstalled and is waiting for its data to be erased (§10). Insights' daily totals count each day before its visits are deleted (§1.10).
- Order records and line items (order id and name, total, email codes, verdicts, country code, counts, card-attempt counts, score,
signals, frozen visit findings, Shopify risk and cancellation data): no time limit while the app is installed. They are kept until
a
customers/redactorshop/redactrequest erases them (§10). - The checkout check: per-day counts for 90 days; failed-cart hashes in memory for up to two hours; the mark on a cart for as long
as Shopify keeps that cart. The sealed
_cscart attribute (§1.3) stops opening after 30 minutes, but Shopify copies it onto the order, where it stays for as long as you keep the order; Cart Shield does not remove it. - IP lookup cache: to avoid looking the same IP up twice, we cache each lookup's answer, including the country.
- Entries last 6, 24 or 72 hours depending on the answer, and 24 hours for the DNS blocklist.
- The cache is indexed by a keyed code of the full IP address, IPv4 or IPv6, not of the connection. It is not linked to any order or shop.
- ⚠️ Expired entries are deleted when a later lookup triggers the clean-up (about 1 write in 16), so an expired entry can stay in the database after its expiry. It is not used after it expires.
- A second, in-memory cache holds up to 5,000 recent answers and is lost whenever the app restarts.
- Insights daily totals (§1.10): 365 days, for every shop whatever its plan, then deleted by the hourly job; erased with your shop's data (§10). They are counted from visits and orders before the visits are deleted, so they outlast the visits themselves.
- Rules: until you delete them, or until your shop's data is erased.
- Refused-checkout records (§1.13): 90 days, then deleted by the hourly job; the in-memory update times and order marks, up to two hours. Erased with your shop's data (§10).
- Activity log (§1.7): 90 days, then deleted by the hourly job; erased earlier with your shop's data, and with the orders it names when one is redacted (§10).
- Settings and OAuth session: while the app is installed. The session is deleted on uninstall.
- Support conversations: the in-app references are deleted with your shop's data. The conversations in Zoho Desk are kept for as long as we need them to support you; ask us and we will delete them.
- Access log: the most recent 20,000 lines. Web server access log: see §1.10.
- Agent signature records and daily lookup counts: no time limit. Neither holds shopper data.
- Your shop's monthly lookup count: the current month only, and erased with your shop's data (§1.10).
- Freezes: until they end, then deleted within an hour (§1.11).
- Billing records: promo codes you typed, until your shop's data is erased; the hashed redemption, trial and paid-period records, indefinitely (§1.12).
- Server logs: kept until the server's system log reaches its size limit (about 4 GB, shared by everything on the server), when the oldest entries are deleted first. There is no fixed time limit: at the volume the server writes today, that is several months.
- Backups. A copy of the database is taken every night, checked, and stored in object storage, and copied to a second bucket; each copy is deleted automatically after about 30 days. The server's disk is also snapshotted daily, and each snapshot kept for 4 days. Both buckets are in Sydney. This is what stops the windows above from being the whole story: an IP code cleared from the live database after 72 hours can still be in a backup taken before then, for about 30 days more. We do not read backups, and we do not restore one to bring back data that has been deleted.
8. Decisions Cart Shield can make about an order or a checkout
In short: by default Cart Shield only scores and explains. Every action here is one you switch on, and a person can review it.
- Scoring and the risk panel (always on). Every order gets a score and a band, shown in Cart Shield and written to the order's risk panel in Shopify. The score is calculated by fixed rules — lists, ranges, counts and fixed weights — the same on every store. It is advice to you; on its own it changes nothing about the order.
- Tagging Strong orders (off by default). If you turn it on, every order scored Strong gets the tag
cart-shield-strong, and so does its customer. The tag is added once and never removed by Cart Shield. Once added it is ordinary Shopify data: Shopify Flow, your order filters, and any email or marketing tool you connect can see it, and what they do with it is set by you and by them. - Holding flagged orders (off by default). If you choose to hold, Cart Shield places a fulfilment hold on a Strong order so you can decide by hand.
- Cancel and refund (off by default). If you choose it, Cart Shield cancels an order (reason "Other", with a staff note "cancelled for review", never "fraud") only if it meets the strictest bar, refunds it to the original payment method, restocks the items and does not email the customer. Strong orders below that bar are held instead. A refund cannot be undone, so this needs your explicit choice.
- Your allow list wins. Before holding or cancelling, Cart Shield checks your allow list at that moment. If the customer is allow-listed, or if it cannot tell whether they are, it does nothing.
- Block rules (§1.4) can stop a checkout, or count against an order after it is placed. They are your rules; the checkout ones are enforced by Shopify's checkout.
- The checkout check (off by default). In Monitor it refuses nothing and counts what it would have done. In Enforce, the checkout
Function refuses a cart our server marked
fail, and shows the buyer your checkout message. A cart with no mark is let through, because Shopify also runs checkout for draft orders, wallet buttons and other channels where the check never runs; and if our server cannot be reached, every cart passes. - The decoy (off by default). A cart holding the decoy product (§1.5) is refused at checkout.
- Freeze (you choose it; auto-freeze off by default). A frozen email address, phone number or delivery address is refused at checkout like a block until the freeze ends, at most an hour late. If you choose "freeze" for flagged orders (only Strong orders, and part of the Strict preset only), the buyer's details are frozen automatically. Your allow list wins.
- Shopify Flow. Cart Shield only tells Flow that an order was scored; anything a workflow then does — a tag, a hold — is the workflow you set up. Cart Shield's template holds and tags; it never cancels.
- Email segments decide nothing by themselves: they are lists you may choose to send to.
These are automated decisions with an effect on a shopper, made only because the merchant chose them. We disclose them because Shopify's protected-customer-data requirements ask apps to be explicit about automated decisions with a significant effect, and because Australian Privacy Principle 1.8 requires it from 10 December 2026.
A person can review any decision. If you are a shopper and think an order or checkout was handled wrongly, contact the store. The store controls these settings and can release, reverse or change them. If the store needs our help to understand a decision, we will help them.
9. How we protect it, and what happens if that fails
- Traffic between Shopify, Cart Shield, shoppers' browsers and your browser is encrypted in transit (HTTPS).
- Administrative access to the server is key-based only — password logins are disabled — and limited to the operator. The app runs as its own unprivileged system account, and its database is readable only by that account. The server's storage is encrypted at rest with a provider-managed key, and backups are held in object storage encrypted at rest.
- IP and address codes. IP addresses are kept in the database only as keyed codes (HMAC) — of the whole address for IPv4, of the
/64prefix for IPv6 — and shipping addresses only as keyed codes. The key is Cart Shield's Shopify app client secret, held on our server and also known to Shopify. Anyone holding that key could recover an IPv4 address from its code by trying every possible address, and could test a candidate shipping address. So we treat these codes as pseudonymous, not anonymous. - The email, visit-key, failed-cart and rule hashes are not keyed (§1.1–1.4). We treat them as personal data.
- The checkout check's Storefront token is encrypted with a key derived from a separate secret held only on our server.
- Every webhook's signature, and every checkout-check request's app-proxy signature, is checked before anything is done with it.
No system is perfectly secure. If a data breach affects your store, we will tell you without undue delay, and within 72 hours of becoming aware of it. Where the Australian Notifiable Data Breaches scheme or GDPR Article 33 applies, we will also notify the regulator.
10. Deletion — Shopify's mandatory compliance webhooks
customers/data_request: Cart Shield counts the order records held for that person and logs the count, so we can report it to you by hand. ⚠️ The count includes order records only, not the person's line items, rules or activity-log entries. If you relay a request, ask us and we will check those by hand as well.customers/redact: for the orders listed in the request, Cart Shield deletes the order records, their line items and their activity-log entries, and clears the IP code on the linked visits. It deletes email and phone rules matching the person, and republishes your checkout rules so the deleted hash stops acting at checkout. Some data is not touched:- the linked visit keeps the raw order id until the visit is pruned (§7);
- name and address rules — the request carries no name, and matching addresses is not implemented; you can delete such rules yourself, or ask us to;
- the IP lookup caches, which are not linked to a person or shop; entries are not used once they expire (§7);
- the Insights daily totals (§1.10): a day's counts may include that person's orders, but they hold no order id and nothing that leads back to anyone;
- the refused-checkout records (§1.13): they hold a hashed checkout token and no customer id, email, phone or order id, so nothing in the request can find them; they are deleted after 90 days (§7);
- server logs, the web server access log and the access log;
- copies in backups, until they expire (§7).
shop/redact(sent by Shopify about 48 hours after uninstall) deletes all of your shop's visits, orders, line items, rules, activity log, settings (with the encrypted Storefront token), the checkout check's counts, refused-checkout records, Insights daily totals, the Flow triggers it had switched on, the promo codes it typed, session and support references. The hashed billing records (§1.12) are kept on purpose. It does not delete the support conversations in Zoho Desk, the access logs, agent-signature records, the IP lookup cache, server logs or backups before they expire.app/uninstalled: deletes the OAuth session immediately.
All three compliance webhooks verify Shopify's signature before acting; an invalid signature is rejected and no data is touched.
What stays in your store after uninstall. Tags Cart Shield added (§8), the risk-panel verdicts on your orders, and the decoy product
if you used it (§1.5) are your store's data and stay there, as does the sealed _cs attribute on any order placed from a checked cart
(§1.3). The validation metafield (§1.4), the checkout check's settings (§1.3) and the
marks on carts are held by Shopify against Cart Shield's installation, its checkout validation and the carts, not on our server.
11. Your rights, and how to use them
In short: ask us at support@sushinet.fyi and we will answer within 30 days, free.
- Merchants: you can ask for a copy of what we hold about you, or ask us to correct it, delete it, restrict it, or give it to you in a portable form. This includes your Zoho Desk conversations. There is no charge, unless a request is clearly unfounded, repetitive or excessive — in which case we will tell you why before doing anything.
- Shoppers: the store is the controller of your data, so please send requests to the store. Shopify passes deletion requests to us automatically (§10).
- Complaints: please tell us first. You can also complain to the Office of the Australian Information Commissioner (https://www.oaic.gov.au), or to your local data protection authority if you are in the EEA or the UK.
- California and other US state residents: we have not sold or shared personal information for cross-context behavioural advertising, and we do not process sensitive personal information.
12. Children's data
Cart Shield is a business tool sold to merchants and is not directed at children. We do not knowingly collect personal information about anyone under 16. If we learn that we hold some, we will delete it.
13. Cookies and your storefront
- Inside the app's admin pages, Shopify's app framework sets a strictly necessary session cookie so you stay signed in.
- On your storefront, Cart Shield sets no cookie and stores nothing in the browser. The web pixel (§1.1) runs inside Shopify's
pixel sandbox and uses Shopify's own
clientId, which Shopify manages. The checkout check's script, when you switch it on (§1.3), reads Shopify'scartcookie without changing it.
14. Access scopes, and Protected Customer Data status
Cart Shield asks for these scopes, each for the feature named:
| Scope | Used for |
|---|---|
write_orders |
Reading orders (§1.2); writing the verdict to the risk panel; cancel and refund when you turn it on (§8) |
write_pixels |
Connecting the web pixel (§1.1) |
read_customer_events |
Subscribing that pixel to Shopify's standard events |
write_validations |
Installing and configuring Cart Shield's checkout validation Function (§1.4) |
write_merchant_managed_fulfillment_orders |
Holding and releasing a flagged order that ships from your own location (§8) |
write_third_party_fulfillment_orders |
The same hold, for an order that ships from a fulfilment service's location |
read_shopify_payments_disputes |
Home's dispute figures, read live and not stored (§1.6) |
read_shopify_payments_accounts |
The Shopify Payments account those disputes sit under, which Shopify gates separately |
write_customers |
Reading whether an order is the customer's first (§1.2); tagging a Strong order's customer when you turn it on (§8) |
write_products |
Reading a product's publish time (§1.2); creating and archiving the decoy (§1.5) |
write_publications |
Publishing the decoy to the Online Store channel only (§1.5) |
read_themes |
Checking whether the checkout check's app embed is switched on in your live theme, so Protection can warn you. Nothing in a theme is written |
unauthenticated_read_checkouts |
Reading the checkout check's mark on a cart through the Storefront API (§1.3) |
unauthenticated_write_checkouts |
Writing that mark |
read_reports |
The assistant order label (§1.2): once an hour, one Shopify report query per shop, for orders from the last 48 hours that Shopify has not yet attributed. It reads each order's id with the assistant channel Shopify's reports name (agentic_referring_channel, agentic_sales_channel) and keeps only that channel name on the order, with which source it came from and when it was last asked. It is shown as a fact and never changes the score. Shopify's reports do not include test orders |
Any scope that writes a resource also lets the app read it; Cart Shield reads only what the sections above describe.
Protected Customer Data. Cart Shield reads orders, so it handles protected customer data, including name, email, phone and address
fields at Level 2. It subscribes to the protected webhooks orders/create, orders/risk_assessment_changed, orders/cancelled and
checkouts/update (§1.13; checkout data is order data, so write_orders covers it).
Shopify reviews our access to protected customer data as part of App Store review.
15. Changes to this policy
If what Cart Shield collects, where it sends it or how long it keeps it changes, we will update this document and the "Last updated" date before the change goes live. Material changes are announced in the app.
16. Contact
Questions about this policy, or a request to access or delete data we hold: support@sushinet.fyi — Edwin Guo, trading as Sushinet, New South Wales, Australia.