Last updated: 22 October 2026. Basis Receivables is a Shopify app operated by Basis Gova Binyan Veyazamut Ltd. (Israel). Contact: support@basis-s.co.il. This is the companion to the Privacy Policy: that document says what data the app handles and why; this one says how it is protected and what happens if something goes wrong.
The app is a read-only report. It holds no write permission on any store, keeps no database, stores no merchant or customer record, and is operated by a single person. The data it reads from Shopify lives in memory for the duration of one request and is then gone. The realistic incident surface is therefore a defect in the app's own code or a compromise of the operator's own accounts — and both are covered below.
The backend is a small Node.js service hosted by Render, Inc. (United States); the dashboard is a static single-page application served by that same service inside the Shopify admin. Platform-level controls — network isolation, TLS termination, patching of the host, physical and network security — are provided and operated by Render under its own security program. There is no database, queue, cache, file store or CDN of our own in the data path.
| Scope | Why the app needs it |
|---|---|
read_orders, read_all_orders | To read unpaid orders and their balances; the extended-history scope so an aging report can reach invoices older than 60 days |
read_companies | To group receivables by the B2B company that owes them |
read_payment_terms | To read due dates from payment terms rather than guessing them |
read_customers (where granted) | For unpaid invoices raised from draft orders that are not linked to a B2B Company, on the dashboard's default list only: each order's customer ID and first and last name, to group and label those invoices and to address a reminder draft. Never an email, phone number or address, and never when "Include every unpaid order" is turned on (see the Privacy Policy) |
read_draft_orders (where granted) | To list draft orders whose invoice was sent and that are not orders yet: each draft's number, status, dates, currency, total and payment terms, and whether it has become an order. No customer, email, phone number, address or payment link is read (see the Privacy Policy) |
All scopes are read-only. The app cannot change an order, a price, a customer or a setting, even if it were compromised. Any change to this scope set is surfaced by Shopify to the merchant as a permission change requiring consent, so it can never be silent. The scopes the app holds today are listed on its App Store listing and in Shopify's install screen.
shop/redact webhook) or the service restarts, after which it is re-obtained from Shopify through token exchange. The second exists only if Shopify has declined to serve customer names for the store: a marker holding the store's domain and an expiry time 30 minutes ahead, so the app does not ask again on every load. Nothing sweeps it on a timer: it is removed the first time the dashboard loads its default list for the store after that time (a load with "Include every unpaid order" turned on neither reads nor sets it), when a new token is exchanged for the store, on the shop/redact webhook, when the service restarts, or, if more than 5,000 stores are marked at once, when it is the oldest mark. A store that does not load that default list again therefore keeps its marker until one of the other events. The third exists only if Shopify has declined to serve draft orders for the store (it has not granted read_draft_orders): a marker of the same kind, the store's domain and an expiry time 30 minutes ahead, so the app does not ask for draft orders again on every load. It is checked, and set when Shopify declines, on any dashboard load that reads the store's unpaid orders successfully, with or without "Include every unpaid order" turned on. Nothing sweeps it on a timer either: it is removed the first time such a load happens for the store after that time, when a new token is exchanged for the store, on the shop/redact webhook, when the service restarts, or, if more than 5,000 stores carry this marker at once, when it is the oldest of them. A store whose dashboard is not loaded again therefore keeps this marker until one of the other events.All traffic is encrypted with TLS: browser to service, service to the Shopify Admin API, and Shopify's webhook deliveries to the service. Every request from the embedded dashboard carries a Shopify session token that is verified server-side (signature, audience, expiry) before anything is read; webhook deliveries are verified with Shopify's HMAC signature and rejected otherwise, and a verified delivery is acted on only for the store named inside its signed payload.
Development and testing use Shopify development stores and a local environment; the production service serves merchant stores only. Because no merchant data is stored, no production data is ever copied into a test environment — there is nothing to copy. Automated tests run against fixture data that is invented for the purpose.
The app's data-loss strategy is not to hold data: no exports, no reports saved server-side, no mail sent by the app (reminder drafts are copied by the merchant into their own mail client), no analytics or tracking service. Secrets (the app's API secret) exist only in the hosting provider's environment configuration and are never committed to source control.
Every API request is logged on the hosting provider's log stream as a structured line: the store domain, the outcome, counts (invoices, companies) and timing, the Shopify user ID of the staff member who made it (a number, not a name or email) and the IP address it came from. A refused request (an invalid session token or webhook signature, a rate limit, or a full service) is logged with its IP address and browser user-agent string; rate-limit and capacity refusals at most once a minute per source, so a flood cannot flood the log. These lines contain no customer names, emails, addresses, order contents or tokens, and they are what would be used to reconstruct who accessed what during an investigation. Logs roll off automatically under the provider's retention.
The app is developed in a version-controlled repository with an automated test suite. The behaviours that matter for security — token verification, HMAC verification on webhooks, the read-only scope set, the customer fields the API queries may ask for (a customer's ID and first and last name only — never an email, phone number or address) — are covered by tests. The whole suite runs automatically on every change and reports a failure within minutes; a change that fails it is fixed or reverted. The suite does not hold a deploy back: deploys are automatic from the repository's default branch, so a bad deploy is rolled back by reverting the change, which deploys the same way.
If you believe you have found a security issue, write to support@basis-s.co.il with the subject line Security report: Basis Receivables, including the steps to reproduce and the store type you tested against. We acknowledge every report, treat a confirmed issue as the first priority, and tell you what we found and what we changed. Please test only against stores you own, and give us the opportunity to fix an issue before disclosing it publicly.
An incident is any event in which merchant or customer data could have been read or altered by someone not entitled to it, or in which the app's credentials could have been exposed. The response is:
If this policy changes, the "Last updated" date above changes with it. A change to what the app can read would also be a scope change, which Shopify surfaces to every merchant for consent.
Basis Ventures — Basis Gova Binyan Veyazamut Ltd., a company registered in Israel.
support@basis-s.co.il