Connect a business’s Stripe account to sync customers, products, and orders for revenue reporting.
Stripe is integrated in two distinct roles. Most “business settings → Stripe” questions are about Stripe Connect (per business). This page documents the Connect flow in detail and gives a short note on Platform Stripe (SaaS billing) at the end.
Each business has at most one row in the stripe_access table:
Field
Description
stripe_account_id
Connect account ID (acct_…) returned by OAuth.
account_name
Display name from Stripe (business name, company, individual name, or email).
date_created
Timestamp the link was saved.
No refresh token is stored. Access goes through the platform’s Stripe Connect app (STRIPE_CONNECT_CLIENT_ID + STRIPE_SECRET_KEY) acting on behalf of stripe_account_id.
Agency app — stripeSetting.js calls GET /api/stripe/connect-url (requires business access).
The user is sent to Stripe Connect with scope read_write.
The callback GET /api/stripe/oauth/callback exchanges the code, saves or updates stripe_access, then redirects back to settings with ?stripe=connected or ?stripe=error.
Client portal uses the same pattern with state=forclient:… and client routes (/stripe/connect-url, /stripe/status, /stripe/disconnect).
Plus frontend redirect URLs for agency vs. forclient flows.
Connect the client’s Stripe account, not your agency’s. Each business should point to its own Stripe account so customer and order data stays isolated per client.
A scheduled job (stripeScheduler, npm run job:stripe) and the Manual sync button both call fetchStripeData, which uses the platform secret with stripeAccount: stripe_account_id (Connect context).Data is synced incrementally by last_successful_date when set:
DELETE /api/stripe/:businessId removes stripe_access plus the business’s products, orders, customers, and sync jobs. It does not clear every Stripe-related table — invoices and checkout sessions may remain unless cleared elsewhere.
List customers with total spent, order count, last purchase, currency; optional match to GHL contact by email (powers the Stripe customers tab in SalesGrid).
POST contacts/stripe-summary-by-emails
Batch lookup used by Leads, Calls, and Sales grids.
StripeColumns.js
Adds Stripe Spent and Stripe Orders columns to the grids when Stripe is connected and there is matching email data.
stripeByEmailModel.getStripeInfoByEmail
Powers per-email Stripe detail in contact history (customers, payments, invoices, checkout).
Spend is deduplicated across invoices, checkout sessions, and standalone payment intents so the same payment never double-counts.
Connection status and account name shown at the top of the Stripe panel.
Manual sync (ManualSyncBlock type="stripe") triggers the same fetch path as the scheduler — useful after a fresh connection or after disconnect/reconnect.
Stripe data does not feed the Facebook/ad rules engine (unlike Clarity).
ROAS and ad reporting in the Business dashboard still come primarily from GHL and other sources. Wire Stripe in separately if you need it as a revenue source.
Separate from the per-business Connect account, the platform’s own Stripe account handles:
Tenant subscriptions, invoices, packagestripe_price_id, and onboarding checkout.
Webhooks: checkout.session.completed, customer.subscription.*, invoice.*, credit grants, seat limits, and more.
This bills agencies on The Agency Engineer SaaS, not the client’s ad-business Stripe catalog. Configuration lives under SaaS Packages and the platform webhook handler at /api/webhooks/stripe.
Stripe Connect — one linked acct_… per business via OAuth. Daily and manual sync of customers, products, prices, payments, invoices, and checkout into local tables. Used to enrich Contacts and Sales grids with spend and order counts by email, plus a dedicated Stripe customers view.
Platform Stripe — billing your tenants on The Agency Engineer itself.