Appearance
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
| Variable | Description | Example |
|---|---|---|
SHOPIFY_API_KEY | Public API key from Partner Dashboard. | xxxxxx |
SHOPIFY_API_SECRET | Private API secret. | xxxxxx |
SCOPES | Comma-separated list of OAuth scopes (must include at least one). | read_products,write_products |
SHOPIFY_APP_URL | Public HTTPS URL for the deployed app (used for OAuth callbacks). | https://bpe-ten8.onrender.com |
SHOPIFY_API_VERSION | Admin API version to use (defaults to current stable). | 2025-07 |
SHOP_CUSTOM_DOMAIN | (Optional) Custom domain if using one. | app.example.com |
SUPPORT_EMAIL | Support contact shown in Privacy/Support pages and listing. | support@xyppy.com |
DATABASE_URL | Primary connection string (e.g., Neon pooled). | postgres://... |
DIRECT_URL | Direct connection (no pooler) for Prisma migrations. | postgres://... |
JOB_QUEUE_ENABLED | Enables background job runner. | 1 |
NODE_ENV | Environment mode; should be production in live env. | production |
TEST_MODE | Leave 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.
| Variable | Description | Example |
|---|---|---|
TIER1_HANDLE | Shopify plan handle for tier1 (Starter). | starter |
TIER2_HANDLE | Shopify plan handle for tier2 (Standard). | standard |
TIER3_HANDLE | Shopify plan handle for tier3 (Advanced). | advanced |
TEST_TIER | (Optional) Force a specific tier for testing (bypasses billing lookup). | tier2 |
How tier resolution works
- The app queries Shopify's
appInstallation.activeSubscriptionsAPI - It reads the
planHandlefield from each subscription's line items (vialineItems.plan.pricingDetails.planHandle) - It matches the plan handle against
TIER1_HANDLE,TIER2_HANDLE,TIER3_HANDLE(case-insensitive) - 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
- Use a development store - Shopify creates test subscriptions automatically
- Check
/app/billing/status- Shows current subscription status, tier resolution, and trial info - Use
TEST_MODE=1- Bypasses subscription gating for local development - 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:
| Variable | Description | Example |
|---|---|---|
APP_ENV | Signals the app to use staging-specific configuration. | staging or preview |
DATABASE_URL | Staging Neon branch pooled connection string. | postgres://…-pooler.neon.tech/neondb?sslmode=require |
DIRECT_URL | Staging Neon branch direct connection string (no -pooler). | postgres://…neon.tech/neondb?sslmode=require |
SHOPIFY_API_KEY | Staging Shopify app API key (different from production). | xxxxxx |
SHOPIFY_API_SECRET | Staging Shopify app API secret. | xxxxxx |
SHOPIFY_APP_URL | Staging Render service URL. | https://bpe-staging.onrender.com |
Current Neon branches
| Branch | Purpose | Endpoint |
|---|---|---|
main | Production | ep-billowing-sound-aej92wq7 |
staging | Staging/QA | ep-bold-moon-ae7orloc |
preview | E2E tests / preview | ep-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.tomlsets webhook API version2025-07. Keep in sync with deployed code andSHOPIFY_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
- Set/confirm environment variables in hosting UI (Render → Environment).
- Run database migrations (
npx prisma migrate deploy). - Deploy app (Docker/Render auto-deploy).
- Verify health endpoint
/health:- API keys present
- DB connection OK
- Job queue enabled
- Trigger sample job to ensure queue runs.
- 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(expect200). - Webhook failures: watch Partner Dashboard (App → Webhooks) for failure counts.
- Billing events: optionally subscribe to
app_subscriptions/updatefor 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.