Merchant onboarding & KYB

Before a merchant can process a single payment, acquiring rules require know-your-business (KYB) verification. You create the merchant with one API call; Finscale collects the verification data, runs the checks, and reports every state change as an event. This page walks the lifecycle from created to active — and what restricted and suspended mean when monitoring flags something.

The KYB lifecycle

Every merchant moves through one state machine, exposed as kyb_status on the Merchant object. Verification states move forward; under_review can bounce back to kyb_pending when the checks need more information, and monitoring can move an active merchant to restricted or suspended at any time.

create created kyb_pending under_review active onboarding info complete checks pass more info needed restricted suspended action required resolved severe escalate reinstatement review verified — MID assigned some capabilities paused all activity paused
kyb_statusMeaningCan process?
createdThe record exists; no verification data yet.No
kyb_pendingWaiting on required information or documents from the merchant.No
under_reviewChecks are running. May return to kyb_pending if more information is needed.No
activeVerified. Capabilities activate and a mid is assigned.Yes
restrictedAction required; some capabilities are paused until it's resolved.Partially
suspendedAll activity paused — no payments, no payouts.No

Start onboarding

Create the merchant with its registered legal identity and a four-digit ISO 18245 merchant category code (MCC) describing its line of business. legal_name and country are fixed after creation — a different legal entity is a new merchant.

POST /v1/merchants
curl https://api.finscale.dev/v1/merchants \
  -H "Authorization: Bearer sk_test_51FinscaleDemo…" \
  -H "Idempotency-Key: idem_mch_aurora_01" \
  -H "Content-Type: application/json" \
  -d '{
    "legal_name": "Aurora Retail B.V.",
    "trading_name": "Aurora",
    "country": "NL",
    "mcc": "5734"
  }'

# 201 Created
{
  "id": "mch_7Rq3wN8dK2Vs",
  "object": "merchant",
  "legal_name": "Aurora Retail B.V.",
  "trading_name": "Aurora",
  "country": "NL",
  "mcc": "5734",
  "mid": null,
  "kyb_status": "kyb_pending",
  "capabilities": {
    "card_payments": "pending",
    "local_methods": "pending",
    "payouts": "inactive"
  },
  "livemode": false,
  "created_at": "2026-07-16T08:02:19Z"
}

The merchant comes back in kyb_status: kyb_pending with capabilities pending or inactive and no mid yet. From here, Finscale collects the required verification data and documents through hosted onboarding — you don't build document-upload flows or talk to registries. Track progress via merchant.updated events or by polling GET /v1/merchants/{id}.

What KYB verifies

The checks are the ones anti-money-laundering regulation and card-scheme rules require before an entity may accept payments:

  • Legal existence. The entity is registered, in good standing, and legal_name matches the registry of its country of incorporation.
  • Ownership. Ultimate beneficial owners (UBOs) and directors are identified and verified.
  • Screening. The entity and its owners are screened against sanctions and watchlists — at onboarding and continuously afterwards.
  • Line of business. What the merchant actually sells matches the declared mcc and is acceptable under scheme and provider rules.
  • Settlement account. The bank account that will receive payouts belongs to the verified entity.

Most merchants clear the checks without intervention. When a check can't complete automatically, the merchant returns to kyb_pending with a request for more information — each bounce fires a merchant.updated event, so your onboarding UI can react without polling.

Activation: MCC & MID

When the checks pass, kyb_status becomes active and two things happen:

  1. The MCC is confirmed

    You declare an mcc at creation; review validates it against the merchant's real line of business and corrects it if it's wrong — a mismatched MCC is a scheme-compliance problem, not a cosmetic one. Changing mcc later (via update) can send the merchant back to under_review.

  2. A MID is provisioned

    The merchant gets a mid — its merchant id at the acquiring level. This is the identifier that appears in scheme clearing records and settlement reports, and it's how you tie a settlement line back to a specific merchant. mid is null in every state before active.

Capabilities activate at the same time — usually together, but they can stagger: card_payments may go active while payouts stays pending on the bank-account check. Gate each feature of your product on its capability, not on kyb_status.

After activation: restricted & suspended

Verification doesn't end at active. Screening reruns continuously, registry data goes stale, and transaction monitoring watches live volume. When something needs attention, the merchant moves to restricted: the affected capabilities pause, and the dashboard shows exactly what's needed — an expired document, an ownership change to re-verify, activity that doesn't match the declared line of business. Resolve it and the merchant returns to active.

suspended is the severe case — confirmed sanctions hits, fraud findings, unresolved restrictions. All activity pauses: no payments, no payouts. Reinstatement goes back through review, not through a support ticket.

Treat restricted as a deadline, not a warning A restricted merchant is one unresolved request away from suspended. Surface the required action to the merchant the moment the merchant.updated event arrives — waiting for them to notice a failed payout is the slow path.

Webhook events

Every change to kyb_status or a capability fires merchant.updated with the full Merchant object in its new state:

merchant.updated — checks passed
{
  "id": "evt_5s8Y2kLmN0Ta",
  "object": "event",
  "type": "merchant.updated",
  "created_at": "2026-07-18T14:11:47Z",
  "livemode": false,
  "data": {
    "object": {
      "id": "mch_7Rq3wN8dK2Vs",
      "object": "merchant",
      "kyb_status": "active",
      "mid": "845512000318",
      "capabilities": {
        "card_payments": "active",
        "local_methods": "active",
        "payouts": "active"
      }
    }
  }
}

data.object abridged — deliveries carry the complete Merchant object. Events are not ordered; derive state from the object, not from arrival sequence. See Webhooks → Ordering.

Error scenarios

ScenarioResponse
Invalid mcc (not four digits) or country (not ISO 3166-1 alpha-2) 400invalid_request_error
Retrieving or updating a merchant id that doesn't exist 404invalid_request_error
Reusing an Idempotency-Key with a different payload 409idempotency_error
Processing attempted for a merchant whose relevant capability isn't active 400invalid_request_error; activate the capability first

Field-by-field details of the object and every endpoint are on the Merchant API page; where the mid shows up downstream is covered in Settlement & payouts and Reconciliation.