How Shopvia protects the merchant and the buyer
Written 15 October 2026 for merchants and for the Shopify App Store reviewer. Every claim names the place in our code that makes it true.
What we do
The browser never sets a price
The checkout asks for a quote by sending variant ids and quantities only. The server prices the cart through Shopify, adds the shop's own rules, and signs the result with a secret key. Placing an order re-checks the signature, the session and the quote id before anything is created. An online payment is charged the amount in that signed quote, never an amount sent by the page, and a captured payment that does not match the order is refunded in full. Why it matters: a buyer cannot lower a total by editing a request, and a merchant cannot be charged for an order priced somewhere else.
Where to check: api.v1.sessions.$id.quote.ts, checkout/quote.server.ts, checkout/place.server.ts, payments/attempts.server.ts, payments/confirm.server.ts.
Store configuration stays on the server
Each store's settings are looked up from its own record by a public key. The storefront receives only a short public subset, copied field by field. Fraud lists, billing, messaging settings and secrets are not in it.
Where to check: modules/shop-config/config.ts, api.v1.config.ts, modules/shop-config/config-types.ts.
Buyer contact is handled under a consent line
The phone field sits under a consent line. Contact and address are encrypted when stored. A reminder is queued only when that consent was recorded, and a reply starting with STOP stops it. Checkouts that never became orders are deleted after 30 days.
Where to check: widget/src/drawer/PhoneField.tsx, crypto/cipher.server.ts, jobs/handlers/recovery.ts, messaging/optout.server.ts, jobs/handlers/retention.ts.
Billing is Shopify Billing
Plans are charged by Shopify after the merchant approves them on Shopify's own page. There is no wallet to top up and no per-order credit balance.
Where to check: modules/plan/plan.server.ts, routes/app.plan.tsx.
The store survives the app
The theme's own buy buttons are restored if our checkout has not opened within 4 seconds. A shop that an operator has paused answers new checkouts with 503, and the storefront falls back to the native checkout.
Where to check: widget/src/loader-lib/boot.ts, extensions/ock-theme/blocks/ock-embed.liquid, routes/api.v1.sessions.ts.
Writes are schema-checked on a versioned API
Every buyer-facing checkout and order route lives under /api/v1/ (webhooks are separate and signature-checked). Bodies are parsed with a schema before use and are size-capped. Two small event routes read no fields from the body at all. Order changes by a buyer need a short-lived action token or a one-time code.
Where to check: api.v1.sessions.$id.place.ts, orderpage/actions.server.ts, http/api.ts, orderpage/stepup.server.ts.
How this differs from the common alternative
Some checkout designs compute totals in the browser and send them to the server. Some look a store's configuration up by shop domain and return all of it to any caller. Some re-send the buyer's details on a timer to keep a server copy current. Some bill through a prepaid balance the merchant must keep topped up. We do none of the four.
What we do NOT claim
- No third-party penetration test has been done. A written internal audit exists; we do not claim every finding in it is closed.
- Encryption keys come from the app's environment. Cloud key management is not yet proven on a real key.
- The public config subset is visible to anyone who views the storefront: button style, visibility rules, pixel ids and active offers.
- We do not claim a checkout conversion lift or a fall in returns-to-origin; we have no measurement that would support either.
- Phone numbers typed into a checkout in progress are saved, encrypted, with that checkout until it is deleted. Consent governs reminders, not that save.
- Automated WhatsApp sending is switched off until it is verified with a provider.
- Shopify's written authorisation for an app that replaces Shopify Checkout is not yet in hand, and Shopify App Store approval is not claimed.
- The final price of the paid plan is not decided.
See also the privacy page for what data we process, why, and for how long.