Privacy policy
Last updated: 2026-08-25
This Privacy Policy describes how the Uptest Shopify app ("the App", "we", "us") collects, uses, and stores data when a merchant installs it on a Shopify store. Our goal is to run A/B tests on storefront content while collecting the minimum data required and storing no personally identifiable information (PII) about end customers.
1. What we collect
When the App is installed on a store and an A/B test is active, we collect:
- Anonymous visitor identifier. A 32-character (128-bit) random ID generated client-side and stored in a first-party cookie named
_uptest_vid. Browsers carrying the earlier 16-character format remain compatible during rollout. This ID is not linked to any name, email, IP address, or Shopify customer record on our side. - Consent-withdrawal capability. A separate 32-character random value in
_uptest_rk. While analytics is allowed, our server stores only shop-scoped one-way hashes of this value and the visitor ID. The pair lets us reject delayed pixel, event, or order-attribution traffic after a visitor withdraws analytics consent; the raw capability is not stored server-side. - Per-test variant assignment. A cookie named
_uptest_<testId>per active test, recording which variant the visitor was bucketed into (so the same visitor sees the same variant across page loads). - Active-tests list. A cookie named
_uptest_activelisting the IDs of currently running tests on the shop. This exists so the storefront pixel knows which assignments to forward at checkout. - Page-view events. When a visitor lands on a page that participates in a test, we log: anonymous visitor ID, test ID, variant ID, page path, and a timestamp.
- Conversion events. When a visitor completes a purchase on the store, the merchant's
orders/createwebhook is delivered to our backend. We extract: the visitor ID (carried via the cart's_uptest_visitorattribute), the order ID, the order total, and the order's currency. We use this to attribute revenue to the variant the visitor was bucketed into. - Aggregate consent blind-spot counts. After Shopify confirms that a visitor actively denied analytics consent, the storefront can increment two daily test-level counters: browsers that explicitly declined and treated page views that were not measured. This request contains no visitor ID, capability, variant, page path, order, or revenue. A consent banner that is still waiting for an answer is not counted as a decline.
- Shop-level data from Shopify Admin APIs. Theme template list (read-only), product/page IDs that the merchant chose as test targets, and active subscription state. This data is requested under the scopes declared in the App listing.
2. What we do not collect
We never collect or store:
- Customer names, emails, phone numbers, postal addresses, or any contact details.
- Customer IP addresses (Shopify webhooks include them in the payload — we ignore those fields).
- Payment card data, billing addresses, or any financial information beyond the order total used for revenue attribution.
- Browser fingerprints or any device identifiers beyond the random
_uptest_vidcookie. - Cross-site tracking data — the visitor ID cookie is first-party (set on the merchant's storefront domain) and we do not sync it across stores.
3. Where data is stored
- Database. All event and variant-assignment data is stored in a managed Cloud SQL for PostgreSQL instance hosted on Google Cloud Platform, in the
us-central1region (United States). - Application servers. The App backend runs on Google Cloud Run in the same region.
- Encryption. Data is encrypted at rest by Google Cloud's default encryption and in transit using TLS 1.2+ for all client and webhook traffic.
- Service providers. Google Cloud hosts the application and database; Shopify supplies the commerce platform and consent/pixel infrastructure. Resend is used only for merchant-facing transactional emails and does not receive storefront visitor analytics. We do not ship visitor data to analytics SaaS, ad networks, or marketing tools.
4. Who has access
- The merchant (and any staff with access to the merchant's Shopify Admin) can view the test results, including aggregate event counts and revenue figures, via the App's dashboard.
- The App developer (Ivan Kovalko) has operational access for support and debugging only. Production database access is limited to the App developer and is governed by Google Cloud IAM.
- We do not sell, rent, or share visitor or order data with any third party.
5. Cookies
The App writes the following first-party cookies on the storefront's domain:
| Cookie name | Purpose | Lifetime |
|---|---|---|
_uptest_vid | Sticky anonymous visitor ID for variant pinning | 365 days |
_uptest_rk | Random capability used to authenticate withdrawal of the anonymous ID | 365 days |
_uptest_<testId> | Records the visitor's variant for one test | 365 days |
_uptest_active | Comma-separated list of active test IDs (helper) | 365 days |
_uptest_theme | Theme tests only: which theme variant this visitor sees | 1 day |
These cookies are used to keep the A/B-test experience stable (without them, the same visitor could see different variants on different page loads). They contain no names, contact details, or Shopify customer IDs. Whether a particular assignment cookie is classified as strictly necessary can depend on the merchant's configuration and applicable law.
The App also keeps a few keys in the browser's localStorage / sessionStorage under the same _uptest_ prefix: a cached copy of the test configuration, a cached restrictive consent verdict, the landing-page snapshot for the current visit, an explicit-decline marker, and small de-duplication markers. These local values are not uploaded as records. The landing snapshot is created only when analytics processing is allowed.
6. Consent handling
The storefront loads Shopify's Customer Privacy API and checks analyticsProcessingAllowed() before it sends analytics, writes order-attribution data to the cart, or stores browsing context. The API combines the merchant's privacy settings, visitor region, and registered consent.
- If analytics processing is allowed, the App operates normally.
- If the consent banner is still waiting for an answer, the visitor keeps the assigned variant but no analytics or order attribution is sent; this pending state is not reported as a decline.
- If Shopify reports
currentVisitorConsent().analytics === "no", collection stops, existing cart attribution is cleared on a best-effort basis, the old anonymous ID is revoked server-side when its capability matches, and a new local-only ID is generated. The visitor remains on the same variant. - Analytics collected before withdrawal remains part of the historical test result. Withdrawing consent stops subsequent collection; it is not treated as a request to erase previously collected history. Shopify privacy webhooks and merchant deletion requests provide the separate erasure paths described below.
Our Web Pixel declares analytics permission as required, so Shopify controls whether the pixel is loaded. The backend also rejects a previously revoked anonymous ID on App Proxy analytics, Web Pixel checkout events, and order attribution.
7. GDPR and CCPA
We support Shopify's mandatory privacy webhooks:
customers/data_request— creates an idempotent privacy task for owner review and export of any pseudonymous records linked through the supplied order IDs.customers/redact— deletes linked events, variant assignments, metering sessions, privacy-request records, and the hashed consent identity.shop/redact— fired 48 hours after a merchant uninstalls the App. On receipt, we permanently delete the shop record and all associated tests, variants, events, and daily statistics.
Retention. We retain raw, event-level analytics data (the anonymous visitor identifier, the pages visited, and the resulting order id and order value) for 12 months after the A/B test that produced it has finished, plus the running time of the test itself. A scheduled hourly job deletes it automatically after that, together with the record of which variant each anonymous visitor was shown. What we keep beyond that point is a whole-day statistical rollup (DailyStat) — visitor, add-to-cart, checkout and order counts and revenue totals, per test variant per day — which contains no visitor, customer, or order identifiers and cannot be traced back to an individual; it is retained for the lifetime of the test so historical results stay readable. Aggregate consent-decline counters likewise contain no identifier and are kept with the test. A consent identity that has not been revoked expires 365 days after registration; a revoked identity expires 365 days after withdrawal.
Right to access / deletion. Merchants can request a full export or deletion of their shop's data at any time by emailing the address below. We respond within 30 days.
California residents (CCPA). The categories of information collected are listed in section 1 above. We do not sell personal information.
8. Security
- HTTPS-only transport for all merchant-facing and storefront-facing endpoints.
- Webhook payloads are HMAC-validated using the shared secret issued by Shopify.
- The App requests the scopes needed for App Proxy, read-only product/theme/content discovery, order attribution, Web Pixel management, and approved file workflows. It does not request product-write or theme-write access.
- Database backups are kept on Google Cloud SQL with point-in-time recovery enabled.
9. Children
The App is not directed at children under 13, and we do not knowingly collect data from them. If you believe we have inadvertently collected such data, please contact us so we can delete it.
10. Changes to this policy
We may update this Policy from time to time. Material changes will be reflected by an updated "Last updated" date at the top of this document and, where appropriate, by a notice in the App admin.
11. Contact
For privacy questions, data export, or deletion requests:
Email: support@uptest.app
We respond to privacy requests within 30 days.