Skip to main content

Merchant Users And Finance Assistant Keys

Copy and backfill Finance Assistant keys from admin chrome. Do not paste live keys onto this public page.

  1. 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.

  2. 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 a merchant-{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​

  1. Merchant profile may be created by admin UI or Stripe via POST /api/merchants (still unauthenticated). merchant-api then emits merchant.created (GCS history remains a separate audit log).
  2. Admin Add Merchant keeps its existing POST /admin/merchant-users/provision call (no plaintext key in the response). After provision, auth-api writes the merchant ID and Finance Assistant key to Cloudflare KV when credentials are configured.
  3. Copy / POST /admin/merchant-keys/reveal heals 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.
  4. 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-coverage
  • POST /admin/merchant-keys/sync-cloudflare-kv

Data Responsibilities​

  • merchants.json:
    • merchant profile data and merchant key (profiles[merchantId])
  • 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.json keys
    • merchant-router.json keys
    • environment merchant config ID fields
    • auth merchant user ID mapping
    • Cloudflare KV MERCHANT_KEYS (auth-api, via merchant.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_user or automation
  • actor_id and actor_name
  • change_source
  • correlation_id (when available)
  • details with 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 merchantId and metadata.merchantId
  • merchant user has apiKey
  • Cloudflare KV MERCHANT_KEYS has 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