Privacy Policy — Obnold Subscription

Last updated: 3 August 2026

App name: Obnold Subscription
Operator: Obnold
Contact for privacy requests: support@obnold.com
Published policy URL: https://subscriptions.obnold.app/privacy

This Privacy Policy describes how Obnold Subscription (the “App”) handles information when a Shopify merchant installs and uses the App, and when that merchant’s customers interact with subscription features powered by the App. It is based on the App’s actual implemented behavior.

Shopify also processes data under Shopify’s own policies when you use Shopify’s platform, checkout, and billing systems. This policy covers the App’s processing only.


1. Who this policy applies to

  • Merchants — Shopify store owners and staff who install and use the App in Shopify Admin.
  • Customers — end customers of a merchant’s store whose subscription-related information is stored or processed by the App so the merchant can manage subscriptions, notifications, and self-service portal actions.

2. Information we collect

2.1 Merchant information

When a merchant installs or uses the App, we store shop-level and account information needed to run the App, including:

  • Shop identity — the shop’s myshopify domain (and related shop identifiers received from Shopify).
  • Authentication / session data — OAuth access tokens (and related session fields such as scope, expiry, and optional online-user fields Shopify provides, for example staff name and email when an online session is used). These are stored so the App can call the Shopify Admin API on the merchant’s behalf.
  • App settings — onboarding status, whether the customer portal and notifications are marked configured, soft-uninstall timestamp, storefront widget template choice, and widget configuration (labels, colors, and related display settings).
  • Subscription plans configured by the merchant — plan name, billing frequency, discounts, trial days, price used for recurring-revenue calculations, product restrictions, status, and linked Shopify selling-plan identifiers.
  • Automation settings — merchant-chosen rules (for example win-back, auto-pause after failed payments, loyalty discount, and skip limits).
  • Notification templates — subject, body, type, and enabled/disabled state for transactional emails the App can send on the merchant’s behalf.
  • Merchant app billing state — the merchant’s App plan tier and trial/billing status as maintained by the App (for example free/starter/growth/scale, trial dates, and whether a trial has already been used). Charge approval and payment of App fees are handled through Shopify’s App Billing flows; the App stores a local record of plan/status for enforcement and display.
  • Operational logs — merchant action logs (for example plan or widget changes), personal data access logs (who accessed customer-data surfaces — identifiers only, never name/email values), automation logs, and (when webhook processing fails) sanitized webhook event records used for retry. Failed-webhook storage redacts common personal fields (such as email, phone, and name keys) before saving a payload copy.
  • Short-lived widget preview sessions — temporary draft widget configuration used in theme/editor preview, with an expiry time.

2.2 Customer information

For customers who have subscription contracts managed through the App, we store:

  • Shopify customer ID (including GraphQL GID form when provided).
  • Customer name and customer email (when available from Shopify subscription/customer data).
  • Subscription details — status, plan association, next billing date, pause/cancel timestamps, cancellation reason (when provided), Shopify Subscription Contract ID, consecutive failed-payment and skip counters, and a flag used when skip limits are exceeded.
  • Related order records linked to subscriptions — billing cycle number, amount, currency, payment status, retry metadata, and Shopify Order GID when known. These records do not separately store customer name or email; name/email live on the subscription record.
  • Subscription audit events — non-payment narrative events such as status or billing-date changes.
  • Notification delivery logs — notification type, send status, timestamp, optional error message, and recipient email address used for the send.

Payment card data: Customer payment methods and card charges for subscription orders are processed by Shopify (and the merchant’s payment providers), not by the App as a card processor. The App’s database schema includes an optional paymentMethodLast4 field for display, but the App’s current subscription sync path sets this field to null and does not store full card numbers or raw payment credentials.

Customer Account portal: The customer-facing portal displays plan name, subscription status, billing frequency, next billing date, and whether skipping is blocked (isFlagged). It does not display the customer’s name or email from the App’s database in the portal payload. Portal actions (pause, resume, skip, cancel) authenticate with a Shopify session token, update the subscription via Shopify’s APIs where applicable, then sync local records. Cancel may collect a reason category chosen by the customer.

2.3 Information we do not collect (as implemented)

  • The App does not integrate third-party product analytics or error-tracking SDKs (for example Sentry, Mixpanel, or similar) in the application code reviewed for this policy.
  • The theme App Extension does not set App-owned cookies or collect customer name/email in the browser for App storage. It works with product/selling-plan data already on the storefront and fetches public plan options for a product through the App’s storefront/app-proxy endpoint.
  • Runtime email sending uses SMTP via Nodemailer and environment variables (SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASS, SMTP_FROM_NAME, SMTP_FROM_EMAIL). The App does not call a Resend SDK.

3. Shopify data the App can access (OAuth scopes)

The App requests these Shopify Admin API scopes. In plain language:

Scope What it allows the App to do in practice
read_customers Read customer information needed to associate subscription contracts with a customer (for example name and email used in Admin lists and notifications).
read_orders Read order information related to subscription billing/orders the App syncs and displays.
write_discounts Create or manage discount codes used by automations (for example win-back or loyalty flows).
write_own_subscription_contracts Create and update subscription contracts owned by the App (pause, resume, cancel, skip, and related contract sync).
write_products Write product-related data required for selling-plan / storefront subscription setup (including metafield-backed widget configuration).

The App uses Shopify session authentication for the embedded Admin experience and verifies webhooks through Shopify’s webhook authentication.


4. Why we collect data and how we use it

We use the information above only to operate subscription features the App actually provides:

  • Authenticate the merchant and call Shopify APIs securely.
  • Create and sync subscription plans and selling plans with Shopify checkout.
  • Record and display subscriptions and related orders in the merchant Admin UI.
  • Power merchant automations (auto-pause, skip limits, win-back, loyalty discounts).
  • Send transactional emails when templates are enabled (subscription confirmation, renewal reminder, failed payment, and cancellation confirmation). When win-back automation runs on cancellation, the cancellation email may include a generated discount code via the {winback_code} placeholder.
  • Provide the Customer Account subscription portal for self-service pause, resume, skip, and cancel.
  • Render the storefront subscription widget (theme extension + app proxy plan lookup).
  • Show aggregate analytics in Admin (MRR trends, plan performance, cohort retention) derived from subscription and plan records without selecting customer name or email in those analytics queries.
  • Enforce merchant App billing/trial state using local billing records reconciled with Shopify App Subscriptions where configured.
  • Meet Shopify mandatory compliance webhooks (customer data request, customer redact, shop redact).
  • Retry failed non-compliance webhooks using sanitized stored payloads.
  • Run scheduled cleanup of expired widget preview sessions, aged resolved/dead-letter webhook events, and aged notification logs.

We do not sell customer or merchant personal information.

4.1 Consent and merchant responsibility

Shopify merchants are the controllers of their customer relationships. This App processes subscription operational data to provide the features above under the merchant’s Shopify install and scopes. The App includes a consent-evaluation helper (evaluateProcessingConsent) used for purpose labeling and gating (for example skipping transactional email when templates are disabled or the shop is soft-uninstalled).

Limitation (honest): The App does not integrate Shopify’s Customer Privacy / customer consent APIs and does not store per-customer marketing consent flags. Merchants remain responsible for obtaining and honoring any customer consent required by law or Shopify policy for their storefront and marketing practices. Portal and Admin actions authenticate the actor; they do not substitute for the merchant’s consent program.


5. Webhooks and data that flow through the App

5.1 Operational webhooks

The App subscribes to Shopify topics including:

  • subscription_contracts/create, subscription_contracts/update
  • subscription_contracts/activate, subscription_contracts/cancel, subscription_contracts/pause, subscription_contracts/expire, subscription_contracts/fail
  • orders/create
  • app/uninstalled
  • app/scopes_update
  • app_subscriptions/update (subscribed; handler calls syncMerchantBillingFromAdmin to reconcile MerchantBilling, with failure capture + non-2xx so Shopify can retry)

These carry shop, contract, order, and related identifiers used to keep local subscription/order state in sync with Shopify (except where a handler is intentionally acknowledgment-only, as noted above). When a processing failure is persisted for retry, personal fields commonly present on payloads are redacted before storage.

5.2 Mandatory compliance webhooks

The App handles:

  • customers/data_request
  • customers/redact
  • shop/redact

Behavior is described in Section 9.


6. Billing data: App fees vs customer subscription payments

Merchant App billing (what the merchant pays for the App): Plan selection and charge confirmation go through Shopify’s Billing / App Subscription APIs. The App stores a local MerchantBilling record (plan tier, status, trial timestamps, hasUsedTrial, optional Shopify billing identifier). Shopify remains the system that processes the merchant’s payment for the App.

Customer subscription payments (what store customers pay the merchant): Checkout, payment methods, and charge attempts are handled by Shopify. The App stores subscription status, next billing date, order amounts/statuses linked to subscriptions, and failure counters used for automations. The App does not act as the card network or store full payment credentials.


7. Storefront widget and Customer Account portal

7.1 Theme App Extension (subscription selector / widget)

On product pages where the merchant adds the extension, the widget reads product, variant, selling-plan, and merchant widget-config data from the Liquid/storefront context (including App metafields). It may request plan options for a product from the App over the configured app proxy (/apps/obnold → App /api/storefront). It does not collect customer account credentials for the App, and the extension assets do not set App-owned cookies.

7.2 Customer Account extension (subscription portal)

Logged-in customers can view and manage their subscriptions through the portal extension. The portal calls the App backend with a Shopify Customer Account session token. Displayed fields and write actions are limited to those described in Section 2.2.


8. Analytics and notifications

8.1 Analytics

Merchant Admin analytics are aggregate: monthly recurring revenue trends, new/churned subscriber counts, plan performance, and cohort retention percentages. Queries used for these views select subscription identifiers, status, and dates plus plan price/frequency/name — not customer name or email.

8.2 Notifications

When enabled by the merchant and when SMTP is configured on the App hosting environment, the App sends transactional email to the customer’s email address for these template types: subscription confirmation, renewal reminder, failed payment, and cancellation confirmation. Message content is based on merchant-edited templates and placeholders such as customer name, plan name, next billing date, amount, shop name, and (when a win-back code was generated on cancellation) that discount code. Delivery attempts are logged (type, status, recipient, errors). Sends are skipped when the shop is soft-uninstalled or the template is disabled.

Email delivery uses the operator-configured SMTP service (Nodemailer). The specific SMTP provider is determined by the operator’s SMTP_* configuration, not hard-coded in application logic.


9. GDPR / privacy rights and how requests are handled

9.1 How customers and merchants can exercise rights

  • Customers should typically start with the merchant and/or Shopify’s customer privacy tools. Shopify will deliver mandatory compliance webhooks to the App when applicable.
  • Merchants (and customers who need help from the App operator) may contact support@obnold.com to request access, correction, or deletion assistance for data the App stores.

Shopify’s mandatory webhooks are the primary automated path for customer data request and erasure against App-stored data.

9.2 customers/data_request (what the App actually does)

When Shopify sends customers/data_request, the App:

  1. Matches local subscriptions for that shop by customer email and/or customer ID (numeric and GID forms).
  2. Loads related notification logs (by subscription IDs and/or recipient email), limited to the most recent 100 notification log rows.
  3. Builds an export bundle including customer identifiers from the webhook payload, matching subscription fields (id, status, customerId, customerName, customerEmail, plan name, created/cancelled timestamps), and notification log metadata (id, type, status, recipient, sentAt, subscriptionId).
  4. Persists that export in a merchant action log entry (gdpr_customers_data_request) for fulfillment.
  5. Responds to Shopify with HTTP 200.
  6. Logs only non-identifying metadata (export id and counts) — not the export’s personal content.

Important limitation (verified in code): The App stores the export for merchant fulfillment; it does not currently provide a merchant Admin UI or automated email that delivers the export file to the customer. Merchants who receive a Shopify data request should contact support@obnold.com if they need help retrieving the stored export during the fulfillment window.

9.3 customers/redact (what the App actually deletes/anonymizes)

When Shopify sends customers/redact, for matching subscriptions the App:

  • Clears customerName and customerEmail.
  • Sets paymentMethodLast4 to null.
  • Replaces customerId with a non-identifying placeholder of the form redacted:{subscriptionId}.
  • Clears recipient on matching notification logs.

Subscription rows and related non-identifying operational history are retained after this anonymization (they are not hard-deleted by this webhook).

9.4 Shop uninstall vs shop/redact

On app/uninstalled (soft uninstall): The App deletes stored OAuth sessions for the shop, records uninstalledAt on shop settings, and disables automation toggles. It does not immediately delete plans, subscriptions, orders, notification templates/logs, or automation logs. This preserves the ability to honor customer data-request and customer-redact webhooks during Shopify’s post-uninstall compliance window.

On reinstall (after a soft uninstall): The App performs a fresh-install reset: it deletes operational shop data (subscriptions and cascaded orders/audit events, plans, notification logs/templates, automation settings/logs, widget preview sessions), clears related Shopify selling-plan groups when possible, resets widget settings/metafields to defaults, and clears the uninstall marker. The newly issued OAuth session is kept. Merchant App billing records are preserved so a previously used trial is not re-granted (hasUsedTrial).

On shop/redact: After Shopify’s uninstall redact timing, the App erases remaining shop-scoped data, including operational data, merchant billing records, webhook event rows, merchant action logs (including any stored data-request exports), shop settings, and sessions — unless an install probe shows the App is still verifiably installed (for example after reinstall), in which case erasure is skipped. If the install probe cannot be completed, the App proceeds with erasure.

Theme extension block placement on a merchant’s theme is managed in Shopify and is not removed by the App’s reinstall cleanup (only App-owned selling plans and widget metafields are reset by that path).


10. Data retention

Data Retention behavior (as implemented)
Active merchant/customer operational data Kept while the App is installed and until deleted by reinstall purge, customer redact (anonymization), shop redact, or operator-assisted deletion.
Soft-uninstall period Sessions removed; subscriptions and related customer PII retained until reinstall purge or shop/redact.
Widget preview sessions Deleted when expired (cleanup job).
Stored failed-webhook events (resolved / dead-letter) Eligible for deletion after 30 days via cleanup.
Notification logs Eligible for deletion after 90 days via cleanup.
Personal data access logs Retained until shop/redact (or earlier operator deletion).
Merchant billing row Survives soft uninstall and reinstall; deleted on shop/redact.
GDPR data-request export in merchant action logs Retained with other action logs until shop/redact (or earlier deletion if performed by the operator).

11. Data security

Practices verified in the App’s implementation and deployment configuration include:

  • Communication with the App uses HTTPS (the configured application URL is HTTPS). See also docs/security/encryption.md.
  • Merchant Admin access uses Shopify’s embedded app / session-token model; OAuth access tokens are stored in the App database via Shopify’s Prisma session storage adapter.
  • Incoming Shopify webhooks are authenticated through Shopify’s webhook authentication before handlers run.
  • Failed-webhook persistence redacts common personal payload fields before storage (DLP helpers — docs/security/dlp.md).
  • Access to customer personal data surfaces is recorded in personal data access logs (timestamp, opaque actor id, shop, resource, action — no name/email values).
  • Internal Console staff passwords must meet the Console password policy when created (docs/security/password-policy.md); hashes use scrypt.
  • GDPR data-request handling avoids logging export personal content to the application console.
  • Customer portal and Admin GraphQL calls use Shopify-authenticated contexts rather than exposing Admin access tokens to the storefront.
  • Security incident handling is described for operators in docs/security/incident-response.md.

This policy does not claim encryption-at-rest details, backup encryption, or organizational security certifications (for example SOC 2 or ISO 27001) beyond what is visible in application code and public hosting URL configuration. Hosting and database providers may apply their own controls; see Section 12 and docs/security/backup-and-recovery.md.


12. Third-party services that process data

Based on actual integrations and configuration in this codebase:

Service Role
Shopify Platform authentication, Admin/Customer Account APIs, webhooks, checkout/selling plans, App Billing, theme and customer-account extension hosting.
PostgreSQL database Primary application datastore accessed via DATABASE_URL (Prisma).
Render Hosting destination for the App (application_url / SHOPIFY_APP_URL: https://subscriptions.obnold.app).
SMTP email provider Delivers transactional notification email as configured by the operator’s SMTP_* settings (via Nodemailer). The specific vendor depends on that configuration.

No separate third-party product-analytics or error-monitoring service is wired into the application code reviewed for this policy.


13. Cookies and similar technologies

  • The App does not set its own cookies in the theme extension or portal code reviewed for this policy.
  • Merchant Admin authentication relies on Shopify’s session-token / OAuth session model, with session records stored server-side (database), not as App-authored browser cookies.
  • Certain merchant Admin UI screens may use the browser’s localStorage only to remember whether an informational banner was dismissed. That value stays in the merchant’s browser and is not used as a cross-site tracking cookie by the App.

Shopify and the merchant’s storefront theme may set their own cookies under their own policies; those are outside this App’s control.


14. Children’s data

The App is designed for Shopify merchants and their store customers in ordinary commercial subscription use. It is not directed at children. Merchants are responsible for their own storefront compliance regarding age-restricted offerings.


15. International processing

The App’s database and hosting locations depend on the operator’s deployment (including the Render-hosted application URL configured for this project). Confirm processing regions / subprocessors for your production deployment if required by local law (operator-owned; not hard-coded).


16. Changes to this policy

We may update this Privacy Policy when the App’s data practices change. The current version will be published at this document location (and/or the URL provided in the Shopify App Store listing).

Any additional merchant notification method for policy updates is operator-owned. The App codebase does not implement an automated “privacy policy updated” notification.

The “Last updated” date at the top will change when this policy is revised.


17. Contact

For privacy questions, data requests related to App-stored data, or concerns about this policy:

  • Email: support@obnold.com
  • Legal entity: Obnold
  • Address: (publish with hosted legal pages; not stored in app code)

If you are a customer of a merchant using the App, please also contact that merchant, since they are typically the primary controller of your storefront customer relationship. Shopify’s tools and the compliance webhooks described above are how platform-mandated requests reach the App.