10 min read
Shopify App Integration Guide
Wire install and uninstall lifecycle events into Invizo CRM
Use this guide to connect your Shopify app backend with Invizo CRM so merchant install and uninstall events are synced reliably.
Key takeaway. Put install/uninstall calls in backend webhooks only, authenticate with bearer token, and keep worker/Redis online for queue delivery.
Architecture overview
Your Shopify app receives lifecycle events. Your backend then calls Invizo ingest APIs. Invizo stores merchant/app/plan data and enqueues lifecycle emails.
- Shopify -> your app webhook handler (server-side)
- Your backend -> Invizo /api/v1/merchants/install or /api/v1/merchants/uninstall
- Invizo -> DB upsert + queue + worker delivery
Prepare app settings in Shopify
Start with clean app settings so OAuth and webhook delivery stay consistent across environments.
- Create your app in Shopify Partners and open app configuration.
- Set App URL and redirect URLs to your deployed host.
- Install app on a test store and confirm OAuth flow works.
- Register app/uninstalled webhook topic to your backend endpoint.
Configure CRM ingest authentication
Every server-to-server call to Invizo CRM must include an ingest bearer token.
- In Invizo CRM, generate an API key from Settings > Generate API key.
- From Shopify backend, call CRM with header Authorization: Bearer <token>.
- Never expose this key in browser code; keep it server-side only.
Authorization: Bearer <INVIZO_INGEST_TOKEN> Content-Type: application/json Idempotency-Key: install-<shop>-<timestamp>
Map Shopify data to Invizo payload
- appSlug -> stable app identifier (e.g. bundle-builder)
- appName -> readable app name shown in CRM
- shop -> *.myshopify.com domain
- merchantName/email -> shop owner or billing contact
- planName -> current plan from your app billing state
- status -> usually active on install
Install API guideline
- Endpoint: POST /api/v1/merchants/install
- Alias: POST /api/v1/merchants/ingest
- App and Plan are auto-created if they do not exist.
- Call this inside your app installed webhook/event handler.
{
"appSlug": "bundle-builder",
"appName": "Bundle Builder",
"shop": "demo-shop.myshopify.com",
"merchantName": "Demo Shop",
"email": "owner@demo-shop.com",
"planName": "Pro",
"country": "US",
"timezone": "America/New_York",
"status": "active"
}Fetch example for app installed webhook
- Use this in your backend webhook processor after app installation is confirmed.
await fetch("http://localhost:3000/api/v1/merchants/install", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.INVIZO_INGEST_TOKEN}`,
"Idempotency-Key": `install-${shop}-${Date.now()}`,
},
body: JSON.stringify({
appSlug: "bundle-builder",
appName: "Bundle Builder",
shop,
merchantName: shopName,
email: ownerEmail,
planName: "Pro",
country: "US",
timezone: "America/New_York",
status: "active",
}),
});Uninstall API guideline
- Endpoint: POST /api/v1/merchants/uninstall
- This marks merchant churned and queues exit email if pending.
- If merchant is missing for that appSlug + shop, API returns 404.
- Call this inside your app uninstalled webhook/event handler.
{
"appSlug": "bundle-builder",
"shop": "demo-shop.myshopify.com",
"reason": "App uninstalled by merchant"
}Fetch example for app uninstalled webhook
- Use this in your backend webhook processor when app is removed.
await fetch("http://localhost:3000/api/v1/merchants/uninstall", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.INVIZO_INGEST_TOKEN}`,
},
body: JSON.stringify({
appSlug: "bundle-builder",
shop,
reason: "App uninstalled by merchant",
}),
});Recommended retry policy
- Retry on HTTP 429/5xx with exponential backoff (e.g. 1s, 3s, 10s).
- Do not retry on 400 (invalid payload) until data is fixed.
- Log CRM response body for failed calls to debug quickly.
- Preserve webhook event id in logs for traceability.
Integration test checklist
- Install from test store -> merchant appears in CRM Merchants list.
- App/plan auto-create in CRM if first-time appSlug/planName.
- Uninstall event marks merchant as churned.
- Mail Log shows queued/sent/failed states as worker processes jobs.
- Duplicate install calls should upsert same merchant by appId+shop.
Operational checklist
- Run Redis + worker so welcome and exit queues can process.
- Monitor /mail-log and dashboard queue log after webhook delivery.
- Retry failed webhook events from Shopify if non-2xx is returned.