Skip to main content

Rate Cards Overview

Operators edit the credit-product catalogue on Lenders. They do not upload a GCS object from this docs site.

  1. Open Admin → Lenders (https://admin.finmatch.io/lenders/). Below the lender cards, Rate Card Products is the grouped catalogue. Subtitle: All credit products from the rate card, grouped by lender. Idle row: Loading rate card products.... After the page script runs, header buttons Credit products JSON (title Master Rate Card (Credit Products API)) and Lender-originated quotes JSON. Same sticky bar as each lender’s Credit Products tab (Edit mode, Quotes, Timing, Legacy columns). Catalogue chrome.

  2. Click a lender card for that lender’s Credit Products table (same writer — not a second catalogue). Add Credit Product opens the popup. Row Actions is Edit. Credit products.

  3. Merchant assignment is a different save. Open the merchant → Overview → Lender card. Tick products, set Min Deposit % / Direct apply URL, then Save credit products. Idle status: Edit checkboxes, apply URLs, and min deposit % rules. Author per-product Min Deposit % there. Merchant Page Editing and Calculator deposit dropdown.

  4. Not authorised merchants skip both rate-card downloads. Set FCA status on the Merchant card. Re-save Credit products or FCA status so merchant-api stamps profile fcaStatus onto the merchant row. Merchant FCA status and Not authorised merchants skip both fetches.

Do not paste APR ladders or SKU pound figures onto this public page.

Single writer (source of truth)​

WhatWriterWhere
Credit product cataloguecredit-products-api onlygs://finmatch-shared/finmatch-rate-card.json
Merchant product assignmentsmerchant-api (admin UI)assigned_rate_card_products on each merchant row in env configs/finmatch-merchant-config.json

Admin Credit Products / lender detail editors call the API (PUT/POST/DELETE /api/v1/credit-products). They do not write env-bucket rate cards. partner-api and integrity checks already read the shared catalogue via the API or GCS root object.

See also: Source of Truth Architecture §4.

Current landscape (verified Aug 2026)​

Declared model: one writable catalogue (shared root via credit-products-api).

Runtime reality: the storefront still dual-reads — env bucket first, shared root second.

ObjectWriterTypical live shape (Aug 2026)Storefront role
gs://finmatch-shared/finmatch-rate-card.jsoncredit-products-api~166 products; event-authored products (transaction_events) live hereTop-up / override; Propensio & most Zopa IDs only here; container/FA busted re-fetch on p
gs://finmatch-{p,s,t}/configs/finmatch-rate-card.jsonNone (not CPA; excluded from sync-to-gcs.yml)Stale snapshots (p ~87 products, 0 events; s/t smaller still)SDK primary fetch via rateCardsUrl

Env objects are not mirrors of shared. Product ID sets diverge; overlapping SKUs can differ in shape (shared event + legacy_projection vs env legacy first_payment only). A git working copy may exist on finmatch-p but does not deploy to the live env object.

Fetch paths (detail): Storefront asset delivery §3 “Dual rate-card model”.

Not authorised merchants skip both fetches​

When runtime fcaStatus is not_authorised, the SDK does not download the env rate card or the shared fallback. It writes an empty object to finmatch_rate_cards so a previously cached catalogue cannot leak regulated product data. Calculator and headless Apply still run; the shopper never picks a credit product.

Fail-safe: missing runtime fcaStatus still downloads. merchant-api stamps profile fcaStatus onto the merchant row on every runtime write. If a Not authorised merchant still fetches finmatch-rate-card.json, re-save Credit products or FCA status. Training: Merchant FCA status.

Intention of travel​

One event-driven credit product catalogue, owned by credit-products-api, consumed by storefront and APIs — no parallel env rate-card files.

Target end state:

  1. Authoring: all live products use transaction_events (+ schema version). Legacy top-level finance fields remain only as legacy_projection where needed for older consumers — not as a second catalogue.
  2. Storage: gs://finmatch-shared/finmatch-rate-card.json remains the backing object (or a successor bucket path) with credit-products-api as the only writer.
  3. Consumption: storefront receives a merchant-scoped slice (via getMerchantConfig or credit-products-api), not a full 253 KB file and not a separate env configs/finmatch-rate-card.json.
  4. Retirement: env configs/finmatch-rate-card.json objects become unused and are deleted after assignment coverage and parity checks; SDK applySharedRateCardFallback and container/FA special-case top-ups are removed.

This programme is tracked as Step 4 in the egress / versioned-assets agent brief. Step 1 (remove JSON cache-busters on shared top-up fetches) is safe only while shared remains authoritative for those products; Steps 4–5 deliver the structural fix.

Measured inventory, the four merchants that block retiring the env mirrors, and the gated migration phases: SSOT consolidation plan (unlisted until sign-off).

Not in this phase: inventing a second GCS catalogue; reintroducing env-bucket writes from git sync.