Merchant Users And Finance Assistant Keys
Copy and backfill Finance Assistant keys from admin chrome. Do not paste live keys onto this public page.
-
On the merchant Overview Merchant card, the row is Finance Assistant API Key. ⓘ About Finance Assistant API keys. Idle: Loading…. Empty: Not provisioned — click Copy to create. Copy reveals the key after the admin password prompt. Success toast: Merchant API key copied to clipboard. Merchant Page Editing.
-
Admin → Users (
https://admin.finmatch.io/users/). Merchant rows: Copy FA (success Finance Assistant key copied to clipboard.) and Credentials. Sync Merchant API Keys backfills the class of profiles that never got amerchant-{id}auth user. Busy: Syncing merchant API keys…. Result: Synced: N created, N updated, N skipped. Users.
Copy heals one missing merchant user. Sync heals the class. Stripe / API-created merchants (for example M869410) can exist as a profile without an auth user. That is a class of merchants, not one bug.
auth-api is the only writer of Finance Assistant keys. Keys are
minted only for a trusted admin session (requireAdmin, plus password
elevation on reveal). Public POST /api/merchants must not mint
sk_live_… credentials. The same service writes the Cloudflare KV
mirror (MERCHANT_KEYS on the finance-assistant-proxy Worker) once
Cloudflare credentials are configured on auth-api. Until then, KV
writes no-op and merchant create still succeeds. Operators do not paste
keys into KV by hand.
Canonical Lifecycle
- Merchant profile may be created by admin UI or Stripe via
POST /api/merchants(still unauthenticated).merchant-apithen emitsmerchant.created(GCS history remains a separate audit log). - Admin Add Merchant keeps its existing
POST /admin/merchant-users/provisioncall (no plaintext key in the response). After provision,auth-apiwrites the merchant ID and Finance Assistant key to Cloudflare KV when credentials are configured. - Copy /
POST /admin/merchant-keys/revealheals a missing merchant user from the merchant id, then returns the key. That is the path that unblocks Stripe-created merchants. Reveal does not reactivate a deactivated merchant user (Copy retry also ignores that inactive error). The same reveal is Copy FA on Users. Revoke on that page retires a typed credential (sandbox preview links stop working). Issue and revoke also update the KV pair. - Users → Sync Merchant API Keys stays the bulk backfill for the historical class of profiles that never got a
merchant-{id}auth user. Sync also writes KV for merchants that now have a key.
There is no dashboard button for KV coverage or backfill. Admin API only (IDs, never key values):
GET /admin/merchant-keys/cloudflare-kv-coveragePOST /admin/merchant-keys/sync-cloudflare-kv
Data Responsibilities
merchants.json:- merchant profile data and merchant key (
profiles[merchantId])
- merchant profile data and merchant key (
merchant-router.json:- environment/domain routing keyed by merchant ID
auth-credentials.json:- merchant user login/API identity keyed by username
- merchant linkage through
merchantId+metadata.merchantId - merchant Finance Assistant key (
apiKey)
Finance Assistant API Key Role
- Used for Finance Assistant workflows:
- enquiry submission
- lender start-finance-application calls
- Not required for partner quote maths path.
- Missing key behavior:
- quote endpoint may still return valid products
- Finance Assistant side-effects can fail (especially without proxy fallback key mapping)
Merchant ID Change Rules
Merchant ID updates must be treated as migrations:
- Preflight checks must pass before write:
- old ID exists
- new ID does not exist
- env config files are readable
- no ID conflicts in env configs
- Migration must update all required stores:
merchants.jsonkeysmerchant-router.jsonkeys- environment merchant config ID fields
- auth merchant user ID mapping
- Cloudflare KV
MERCHANT_KEYS(auth-api, viamerchant.id_changed)
- If required migration step fails, rollback should be attempted and surfaced as an explicit error.
Audit / Merchant History Requirements
Every merchant profile-affecting action must emit a history event.
Required fields:
actor_type:admin_userorautomationactor_idandactor_namechange_sourcecorrelation_id(when available)detailswith meaningful change context
Applies to:
- manual admin profile edits
- merchant ID changes
- environment switches
- Stripe link/unlink actions
- automated sync/ingestion jobs that alter merchant data
Reconciliation Checklist
Use this when investigating onboarding or drift:
- merchant exists in Merchant API
- merchant user exists in Auth API with role
merchant - merchant user has
merchantIdandmetadata.merchantId - merchant user has
apiKey - Cloudflare KV
MERCHANT_KEYShas that merchant ID (after provision / Copy / Sync; coverage endpoint lists unpaired IDs only) - no conflicting username mapping
- merchant history contains events for recent profile mutations
- if Copy Key returned "Merchant user not found", Copy again after this fix (reveal heals) or run Users → Sync Merchant API Keys to backfill the class