Why you supply these keys yourself
WhatsApp messages go out from your business number, and your Shopify and Stripe data is read from your account — never pooled through ours. That keeps your brand on every message and your data under your control, and it means providers bill you directly at their own rates with nothing added on top.
Every key is encrypted with AES-256-GCM before it touches the database and is never shown again — only a masked hint. Decryption happens server-side, at the moment we call that provider on your behalf.
Go to IntegrationsGoogle sign-in (on your own domain)
One-click signup and login with Google — no password to invent, no confirmation email to wait for. The user never leaves cortex.mnbresearch.com. On paid traffic this is one of the largest single conversion levers there is.
- 1Why Supabase is still involved
Every account, session and row-level security rule in Cortex is anchored to a Supabase auth user, so any Google sign-in has to end with a Supabase session — that part isn't optional. What you CAN avoid is the ugly full-page bounce through supabase.co: Cortex uses Google Identity Services, so the sign-in happens on your domain and Google only needs to trust cortex.mnbresearch.com.
- 2Create the OAuth client in Google Cloud
console.cloud.google.com → your project → APIs & Services → Credentials → Create Credentials → OAuth client ID → application type Web application. Name it “MNB Cortex Web”. If prompted, configure the consent screen first: User type External, app name MNB Cortex, your support email and logo.
- 3Whitelist your domain as a JavaScript origin — this is the bit you asked about
Under “Authorised JavaScript origins” add exactly https://cortex.mnbresearch.com (scheme, no trailing slash, no path). This is what lets Google issue a token to a page served from your domain, and it is the only Google-side entry the on-domain flow needs.
- 4Also add the Supabase redirect URI, as a safety net
Under “Authorised redirect URIs” add https://krklgsmeamnxeawdlmka.supabase.co/auth/v1/callback . The on-domain flow doesn't use it, but having it means the classic redirect route still works if a browser ever blocks the in-page one — and it costs nothing to add now.
- 5Put the CLIENT ID in Vercel
Vercel → mnb-cortex → Settings → Environment Variables → Add: NEXT_PUBLIC_GOOGLE_CLIENT_ID = your ID ending in .apps.googleusercontent.com. Production. Then redeploy — NEXT_PUBLIC_ values are baked in at build time, so the button won't appear until you do. This value is public by design; it is visible in the page source of every site that uses Google sign-in.
- 6Put the CLIENT ID in Supabase — the secret is NOT needed
Supabase → Authentication → Sign In / Providers → Google → enable it, put the ID in “Client IDs”, Save. The ID in use is 31653003935-bbqm7ei6jvf5i1of2t4eife5pdn6580r.apps.googleusercontent.com . Supabase needs it to verify the token was really issued for your app; without it sign-in fails with an audience error. Leave “Client Secret (for OAuth)” EMPTY — that field is only used by the redirect flow, and the provider saves happily without it. So the on-domain route means no client secret exists in any second system at all. Leave “Skip nonce checks” off; the button doesn't set a nonce, so nothing needs relaxing.
- 7Set the site URLs in Supabase
Authentication → URL Configuration. Site URL https://cortex.mnbresearch.com , and add https://cortex.mnbresearch.com/auth/callback under Redirect URLs.
- 8Publish the consent screen before you advertise
While it is in “Testing”, only accounts you have explicitly listed can sign in — everyone else sees “app is blocked”. Switch it to “In production”. Basic email/profile scopes need no Google review, so this takes effect immediately.
- •Adding a trailing slash or a path to the JavaScript origin. It must be exactly https://cortex.mnbresearch.com — origin only.
- •Setting NEXT_PUBLIC_GOOGLE_CLIENT_ID in Vercel and not redeploying. NEXT_PUBLIC_ variables are compiled into the build, so nothing changes until the next deployment.
- •Putting the client ID in Vercel but not in Supabase. Google signs the user in and Supabase then rejects the token with an audience error — Cortex names this case explicitly if it happens.
- •Leaving the consent screen in Testing mode, which blocks every real visitor.
- •A customer who signed up by email and later uses Google with the SAME address: Supabase links them to one account, which is what you want — but it surprises support the first time.
WhatsApp Business (Meta Cloud API)
Send reminders, payment chases and broadcasts from your own WhatsApp business number, and let Cortex agents message customers directly.
- 1Create a Meta developer account
Go to developers.facebook.com and sign in with the Facebook account that owns (or will own) your business page. Accept the developer terms. This is free.
- 2Create an app of type “Business”
My Apps → Create App → choose “Business” → give it any name (e.g. “Cortex Messaging”). Ignore the other app types; only Business exposes WhatsApp.
- 3Add the WhatsApp product
On the app dashboard, find WhatsApp in the product list and click “Set up”. Meta creates a test number for you automatically, and links a WhatsApp Business Account (WABA).
- 4Copy your Phone number ID
WhatsApp → API Setup. You'll see “From” with a phone number and, directly beneath it, a Phone number ID — a long number like 123456789012345. That ID is what Cortex needs, NOT the phone number itself.
- 5Generate a PERMANENT access token
The token shown on the API Setup page expires in 24 hours — don't use it. Instead: Business Settings → Users → System Users → Add, create a system user with the Admin role, click “Generate New Token”, pick your app, tick the whatsapp_business_messaging and whatsapp_business_management permissions, and set the expiry to Never. Copy the token immediately; Meta shows it once.
- 6Add your own business number
WhatsApp → API Setup → “Add phone number”. It must be a number NOT currently registered on the normal WhatsApp or WhatsApp Business app — if it is, delete that account first and wait a few minutes. Verify by SMS or call.
- 7Paste both values into Cortex
Integrations → WhatsApp Business → Connect. Put the system-user token in “Permanent access token” and the ID from step 4 in “Phone number ID”. Cortex encrypts both with AES-256-GCM before storing them, and never shows them again.
- 8Create and submit a message template
To START a conversation you need an approved template (free-form replies are only allowed within 24 hours of the customer messaging you). WhatsApp Manager → Message Templates → Create. Approval is usually under an hour. Use the template name in Cortex when sending.
- •Using the temporary 24-hour token from the API Setup page. It works in testing and then silently stops the next day — always create a system-user token with expiry Never.
- •Entering the phone NUMBER instead of the Phone number ID. The ID is the long numeric string underneath it.
- •Trying to register a number that is already in use on the WhatsApp app. Delete that account first.
- •Expecting free-form messages to reach a new contact. Outside the 24-hour customer-initiated window, only approved templates are delivered.
Shopify
Cortex pulls your orders and customers every night, so revenue, order counts and repeat-customer KPIs stay current without any manual import.
- 1Open app development
Shopify admin → Settings → Apps and sales channels → Develop apps. Click “Allow custom app development” if you haven't before (owner account only).
- 2Create an app
“Create an app” → name it “MNB Cortex” → Create.
- 3Grant read scopes
Configuration → Admin API integration → Configure. Tick read_orders, read_customers and read_products. Cortex only ever reads; no write scope is needed or requested.
- 4Install and copy the token
API credentials → Install app → reveal the Admin API access token. It starts with shpat_ and is shown once.
- 5Connect in Cortex
Integrations → Shopify. “Shop domain” is your myshopify address (e.g. mystore.myshopify.com — not your custom domain). Paste the shpat_ token as the access token.
- •Using your public custom domain instead of the .myshopify.com one.
- •Missing read_orders — the connection tests fine and then syncs nothing.
Stripe
Paid charges arrive as settled receivables, so your cash position reflects money that has actually landed.
- 1Open API keys
Stripe Dashboard → Developers → API keys.
- 2Create a restricted key
“Create restricted key”. Grant READ on Charges and Balance transactions, and nothing else. A restricted key limits the damage if it ever leaks — prefer it to the secret key.
- 3Paste it into Cortex
Integrations → Stripe → Connect. The key begins rk_live_ (restricted) or sk_live_ (secret).
- •Pasting a test-mode key (sk_test_/rk_test_) — it connects but returns no live payments.
Razorpay
Captured payments become paid receivables automatically, so collections and cash figures stay accurate.
- 1Open API keys
Razorpay Dashboard → Account & Settings → API Keys.
- 2Generate a key
“Generate Key”. Razorpay shows the Key Secret exactly once — copy it before closing the dialog.
- 3Paste both into Cortex
Integrations → Razorpay. Key ID starts rzp_live_; the secret is the value you just copied.
- •Using rzp_test_ credentials — no live payments will appear.
Google Sheets
Cortex reads a sheet you already maintain and turns it into live KPIs — the fastest way in if your data isn't in any system yet.
- 1Publish the sheet
In your sheet: File → Share → Publish to web → publish the specific tab as CSV.
- 2Copy the published link
Use the URL Google gives you after publishing, not the normal address bar link.
- 3Paste it into Cortex
Integrations → Google Sheets. Cortex matches columns by header name, so amount / customer / date are found whatever order they're in.
- •Sharing the edit link instead of publishing. An unpublished sheet returns a login page and the sync fails.
- •Amounts formatted as text with symbols — Cortex strips ₹ and commas, but a column of genuine text won't total.
Stuck on any of these?
Send us the step you're on and we'll walk you through it — or do it with you on a call. WhatsApp in particular is fiddly the first time, and it's faster than reading Meta's documentation.