Guide: Production Deployment
Guide: Production Deployment
This guide covers deploying a SeloraX embedded app to production, using the SeloraX Messaging architecture (separate frontend + backend) as an example.
Architecture
A typical SeloraX app has three components:
┌──────────────────┐ iframe ┌──────────────────┐
│ SeloraX Dashboard │───────────────>│ App Frontend │
│ admin.selorax.io │ postMessage │ (Vercel, etc.) │
└──────────────────┘ └──────────────────┘
│ │
│ REST API │ REST API
v v
┌──────────────────┐ ┌──────────────────┐
│ SeloraX Platform │── webhooks ──>│ App Backend │
│ api.selorax.io │ (Inngest) │ (DO App Platform)│
└──────────────────┘ └──────────────────┘
Backend Environment Variables
| Variable | Description | Example |
|---|---|---|
SELORAX_CLIENT_ID | App client ID from Developer Portal | sx_app_... |
SELORAX_CLIENT_SECRET | App client secret (keep secret!) | sx_secret_... |
SESSION_SIGNING_KEY | Session token signing key (64 hex chars) | ac4d5804b668... |
SELORAX_API_URL | Platform API base URL | https://api.selorax.io/api |
DATABASE_URL | Your app's database connection string | mysql://user:pass@host/db |
PORT | Server port | 5002 |
NODE_ENV | Environment flag | production |
JWT_SECRET | JWT signing secret for legacy auth | your-secret |
Provider-specific variables (for SMS apps):
| Variable | Description |
|---|---|
SMS_API_KEY | SMS provider API key |
SMS_API_ENDPOINT | SMS provider endpoint URL |
Frontend Environment Variables
| Variable | Description | Example |
|---|---|---|
NEXT_PUBLIC_MESSAGING_API_URL | Full URL to your backend API | https://api.myapp.example.com/api/messaging |
Protocol matters
Use https:// for production. Using http:// will fail on most hosting providers and browsers will block mixed content.
Step 1: Deploy Backend
Deploy your Express server to any Node.js hosting provider:
- DigitalOcean App Platform — Use the Dockerfile, set env vars in the console
- Railway / Render — Connect GitHub repo, set env vars
- Self-hosted — Use PM2 or Docker behind a reverse proxy with SSL
Verify the backend is running:
curl https://your-backend.example.com/api/messaging/healthStep 2: Deploy Frontend
Deploy your React/Next.js frontend to Vercel, Netlify, or similar:
- Set
NEXT_PUBLIC_MESSAGING_API_URLto your production backend URL - Deploy and note the production URL (e.g.,
https://messaging.selorax.com)
Step 3: Update App URLs
Via the Developer Portal or API, update your app's URLs:
PATCH /api/v1/apps/:appId
Content-Type: application/json
Authorization: Bearer <token>
{
"app_url": "https://messaging.selorax.com",
"webhook_url": "https://api.messaging.selorax.com/api/messaging/oauth",
"webhook_receive_url": "https://api.messaging.selorax.com/api/messaging/webhooks"
}| URL | Purpose |
|---|---|
app_url | Frontend loaded as iframe in merchant dashboard |
webhook_url | Receives OAuth token callbacks during direct-install |
webhook_receive_url | Receives webhook event deliveries (order changes, etc.) |
Step 4: Verify Scopes
Ensure your app's requested_scopes includes all scopes your app needs:
SELECT requested_scopes FROM apps WHERE slug = 'your-app-slug';If your app uses billing (wallet, charges, subscriptions), you must include "billing":
["read:orders", "read:customers", "read:store", "billing"]For existing installations, also update granted_scopes in app_installations:
UPDATE app_installations
SET granted_scopes = '["read:orders","read:customers","read:store","billing"]'
WHERE app_id = ? AND store_id = ?;Step 5: Test the Full Flow
- Marketplace visibility — Navigate to the marketplace in a merchant dashboard. Your app should appear if
is_listed = 1andis_active = 1. - Install — Click Install. The platform calls your
webhook_url/tokenwith tokens. - Iframe loads — Open the app page. The iframe should load your
app_urlwith HMAC params. - Session token works — Your app should receive a session token via postMessage and display data.
- Wallet works — If using billing, the wallet balance should display and Top Up should work.
- Webhooks work — Trigger an event (e.g., change an order status) and verify your webhook endpoint receives it.
Common Issues
Wallet / Top Up Button Not Showing
Cause: Missing billing scope.
The wallet API endpoint (GET /api/apps/v1/billing/wallet) requires requireScope('billing'). If billing is not in requested_scopes AND granted_scopes, all wallet calls return 403, and your frontend shows no wallet data.
Fix: Add billing to both apps.requested_scopes and app_installations.granted_scopes.
Iframe Shows "Connecting..."
Cause: app_url is wrong, or DASHBOARD_URL on the platform doesn't match the actual dashboard origin.
The iframe loads your app_url with HMAC params. If the URL is wrong, the iframe can't load. If DASHBOARD_URL doesn't match the actual dashboard origin, the postMessage handshake fails.
Fix: Verify app_url points to your production frontend. Check that the platform's DASHBOARD_URL env var matches the actual dashboard domain.
Webhook Delivery Fails (500)
Cause: Your webhook_receive_url is incorrect, or your backend is down.
Fix:
- Use the Developer Portal webhook test endpoint to verify connectivity
- Check your backend logs for errors
- Verify the
webhook_receive_urlin the Developer Portal matches your deployed backend
OAuth Token Callback Fails
Cause: webhook_url is wrong or backend isn't handling POST to /token path.
During direct-install, the platform POSTs tokens to {webhook_url}/token. If this fails, the installation succeeds but your app doesn't receive tokens.
Fix: Verify webhook_url is correct and your backend handles POST {webhook_url}/token.
"Invalid session token" on API Calls
Cause: SESSION_SIGNING_KEY mismatch between your backend and the platform.
Fix: Check the signing key in the Developer Portal matches your backend's SESSION_SIGNING_KEY env var. If you regenerated the key, update your backend deployment.