Skip to content

Production Environment Configuration

Use this reference when deploying Bulk Product Editor to production (Render or alternative host). Keep secrets in your hosting provider’s secure settings.

Required environment variables

VariableDescriptionExample
SHOPIFY_API_KEYPublic API key from Partner Dashboard.xxxxxx
SHOPIFY_API_SECRETPrivate API secret.xxxxxx
SCOPESComma-separated list of OAuth scopes (must include at least one).read_products,write_products
SHOPIFY_APP_URLPublic HTTPS URL for the deployed app (used for OAuth callbacks).https://bpe-ten8.onrender.com
SHOPIFY_API_VERSIONAdmin API version to use (defaults to current stable).2025-07
SHOP_CUSTOM_DOMAIN(Optional) Custom domain if using one.app.example.com
SUPPORT_EMAILSupport contact shown in Privacy/Support pages and listing.support@xyppy.com
DATABASE_URLPrimary connection string (e.g., Neon pooled).postgres://...
DIRECT_URLDirect connection (no pooler) for Prisma migrations.postgres://...
JOB_QUEUE_ENABLEDEnables background job runner.1
NODE_ENVEnvironment mode; should be production in live env.production
TEST_MODELeave unset or 0 in production (staging can use 1 for fixtures).0
USAGE_CAP_OVERRIDE(Optional) Only for staging/dev to override calculated plan caps for testing.10
EMAIL_QUEUE_ENABLED(Optional) Disable email queue when set to 0.1
SENDGRID_API_KEY(Optional) SendGrid API key for outbound email.SG.xxxxx
EMAIL_FROM(Optional) From address for outbound email.Bulk Product Editor <support@xyppy.com>
EMAIL_UNSUBSCRIBE_SECRET(Optional) Secret for unsubscribe tokens.super-secret
SHOPIFY_APP_STORE_URL(Optional) App Store listing URL (used for review links).https://apps.shopify.com/your-app-handle
APP_NAME(Optional) Override app name in emails.Bulk Product Editor
OPENAI_API_KEY(Optional) OpenAI API key for AI-powered help chat.sk-...
CHAT_ENABLED(Optional) Force enable chat widget even without AI (fallback mode).1

Billing / Tier Configuration

These variables map Shopify Partner Dashboard plan handles to internal tier IDs. All three must be set for billing to work correctly.

VariableDescriptionExample
TIER1_HANDLEShopify plan handle for tier1 (Starter).starter
TIER2_HANDLEShopify plan handle for tier2 (Standard).standard
TIER3_HANDLEShopify plan handle for tier3 (Advanced).advanced
TEST_TIER(Optional) Force a specific tier for testing (bypasses billing lookup).tier2

How tier resolution works

  1. The app queries Shopify's appInstallation.activeSubscriptions API
  2. It reads the planHandle field from each subscription's line items (via lineItems.plan.pricingDetails.planHandle)
  3. It matches the plan handle against TIER1_HANDLE, TIER2_HANDLE, TIER3_HANDLE (case-insensitive)
  4. The matched tier ID is used for feature gating

Note: The planHandle is a stable identifier you set in the Shopify Partner Dashboard when creating pricing plans. It's different from the display name and won't change if you rename the plan.

Shopify Managed Pricing behavior

  • Free trial: All plans include a 14-day free trial configured in Partner Dashboard
  • Subscription on install: Merchants must subscribe to a plan when installing the app
  • Auto-cancellation on uninstall: Shopify automatically cancels subscriptions when the app is uninstalled
  • Test subscriptions: Development stores automatically get test subscriptions (no real charges)

Testing billing flows

  1. Use a development store - Shopify creates test subscriptions automatically
  2. Check /app/billing/status - Shows current subscription status, tier resolution, and trial info
  3. Use TEST_MODE=1 - Bypasses subscription gating for local development
  4. Use TEST_TIER=tier2 - Forces a specific tier without checking Shopify billing

Staging / Preview environment

The staging environment uses a separate Neon database branch and Shopify app credentials. Key differences from production:

VariableDescriptionExample
APP_ENVSignals the app to use staging-specific configuration.staging or preview
DATABASE_URLStaging Neon branch pooled connection string.postgres://…-pooler.neon.tech/neondb?sslmode=require
DIRECT_URLStaging Neon branch direct connection string (no -pooler).postgres://…neon.tech/neondb?sslmode=require
SHOPIFY_API_KEYStaging Shopify app API key (different from production).xxxxxx
SHOPIFY_API_SECRETStaging Shopify app API secret.xxxxxx
SHOPIFY_APP_URLStaging Render service URL.https://bpe-staging.onrender.com

Current Neon branches

BranchPurposeEndpoint
mainProductionep-billowing-sound-aej92wq7
stagingStaging/QAep-bold-moon-ae7orloc
previewE2E tests / previewep-nameless-butterfly-ae96woar

See docs/internal/deployment/preview-env.md for full setup instructions.

Webhook configuration

  • Environment variables are validated at runtime via Zod and the app will fail fast if a required variable (API key/secret, scopes, app URL) is missing.
  • shopify.app.toml sets webhook API version 2025-07. Keep in sync with deployed code and SHOPIFY_API_VERSION.
  • After deploy, confirm mandatory webhooks (privacy topics + app/uninstalled, app/scopes_update) show as successful in Partner Dashboard.
  • If using CLI to retest:
    shopify app webhook trigger --topic shop/redact --api-version 2025-07 \
      --delivery-method http --address https://<app-url>/webhooks/shop/redact

Deployment steps

  1. Set/confirm environment variables in hosting UI (Render → Environment).
  2. Run database migrations (npx prisma migrate deploy).
  3. Deploy app (Docker/Render auto-deploy).
  4. Verify health endpoint /health:
    • API keys present
  • DB connection OK
  • Job queue enabled
  1. Trigger sample job to ensure queue runs.
  2. Trigger privacy webhooks via CLI to confirm 200 responses.

Monitoring & logging

  • Application logs: Render dashboard (enable alerts for error-level logs).
  • Error tracking (recommended): integrate Sentry, New Relic, or equivalent.
  • Uptime monitoring: set external monitor for /app/health (expect 200).
  • Webhook failures: watch Partner Dashboard (App → Webhooks) for failure counts.
  • Billing events: optionally subscribe to app_subscriptions/update for notifications.

Post-deploy checklist

  • Confirm Shopify Admin can load the embedded app without errors.
  • Run smoke test from Manual QA Test Plan.
  • Spot-check DB (sessions, jobs) to ensure migrations successful.
  • Update documentation/CHANGELOG with release notes.