#Intake B2B: Privacy Policy
Last updated: 2026-05-16
Roles. Throughout this policy, "the app" refers to the Intake B2B Wholesale Approval app and its operator (the legal entity that publishes and runs the service). "The merchant" is the Shopify store owner who installs the app. "The applicant" or "buyer" is the individual or business that submits the wholesale application form.
The app acts as a data controller for data the merchant provides to set up and operate the app on their store (notification email, form configuration, install record). The app acts as a data processor on the merchant's behalf for applicant-submitted data and for any of the merchant's customer data accessed via the Shopify Admin API; the merchant remains the data controller for that information and instructs the app via its in-admin settings.
#1. Data we collect
The app processes two categories of data on behalf of the merchant:
- Applicant-provided data submitted through the buyer-facing wholesale application form (business name, contact details, address, VAT / tax ID, optional free-text fields, and optional document uploads such as resale certificates or business licenses).
- Merchant configuration (notification email, form-field settings, document refresh period, approval-default tags, etc.) and a per-shop install record.
We do not collect analytics, tracking cookies, or third-party ad IDs.
#2. How we use your data (purposes of processing)
We use the data described in §1 only for the purposes the merchant has configured the app to perform. Specifically:
- Operating the wholesale-application workflow. Applicant submissions are stored, displayed in the merchant's Shopify admin, and acted on by the merchant (approve, request more information, reject). On approval the app calls Shopify's Admin API to create or link a Company, a Company Contact, and (where the merchant configured them) a B2B catalog assignment, payment terms, and customer tags.
- Notifying merchants and applicants. The app sends transactional email via Resend: to merchants when a new application arrives or is resubmitted, and to applicants when their application is approved, rejected, when the merchant requests more information, or when the application is auto-closed by the retention sweep.
- Document handling. Applicant documents are uploaded to a private Cloudflare R2 bucket so the merchant can review them during approval.
- Retention enforcement. A daily background sweep auto-closes long-stale applications and permanently deletes rejected applications past their retention window (see §6).
- Compliance with Shopify's mandatory webhooks. We respond to
customers/data_request,customers/redact, andshop/redactwebhooks (see §8). - Security and abuse prevention. Per-IP rate limiting, duplicate submission throttling, and a server-side honeypot field protect the buyer-facing form from automated abuse. Aggregate sanitized log lines are written for retention sweeps and webhook deliveries; we do not log applicant emails, raw payloads, R2 keys, or signed URLs.
We do not use applicant or merchant data for advertising, profiling, analytics, or model training.
#3. Legal basis for processing (GDPR Article 6)
Our lawful bases for processing personal data depend on the role we occupy for that data and the processing activity in question:
For merchant configuration data (the merchant's notification email, form settings, install record — the app is the controller):
- Article 6(1)(b) — Performance of a contract. Processing necessary to deliver the app to the merchant under our App Store terms (account setup, billing, sending the merchant operational notifications, responding to support requests).
- Article 6(1)(c) — Legal obligation. Where applicable, retaining records required by tax, audit, or platform-compliance obligations.
- Article 6(1)(f) — Legitimate interests. Operating and securing the service, preventing abuse of the public buyer-facing form, monitoring for fraud, and improving reliability. Our interest is balanced against the limited and operational nature of the data involved.
For applicant data and any merchant-customer data accessed via the Shopify Admin API (the merchant is the controller; the app is the processor):
The merchant determines the lawful basis for processing this data and documents it in their own privacy policy. The app processes such data only on the merchant's documented instructions, expressed through the app's settings and the actions the merchant takes in the admin (approve, reject, request information, retry sync, retry assignments, update notes / address). Common bases the merchant may rely on for wholesale-onboarding processing include:
- Article 6(1)(b) — pre-contractual measures requested by the applicant (the wholesale relationship the applicant is applying to enter).
- Article 6(1)(f) — the merchant's legitimate interest in vetting prospective wholesale buyers.
If the applicant withdraws or the merchant identifies a different basis, the merchant should communicate that through their own privacy notice and, where appropriate, instruct the app to delete the data via the admin "Reject" action or by initiating a Shopify customer redaction.
#4. Where applicant documents are stored
Applicant document uploads (resale certificates, business licenses, tax documents, and any other files the applicant attaches to the form) are stored in a private Cloudflare R2 bucket. The bucket is not publicly accessible. No public object ACL, no public bucket policy, no published index.
Objects are encrypted at rest using Cloudflare R2's default server-side encryption.
Access to a document is granted through short-lived signed URLs (15-minute expiry) generated on demand when an authenticated merchant views the application detail page in the Shopify admin. The signed URL is not cached, not persisted, and not logged. A merchant who returns to the admin page after the URL expires receives a freshly generated URL.
Applicants themselves do not receive download URLs — the app never surfaces signed URLs on the buyer-facing pages (initial submission, resubmission, or confirmation).
#5. Where other data is stored
Non-document data (application records, status events, custom field values, merchant configuration) is stored in the application's primary PostgreSQL database. Backups and access controls are managed by the database host (e.g., Railway).
#6. Retention
Rejected applications. Applications that are rejected are retained
for 60 days after rejection and then permanently deleted, including any
uploaded documents. This retention window is enforced by a scheduled
daily sweep that runs against the production database. Merchants can
adjust the retention window for their deployment by setting the
REJECTED_RETENTION_DAYS environment variable on the cron service; the
default of 60 days is what the app ships with.
Uninstall cleanup. When a merchant uninstalls the app, session data
is cleared immediately so the app stops attempting to use the revoked
offline access token. Application data, documents, and merchant
configuration are retained for approximately 48 hours per Shopify's
GDPR contract — this window allows a merchant who reinstalls within
that period to pick up where they left off without losing their
application history. After the window elapses, Shopify delivers a
shop/redact webhook and the app deletes all applications, uploaded
documents, merchant configuration, and any remaining sessions
associated with that shop. R2 objects are removed before the database
rows so a retry leaves nothing behind.
Customer-initiated redaction (GDPR). On customers/redact, all
applications and uploaded documents associated with the requested
customer email are deleted from both R2 and the database.
Inactivity-based closure of in-progress applications. To keep
applicant records from accumulating indefinitely, the same daily sweep
that purges old rejected applications also closes applications that
have sat in an in-progress state past a reasonable review window. A
closed application moves to the rejected status, is marked internally
as an auto-closure so the merchant can distinguish it from a manual
rejection, and the applicant receives a neutral closure notification
inviting them to reapply or reach out. Closed applications then follow
the same 60-day rejected-retention clock described above before being
permanently deleted.
The inactivity windows are:
- Pending applications (submitted but not yet reviewed by the merchant) are closed 45 days after submission.
- Applications awaiting more information from the applicant are closed 14 days after the applicant's resubmission window expires (the resubmission window itself is 7 days, so this is effectively 21 days after the merchant requested the additional information).
- Applications that encountered a sync error during approval are closed 45 days after entering the error state if they have not been manually retried or resolved by the merchant.
After closure, the standard 60-day rejected-retention window applies before the record and any uploaded documents are permanently deleted. Merchants can disable the applicant-facing closure email by turning off applicant notifications in the app's settings; the application will still be closed, but no email will be sent.
#7. Third-party subprocessors
- Shopify — app installation, authentication, and the merchant's store data (companies, company locations, customers, tag assignments).
- Cloudflare R2 — private document storage, encryption at rest.
- Resend — transactional email (notifications to merchants and applicants).
- Your database host (e.g., Railway) — PostgreSQL for application records and merchant configuration.
The list above is exhaustive. The app does not integrate with any
third-party analytics, error-tracking, advertising, or marketing
platform. The only outbound network call the app server makes — outside
of the embedded Shopify Admin API client and the AWS S3 SDK call to
Cloudflare R2 — is a single HTTPS POST to api.resend.com/emails to
send a transactional email.
#8. Compliance webhooks
We implement all three Shopify-mandated compliance topics:
customers/data_request: we export the applicant's stored data and document metadata (filename, MIME type, size, upload date) via email to the merchant's configured notification email address. If the merchant has not configured a notification email, the export is skipped and the event is logged for operator review; we do not fall back to any other recipient. We intentionally do not include short-lived download URLs in the export payload because they would expire before most recipients could use them, and we do not issue long-lived URLs because that would extend a private credential beyond the app. If document content itself is required to satisfy the request, the merchant can retrieve it through the admin UI at the time of the request. Note that document content and application records are permanently removed when a correspondingcustomers/redactwebhook is received from Shopify (approximately 30 days after a customer redaction is initiated), so any out-of-band retrieval must happen before that window closes.customers/redact: applicable data is removed.shop/redact: on the Shopify-signalled redaction schedule, the merchant's shop data is removed.
#9. Your data protection rights (GDPR)
If you are an individual whose personal data is processed by the app — either as a merchant operating the app, or as an applicant submitting the wholesale form on a merchant's storefront — you have the following rights under the EU General Data Protection Regulation and the UK GDPR:
- Right of access (Article 15). You can request a copy of the personal data we hold about you and information about how it is processed.
- Right to rectification (Article 16). You can ask us to correct inaccurate or incomplete personal data.
- Right to erasure / "right to be forgotten" (Article 17). You can request deletion of your personal data in the circumstances set out in the GDPR.
- Right to restriction of processing (Article 18). You can ask us to limit how we process your data while a request is being resolved or in other cases provided by law.
- Right to data portability (Article 20). You can ask to receive the personal data you provided to us in a structured, commonly used machine-readable format.
- Right to object (Article 21). You can object to processing based on legitimate interests (Article 6(1)(f)) or for direct marketing purposes; we do not engage in direct marketing using your data.
- Right to withdraw consent. Where processing is based on consent, you can withdraw it at any time without affecting the lawfulness of prior processing.
- Right to lodge a complaint with a supervisory authority. You can complain to your local data protection authority. In the EU and EEA this is typically your member-state data protection authority; in the United Kingdom this is the Information Commissioner's Office (ICO); other jurisdictions have equivalent regulators.
Where to send a request. Because the merchant is the data controller for applicant data, requests by applicants about their wholesale-application information should be addressed to the merchant operating the storefront in the first instance — the merchant's own privacy notice will list a contact. The app will assist the merchant in fulfilling such requests on instruction (for example, by exporting or deleting the applicant's records on the merchant's behalf).
For data the app holds as a controller — i.e., your merchant account configuration and install record — please contact us directly using the details in §10.
#10. How to exercise your rights / contact us
To exercise any of the rights listed in §9, contact us at:
Privacy contact:
[email protected]
When you contact us, please include:
- Your name and the email address you used to interact with the app (for merchants: the email associated with your Shopify store; for applicants: the email you submitted on the wholesale form).
- The shop domain of the merchant whose form you submitted (if you are an applicant).
- A short description of your request and which right you are exercising (access, rectification, erasure, etc.).
- For applicants: please first contact the merchant whose storefront you applied through. If you cannot reach the merchant or your request has not been resolved, contact us using the address above and we will coordinate with the merchant.
We will acknowledge your request without undue delay and respond substantively within 30 days of receipt, in line with GDPR Article 12(3). If your request is complex or you have made multiple requests, we may extend this period by up to a further two months and will notify you of the extension and the reasons within the initial 30-day window.
We may need to verify your identity before responding to a request to ensure we are not disclosing your data to someone else. We will only ask for the minimum information necessary to do so.
#11. Cookies and tracking
The app does not set advertising or tracking cookies, does not use third-party analytics platforms (no Google Analytics, Segment, Mixpanel, PostHog, Amplitude, Heap, or similar), and does not use any cross-site tracking technologies. The app is embedded inside the Shopify admin and relies only on first-party session cookies set by Shopify for authentication; these cookies are governed by Shopify's own privacy and cookie policy.
The buyer-facing wholesale-application form is a server-rendered HTML page served via Shopify's App Proxy. It does not load third-party JavaScript, does not set any persistent cookies of its own, and does not beacon to any analytics endpoint.
#12. Security measures
We apply technical and organisational controls proportionate to the operational nature of the data we process:
- Access control. Production data access is limited to the operator personnel who need it to run the service. Database and storage credentials are scoped per environment and not embedded in client-side code.
- Least privilege for Shopify access. The app requests only the minimum Shopify Admin API scopes required to deliver the documented features (companies, customers, products for catalog assignment, app proxy). Each scope is exercised by a specific feature in the codebase.
- Encryption in transit. All communication with Shopify, Cloudflare R2, Resend, and the application database is secured with TLS.
- Encryption at rest. Documents stored in Cloudflare R2 use Cloudflare's default server-side encryption. The PostgreSQL database uses encryption at rest provided by the database host.
- Logging hygiene. Application logs are sanitized to avoid applicant emails, raw payloads, R2 object keys, and signed URLs.
- Abuse controls. The public buyer-facing form is protected by Shopify App Proxy signature verification, per-IP rate limiting, a duplicate-submission throttle, and a server-side honeypot field.
No system is perfectly secure. We work to keep the controls above effective, and we will notify affected parties of any qualifying data breach per §15.
#13. GDPR compliance
We process personal data in accordance with the EU General Data Protection Regulation and the UK GDPR. As described above:
- We identify the legal basis for each processing activity (§3).
- We respect each of the data-subject rights enumerated in §9 and provide a clear contact channel for exercising them (§10).
- We restrict access to personal data to the operator personnel and subprocessors who need it to operate the service.
- We respond to Shopify's mandatory compliance webhooks
(
customers/data_request,customers/redact,shop/redact) with the actual deletion or export behaviour described in §8. - We notify supervisory authorities and affected individuals of qualifying data breaches per §15.
- We retain personal data only for the periods set out in §6.
International transfers of personal data (for example, to subprocessors that operate outside the European Economic Area) are governed by the Standard Contractual Clauses or an equivalent transfer mechanism agreed with the relevant subprocessor.
#14. California residents (CCPA / CPRA)
If you are a California resident, the California Consumer Privacy Act (CCPA), as amended by the California Privacy Rights Act (CPRA), gives you the following rights with respect to personal information collected about you:
- Right to know what personal information has been collected, the categories of sources, the purposes for collecting it, and the categories of third parties to whom it has been disclosed.
- Right to delete personal information collected from you, subject to certain statutory exceptions.
- Right to correct inaccurate personal information.
- Right to opt out of "sale" or "sharing" of personal information. The app does not sell or share personal information for cross-context behavioural advertising or for monetary or other valuable consideration. There is no opt-out mechanism because there is no sale or sharing to opt out of.
- Right to limit use of sensitive personal information. We do not use sensitive personal information for purposes beyond those permitted by California Civil Code §1798.121.
- Right to non-discrimination for exercising your rights — we will not deny service, charge a different price, or provide a different level of service because you exercised a CCPA right.
To submit a verifiable consumer request, contact us using the details in §10. We will verify your request by matching the email address you provide against the email on file in the application or merchant configuration record. We will respond within the timeframes required by the CCPA (typically 45 days, with one 45-day extension where permitted).
Service-provider role. With respect to applicant data submitted through a merchant's wholesale form, the app generally acts as a "service provider" to the merchant under the CCPA, processing the applicant's personal information solely on the merchant's behalf and under written terms with the merchant. Verifiable consumer requests about applicant data should be addressed to the merchant in the first instance; we will assist the merchant in responding.
#15. Data breach notification
In the event of a personal data breach affecting data we control or process, we will:
- Notify the relevant supervisory authority within 72 hours of becoming aware of the breach where required under GDPR Article 33, unless the breach is unlikely to result in a risk to the rights and freedoms of natural persons.
- Notify affected individuals without undue delay by email when the breach is likely to result in a high risk to their rights and freedoms, in line with GDPR Article 34.
- Notify affected merchants (the data controllers for applicant data) without undue delay so the merchant can satisfy their own notification obligations to applicants and to their own supervisory authority.
The notification will include, as far as reasonably possible, the nature of the breach (categories and approximate number of individuals and records affected), the contact point from whom more information can be obtained, the likely consequences, and the measures taken or proposed to address the breach and mitigate adverse effects.
#16. Children's data
The app is a business-to-business product designed for wholesale onboarding workflows. It is not directed at children, and we do not knowingly collect personal information from children under the age of 16 (the GDPR threshold for parental consent in many member states) or under the age of 13 (the COPPA threshold in the United States).
If we become aware that personal information about a child in either of these categories has been provided to the app — for example, because a child submitted the buyer-facing wholesale form — we will delete that information promptly. A parent or legal guardian who believes their child's personal information has been provided to the app can contact us using the details in §10 to request deletion.
#17. Changes to this policy
We maintain auditable version history for this policy. Material changes (new subprocessors, retention-timeline updates, new data categories) are recorded so the history of updates remains reviewable.
When we add a new subprocessor or change the role of an existing one, we update the subprocessor list in §7 and update the "Last updated" date at the top of this policy. Material changes remain part of that auditable policy history.