A secret key and optional webhook signing secret stored encrypted on the account row, resolved per account with a short cache, plus a per-account settlement currency. Deliberately not Stripe Connect. The key is only ever returned masked to the UI — unlike the CRM token, the full value never round-trips.
Also called: connect Stripe · take card payments · merchant of record · who holds my money
- 1Admin pastes a Stripe secret key in Settings → Integrations.
- 2The key is encrypted and stored; a masked label and connected timestamp are recorded.
- 3Currency defaults from environment but can be overridden per account.
- 4getStripeClient resolves and caches the client per account for outbound calls.
- 5Only the masked preview and a hasWebhookSecret boolean are returned to the UI.
The module records the architectural choice and its reasoning: 'Single-account model: each org charges on ITS OWN Stripe account (the org is merchant of record — funds, fees, refunds, payouts are theirs)... NOT Stripe Connect — there's one merchant, so Connect's onboarding/account-header machinery buys nothing here; if a second tenant onboards, it just stores its own key.' The masking rule is stated in the route: 'masked-only (secret keys grant payment access; never round-trip the full value).' There is also a currency note flagged for a real client: 'Client is in BC — cad.'
- Routing funds through the platform would make it merchant of record.
- A single-currency assumption broke for Canadian builders.
- Returning a live payment key to the browser would be a payment-access leak.
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →