Last updated: September 21, 2026
MarginShield is operated by A2E Group Pty Ltd, trading as MarginShield (“MarginShield”, “we”, “us”). This policy explains how we collect, use, store and disclose personal information when you use the MarginShield true-margin platform. It is written to align with the Australian Privacy Principles (APPs) and, where applicable, the EU General Data Protection Regulation (GDPR).
We collect the following categories of data:
We do not knowingly collect sensitive personal information (health, biometric, political, religious, or trade-union data) and you agree not to upload it.
BAFO for Shopify is the optional “Seen it cheaper?” and “Want our best offer?” feature a merchant can add to the product and cart pages of their Shopify storefront. It processes a narrower, separate set of data about that merchant's own shoppers and orders, in addition to the business data described in Section 1, and it records who installed it. This section sets out exactly what it collects, why, who processes it and when it is deleted.
BAFO for Shopify uses the store’s saved settings: shoppers may submit requests, automatic offers run only where enabled for the store, and merchant fees apply only when disclosed and enabled.
The review-only service is the default. A merchant can later authorise a separate, measured offer experiment for a particular store and for either test or live orders. No measured experiment collects anything until an active certificate records the current owner or admin's agreement to this September 21, 2026 disclosure, the store's current installation, a granted and verified read_orders scope, verified order webhooks and retention job, and an exact active experiment. Live collection also requires Shopify's protected customer data approval. Reinstalling the app, withdrawing that authority, removing the scope, disabling the consenting person, stopping the experiment or switching off collection closes the gate. Nothing collected as test data is later relabelled as live data.
When that experiment is active, BAFO records an eligible exposure and a stable treatment or control assignment on its server before the storefront can show an invitation. The record contains the experiment and policy versions, the surface, currency, item and variant counts, when it became eligible and when its outcome window matures, plus keyed hashes of the cart and, for a logged-in shopper, the Shopify customer ID. It never contains the raw cart token or customer ID. Control assignments, shoppers who ignore an invitation and eligible shoppers who do not buy remain in the denominator; later invitation, selection, issue, application, checkout, payment, cancellation, refund, complaint and repeat-order events are recorded when they occur.
Roles. For BAFO for Shopify, the merchant who installs the app is the data controller of their shoppers' data. MarginShield is the data processor, acting only on the merchant's instructions to run the feature they configured. Full processor terms are in our Data Processing Agreement. BAFO stores nothing a shopper submits from a store until an owner or admin of the store's BAFO workspace has agreed there to our Terms of Service and Data Processing Agreement for that store; until then every request from that store gets a neutral “unavailable” answer. For the data BAFO records about the merchant's own staff when they install or open it (“The merchant's own data”, below), MarginShield is the controller.
When a shopper asks for an offer. BAFO receives an offer request only when a shopper opens the BAFO prompt, answers its questions and submits it. For each request, BAFO stores:
Before a shopper asks, a product page can check whether BAFO is available for the product shown. That check sends only the product and variant IDs, the currency and the quantity, plus the details Shopify adds to every storefront request, and BAFO stores nothing from it (the hosting-provider request logs described above cover it as they do every request).
What the merchant's review team sees. The Requests desk in the merchant's BAFO workspace shows each request with its reason, the competitor and price the shopper gave (for a lower price), the product on the page, its status, when it was made and any hesitation score, the cart it was made from (its item count, its total and, for each line, the product ID, variant ID, quantity and price) and, once it has been reviewed, any internal note the reviewer added. No product name is stored for a cart line, so none is shown. The desk never shows the hashed identifiers described above.
Cart-behaviour signals. On cart pages where the merchant has switched on “Prompt a hesitant cart shopper” (it is off when the BAFO block is added, until the merchant switches it on), and only while Shopify's Customer Privacy API reports that the shopper has allowed analytics, the storefront counts how the shopper uses the cart: how long the cart page has been open and visible, how long since the shopper last interacted with it, how many times a quantity was changed, how many times checkout was selected, whether the pointer left the top of the page (exit intent), and how many times the BAFO pop-up was closed. Each count is capped. The counts are saved in the browser's session storage, which the browser clears when the tab is closed. They are not reused once 30 minutes have passed since they were last saved, and they are deleted as soon as the page finds that analytics consent has been withdrawn. Without analytics consent, nothing is counted, saved or sent. These signals are used for two purposes:
The signals and the score are never used to set, change or influence a price, or to decide whether an offer is made. A shopper who opens BAFO themselves, using the “Seen it cheaper?” or “Want our best offer?” button, can always submit a request, whatever their consent choices.
Orders. In the default review-only mode, the app subscribes to four Shopify order notifications. Shopify sends the order created, order paid and order cancelled notifications only for orders it marks as test orders, so BAFO is never notified that a real order was placed, paid or cancelled. Shopify sends the refund created notification for every refund in the store, because a refund carries no test-order flag of its own that Shopify's filter could use (only each of its payment transactions says whether it was a test, and a refund with no transaction would then never be sent). Shopify trims each notification before sending it: an order notification carries only the order's ID, its test-order flag, its cart token and the time the order was last updated, and a refund notification carries only the ID of the refunded order and the refund's own ID. The last-updated time and the refund's ID are included only so that Shopify does not discard a later notification as a copy of an earlier one; BAFO does not use them. BAFO uses the cart token only to check the link described below, never stores it, and logs none of these fields. BAFO then looks up and stores an order only if all three of these are true:
A refund is stored only if BAFO has already stored an event for the refunded order. For every other order or refund, BAFO acknowledges the notification, makes no call to Shopify and stores nothing from it. If an order it does not store is a test order, BAFO notes only why it was not stored (it had no cart token, no BAFO request was made from its cart, the link could not be checked, or the store's currency is not one BAFO reads order facts in) and when, so that the merchant can see on the BAFO Orders page why it is missing. Each note replaces the previous one, contains no order ID, cart token, customer detail or other part of the notification, and is deleted when the app is uninstalled. BAFO keeps nothing at all about an order that is not a test order.
For a linked order, BAFO reads the order from Shopify, not from the notification, and stores only the order's ID, name (such as #1001), test flag, currency, financial status and last-updated time; its total price and total refunded; and each refund's ID and total. It does not request or store the order's line items. With them it keeps the notification's type, its Shopify event ID, when it arrived and the cart-link hash, and a record that the order is a test order on which no BAFO fee was charged. BAFO never requests or stores the order's customer, email, phone number, address or note.
In an explicitly authorised measured experiment, the same four notifications are reconciled for the certificate's test or live environment. BAFO reads the current cumulative Shopify order after each delivery and stores its immutable environment, order and event IDs, revision time, financial and cancellation status, whether taxes are included and whether the order was edited; cash received, refunded and retained; current subtotal, discount, tax, shipping, duty, additional-fee, tip and total amounts; and refund totals. For each line it stores product and variant IDs, ordered, current and refunded quantities, original amount, Shopify's reported discount allocation, the current price after all discounts and before taxes, and original and refunded tax. For each refund it stores its time and total, refunded lines, quantities, subtotal and tax, restock state, and refunded shipping and shipping tax. It still never requests or stores the order's customer, name, email, phone number, address or note. Duplicate deliveries are recorded once; revisions only move forward, equal-time disagreements are quarantined, and refunds received before a paid notification are reconciled from the cumulative order rather than added twice.
The Performance page reports assigned treatment and control denominators, non-buyers, ignored invitations, paid, cancelled and refunded outcomes, missing links and provisional financial coverage. Retained payment comes from Shopify's net payment amount. Merchant-supplied landed product, payment, fulfilment, delivery, return, operating, support, inventory-recovery and BAFO-fee components remain unknown until an authoritative source supplies them. While any required component or conservation check is missing, contribution stays provisional and BAFO shows no uplift or commercial decision. Complete mature results are descriptive differences per assigned eligible shopper, before and after the BAFO fee; they are not presented as a causal claim.
Each exposure's primary analysis cutoff is fixed when the exposure is first recorded. Shopify's order-created time, rather than when a notification reaches BAFO, decides whether an order belongs to that primary window. A late notification, refund or cancellation for an order created inside the window updates that order. A newly created order outside the cutoff is labelled and retained only as a later relationship fact: it has no primary maturity date and cannot change the measured result. Each cost or fee revision is also bound to the exact cumulative order snapshot it describes. BAFO carries a value across an edit or refund only through an explicit matching revision that names the earlier snapshot; it never silently reuses an old cost.
Why BAFO keeps order facts. They let the merchant see, on the BAFO Orders page, each test order checked out from a cart that made a BAFO request, and whether it was paid, cancelled or refunded, with its total and the amount refunded. They are also how BAFO recognises a later refund or cancellation of the same order after the request itself has been deleted, and how it finds the offer requests made from a customer's order when Shopify asks for that customer's data to be provided or deleted. BAFO keeps them for 400 days after each notification arrived (see “How long we keep it” below): a year and a month, so that the merchant can reconcile a full year of BAFO test orders and their refunds. In a measured experiment they also provide the paid, refunded, cancelled, repeat-order and retained-contribution outcomes for the eligible treatment and control denominator, including eligible shoppers who never buy.
Who processes it. Only these sub-processors, each also listed in Section 7, receive BAFO for Shopify shopper or order data:
No other sub-processor receives BAFO for Shopify shopper or order data: none of it is sent to Stripe, Resend or PostHog. Resend, our email provider, delivers the emails about a customer data request (described below) to the owners and admins of the merchant's MarginShield account, with a copy to MarginShield. They give the store, when the request arrived, its deadline and how many records BAFO holds, and never the customer, an order or anything from those records. BAFO for Shopify never sells shopper data, never shares it with any third party other than the sub-processors listed above, and never uses it to train external foundation models.
Optional learning. When the merchant explicitly enables local learning, BAFO uses that store's eligible experiment assignments, response choices and linked purchase, refund and complete contribution outcomes to evaluate fixed, non-monetary response templates. Shoppers who ignore an invitation or buy nothing remain in the comparison. This learner runs inside MarginShield; it sends no records to an external model provider. It cannot change the merchant's financial permissions. Disabling local learning restores the fixed baseline for future decisions.
Shared learning is off by default and requires separate, expiring owner consent. It combines only permitted, clipped aggregate counts and scores with policy and lineage hashes in MarginShield's database. It does not share customer, cart or order identifiers, raw costs or individual rewards, and the aggregate reader returns no merchant identity. Withdrawal, expiry or an installation-authority change removes the contributed aggregates through the bounded retention process; a deletion count and irreversible lineage receipt remain. A shared candidate still needs that store's own evaluation before activation.
Shopper-linked learning decisions and assignments follow their underlying exposure's retention and customer-deletion rules. Derived strategy and evaluation artifacts retain policy identifiers, hashes, aggregate scores, counts and audit results, without raw shopper or order payloads, until the associated installation or organisation is erased. Turning learning off stops future use; it does not erase the audit history.
How long we keep it. BAFO deletes this data automatically: a scheduled deletion job removes it once it reaches these limits:
These are BAFO's default periods. They can be changed only within fixed limits (31 to 365 days for offer requests and eligibility records, and 90 to 730 days for order and refund events), and automatic deletion cannot be switched off. A deleted record can remain in our database's encrypted backups until they roll off, as set out in Section 6.
The deletion job runs at the start of MarginShield's regular scheduled run, before and separately from the other work in that run, so a failure in that work cannot stop it and a failure in the deletion job cannot stop that work. It is also scheduled on its own, so it does not depend on that run being scheduled. Our API logs every run of the job with how many records of each kind it deleted and whether any step failed, and no identifiers.
Uninstalling, and Shopify's deletion requests.
BAFO's records of these uninstall and compliance notifications contain no customer or order details. Each one identifies only the store, or just the type of notification, and records a test-only flag and a zero fee amount. The record of a customer data request also holds the counts described above, and nothing that identifies the customer; the open request described above is kept separately. The record of a shop-redact request that finds the store reinstalled also holds the time of the reinstall, and nothing else.
The merchant's own data. When someone installs BAFO on a store, or opens it from the store's Shopify admin, BAFO learns from Shopify who they are, and uses that to create their MarginShield account or sign them in. MarginShield is the controller of this data.
We do not use your data to train external foundation models. BAFO's optional local and shared policy learning is limited to the purposes and consent choices described in Section 2. We do not sell or share your data, your competitor observations, or your supplier-funding terms with any third party.
Tenant isolation is enforced by PostgreSQL row-level security, which is enabled and forced on every business-data table. Most carry an org_id column; the rest inherit tenancy through a parent record. Buying-group clean rooms compute aggregates server-side without materialising cross-member joins. Your catalog, costs, rebates, and decisions are visible only to your organisation and the users you grant access to.
We implement encryption in transit (TLS 1.2+) and at rest (AES-256), role-based access control, append-only audit logging, Argon2id password hashing, and incident response. Full posture published at /security.
We retain your data while your account is active. There is no self-service account deletion: to close your account and have its data deleted, email privacy@marginshield.io. You may ask us for a copy of your data within 30 days of closing your account; after that, we delete the account's data from our live systems within 90 days. Our background job queue holds a copy of some data only while a job waits or runs (such as an alert's recipient and text, or a catalogue file being imported) and deletes it automatically, within a day of the job completing, seven days of it failing, or seven days of being queued if it never runs; we also remove your organisation's jobs from it when we delete your account. Your account's audit trail is never deleted: when we delete an account, we replace the names, email addresses and hashes of them, phone numbers and Shopify user IDs in it with “[redacted]”, clear the IP addresses and browser details recorded with it, and keep the organisation and user records it refers to only as suspended placeholders, with the name, email address and password removed. Our own operator log entries about your account are kept with the same values replaced, as is, for a member of a buying group, its clean-room access log (query types and counts only). Encrypted backups roll off within a further 90 days. Some records (billing, audit events tied to legal obligations) may be retained longer where required by law. BAFO for Shopify shopper and order data follows its own retention periods and deletion triggers, set out in Section 2, and an account BAFO for Shopify created when it was installed, which nobody has set a password on, is deleted in the same way automatically once its stores have been uninstalled, as Section 2 describes.
MarginShield uses a limited set of sub-processors to deliver the service: Vercel (web hosting), Railway (application hosting, and the Redis cache and job queue), Neon (database, Asia-Pacific (Singapore) region), Cloudflare (R2 object storage, only when large-file catalogue import is switched on: the catalogue files you upload for import), Stripe (billing), Anthropic (bounded selection among fixed non-monetary BAFO response templates, using the shopper's selected reason and optional bounded clarification, never margin or offer calculation), OpenAI (text embeddings of product names, brands, categories and barcodes, to match products; no personal information), Sentry (error monitoring and performance tracing of our API, with request bodies, cookies, query strings and IP addresses removed), Resend (transactional email), Twilio (the SMS alerts you set up: the recipient's phone number and the alert text), Bland AI (the voice price-discovery calls you start, to a competitor store's business phone number, and their transcripts), Google (its Places service, to find a competitor store's public phone number for such a call), Firecrawl, Scrapfly, Zyte, Jina AI and SerpAPI (retrieval of public competitor web pages and search results for the products you monitor; they receive no personal information), PostHog (product analytics of our web app's page views, when switched on, and an organisation-level usage-limit event from our API; see Section 10). Full list and regional details in the Data Processing Agreement.
Your primary database is hosted in the Asia-Pacific (Singapore) region; application hosting is as listed in the sub-processors in Section 7. Limited transfers occur to the United States and other regions via those sub-processors. Where the GDPR or the UK GDPR applies, the transfer of a customer's personal data to us is governed by the European Commission's Standard Contractual Clauses and the UK Addendum to them, which our Data Processing Agreement incorporates; onward transfers to our sub-processors rely on those clauses or another safeguard the GDPR recognises. A2E Group Pty Ltd is an Australian company and handles your personal information in accordance with the Australian Privacy Principles regardless of the region in which it is processed.
You may access, correct, port, restrict, or delete the personal information we hold about you, and object to processing. You can ask us for a copy of your business data at any time. To exercise rights, email privacy@marginshield.io and we will respond within 30 days. If you are unhappy with how we have handled your data, you may complain to the Office of the Australian Information Commissioner (OAIC).
We use first-party cookies and your browser's local storage for authentication and session management. Signing in keeps your session tokens, and your name, email address and role, in your browser's local storage. Installing or opening BAFO for Shopify also sets short-lived first-party cookies (at most 10 minutes) that hold only a random value, matched on our side against a one-way hash of it, to prove that the browser finishing a sign-in step is the one that started it.
When our product analytics is switched on, PostHog records the pages you view in our web app, each with its web address (with the secret part of a password reset, email verification, invitation or audit claim link removed, and any advertising click identifier masked), and your browser and device type, under a random identifier kept in a first-party cookie and your browser's local storage. Your browser sends PostHog its IP address with each page view, as it does to any site it contacts; our analytics runs only while our PostHog project is set to discard client IP data, so PostHog does not keep it, and we ask PostHog not to look up a location from it. Our API can also send PostHog an event when an organisation reaches its plan's product or competitor limit, identified only by the organisation, with its plan and counts. We never send PostHog your name or email address, we do not identify you to it, and we do not use it for cross-site tracking. It records nothing else: no session recordings, heatmaps, clicks, time on a page or scrolling, page titles, referring pages, screen or window sizes, language, time zone, error reports, performance timings or survey answers. You can opt out by turning on your browser's Do Not Track or Global Privacy Control setting, both of which our analytics honours: with either on, PostHog records nothing from your browser, and with Global Privacy Control on it is not started at all.
MarginShield is a B2B platform not directed at children. We do not knowingly collect personal information from anyone under 18.
We may update this policy as the service evolves. We will tell the registered admin about material changes by email before they take effect. The date at the top of this page changes with every version, and a workspace that agreed to an earlier version for BAFO for Shopify is asked in the app to agree to the new one: until an owner or admin does, the workspace stays open under a notice, and BAFO keeps working under the version agreed earlier.
Privacy questions or requests: privacy@marginshield.io.
A2E Group Pty Ltd, Sydney, Australia.