Skip to content
In this section

Vendors

Onboard sub-merchants (vendors) under a platform account — create, screen, and pay marketplace vendors through the REST API.

A vendor is a sub-merchant you onboard under your platform account in the merchant-of-record model: your buyers pay you, and you pass each vendor its share. Fynex screens every vendor from the details you supply, holds it to a cumulative payout limit until it completes verification, and gives you one payee per vendor to pay it through.

The vendor surface is available to Platform accounts only, using the platform's own API key. A merchant account, or a delegated dashboard session, receives 403 platformRequired.

Note

These endpoints are enabled per environment. If POST /payments-api/v1/vendors answers 404 on your account, ask support to enable vendor onboarding for you.


Lifecycle

Every vendor response carries a verification block. verification.status is the one field to branch on:

verification.status Meaning payoutsEnabled
pending_fynex Fynex is screening (reason: screening) or reviewing. Nothing for you or the vendor to do. false
not_required Screening passed; no verification step is due. true, under the cumulative limit
required The vendor must complete a step. Fetch the link with POST /vendors/{vendor_id}/verification-link and hand it to the vendor. true until the limit is reached
in_progress The vendor has started the step. unchanged
complete Fully verified; the cumulative limit no longer applies. true
blocked Refused at screening (reason: screening_refused), declined at verification (reason: declined) or manually blocked (reason: blocked). false, permanently

Screening is non-interactive: the vendor is not contacted and uploads nothing. You supply the identity (company number + country, or name + date of birth + country) and Fynex screens it against sanctions, politically-exposed-person and adverse-media lists. It usually completes within the request; otherwise poll GET /vendors/{vendor_id} until verification.status leaves pending_fynex.

paymentsEnabled is always false: in the merchant-of-record model the vendor never takes a payment itself.


Create a vendor

POST /payments-api/v1/vendors
Authorization: Bearer <platform_sk_key>
Content-Type: application/json

{
  "externalRef": "vendor_8817",
  "entityType": "company",
  "displayName": "Blue Door Ceramics Ltd",
  "contactEmail": "owner@bluedoor.example",
  "country": "GB",
  "companyNumber": "09876543",
  "merchantCategoryCode": "5999",
  "storefrontUrl": "https://market.example/shops/blue-door",
  "address": { "street": "1 High Street", "city": "Edinburgh", "postalCode": "EH1 1AA" },
  "consent": { "sumsubPrivacyNoticeAccepted": true, "acceptedAt": "2026-09-03T12:00:00Z", "ip": "203.0.113.7", "noticeVersion": "2026-07" }
}

For an individual (sole trader), send "entityType": "individual" with a person object instead of companyNumber:

"person": { "firstName": "Jane", "lastName": "Maker", "dob": "1990-04-12" }

dob is required (YYYY-MM-DD; the vendor must be at least 18). displayName is the registered name for a company and the trading name for an individual. merchantCategoryCode is the four-digit MCC describing what the vendor sells; it is required and screened. storefrontUrl is the vendor's page on your marketplace (https). consent is your attestation that the vendor accepted the verification provider's privacy notice on your side; it is required (422 consentRequired) once consent enforcement is on for your environment, and recorded whenever you send it.

{
  "vendorId": "7c1f8a2e-6b3d-4e5f-9a0b-1c2d3e4f5a6b",
  "externalRef": "vendor_8817",
  "entityType": "company",
  "displayName": "Blue Door Ceramics Ltd",
  "paymentsEnabled": false,
  "payoutsEnabled": false,
  "payeeId": 101,
  "verification": { "status": "pending_fynex", "reason": "screening", "actionUrl": null, "actionExpiresAt": null },
  "payoutAllowance": { "currency": "GBP", "limitMinor": 10000, "usedMinor": 0, "remainingMinor": 10000,
                       "basis": "cumulative_lifetime_all_currencies", "enforcement": "monitored", "unlimited": false, "deferred": false },
  "nextTier": { "limitMinor": null, "unlimited": true,
                "requirements": [ { "code": "screening_passed", "status": "in_progress" },
                                  { "code": "identity_verification", "status": "not_started" },
                                  { "code": "agreement_signed", "status": "not_started" } ] },
  "createdAt": "2026-09-05T12:00:00Z",
  "updatedAt": "2026-09-05T12:00:00Z"
}

201 Created on creation. When the screening completes synchronously the verdict is applied before the response is written, so the first response is often already not_required with payoutsEnabled: true.

Idempotency

externalRef is your identifier for the vendor and is unique within your platform. Re-sending an equivalent request (whitespace and letter case do not count) for the same reference returns the existing vendor with 200 OK — safe to retry after a timeout. The same reference with a different body is 409 externalRefConflict: you are reusing a reference for a different vendor.

Responses

All errors use the standard envelope {"error": "<code>"}. Field-level validation failures name the field: {"error": "person.dob: required; YYYY-MM-DD"}.

Status error When
201 — Vendor created
200 — Idempotent replay of an equivalent request
400 <field>: <reason> A field is missing or malformed
401 Missing or invalid Bearer token
403 platformRequired Your account is not an active platform, or the credential is a delegated dashboard session rather than the platform's own key
409 externalRefConflict externalRef already refers to a vendor created with a different request
422 invalidCountry country is not an ISO 3166-1 alpha-2 code
422 countryNotSupported A real country Fynex does not onboard vendors from
422 mccProhibited The merchant category is prohibited
422 vendorScreeningRefused This vendor cannot be onboarded through the API. Contact support if you believe this is wrong
422 consentRequired Consent enforcement is on and consent.sumsubPrivacyNoticeAccepted was not true
429 dailyVendorLimitReached Daily vendor creation limit for your platform; retry after 24 hours
503 screeningUnavailable Screening is temporarily unavailable. Nothing was created; retry with the same externalRef

The vendor mutation routes also have their own per-platform rate-limit bucket, separate from the general API limit; a 429 carrying Retry-After and the JSON body {"error":"rate limit exceeded; retry after the Retry-After header value","code":"rate_limited"} is that bucket.


Read vendors

GET /payments-api/v1/vendors/{vendor_id}
GET /payments-api/v1/vendors?limit=20&offset=0

The list is newest first and paginated like /payees (limit 1–100, default 20). A vendor that belongs to another platform, or does not exist, is 404 vendorNotFound.


When a vendor's verification.status becomes required — you receive MarketplaceVendorVerificationRequired if you subscribed to the vendor events, and GET /vendors/{vendor_id} shows it — request a link and hand it to the vendor:

POST /payments-api/v1/vendors/{vendor_id}/verification-link
Authorization: Bearer <platform_sk_key>
{ "actionUrl": "https://…", "actionExpiresAt": "2026-09-06T12:00:00Z" }

The vendor opens the link and completes verification with the provider; you are not involved in the flow itself. Every call mints a fresh link (the previous one stays valid until its own expiry), so call it again if the vendor lost theirs. The link is bearer-like: send it over a channel you trust and do not log it.

Status error When
200 — Link minted
403 platformRequired Not the platform's own key
404 vendorNotFound Not your vendor
409 verificationNotRequired No step is due for this vendor
503 screeningUnavailable The provider could not mint a link; retry

As the vendor progresses, verification.status moves through in_progress and pending_fynex to complete (or blocked), and the matching MarketplaceVendorVerification* events fire.

Paying a vendor

Each vendor has exactly one payee (payeeId), owned by your platform account. Use it exactly like any other payee:

  1. Attach bank details: POST /payees/{payee_id}/payout-methods — see Payout methods.
  2. Route the vendor's share: name the payee in a split rule — see Splits.
  3. Pay out: POST /payouts from the payee's wallet — see Payouts.

The payee is disabled while verification.status is pending_fynex and stays disabled if the vendor is blocked: a split naming it is refused at payment time, so no funds can accrue to an unscreened vendor. It is enabled the moment the screening passes.

The cumulative payout limit

A screened vendor may receive up to £100 (or equivalent) in cumulative payouts before it must complete full verification. payoutAllowance shows where the vendor stands: limitMinor and usedMinor in GBP minor units (payouts in other currencies count at the current reference rate), remainingMinor what is left, and enforcement what happens at the boundary — monitored means a crossing is detected after the fact and verification is requested; held_for_review means a payout that would cross the limit waits for Fynex compliance. deferred: true means the total could not be computed right now (a payout currency has no current rate); nothing is enabled or disabled by it.

When a vendor crosses the limit Fynex asks it to verify and notifies you (verification.status: required). Vendors that complete verification show unlimited: true and no longer have a cumulative limit.

nextTier says exactly what lifts the limit: three requirements — screening_passed (Gate 1, automatic), identity_verification (the vendor completes verification via the link above) and agreement_signed (the vendor signs the seller agreement Fynex sends at the crossing) — each complete, in_progress or not_started. Once all three are complete the vendor is unlimited and nextTier.requirements is empty.


What vendors are not

  • A vendor is not a seller account you can authenticate as. It has no API key and no dashboard login; you operate it through your platform key.
  • A vendor is not a payee you create yourself. Creating a payee directly (POST /payees) gives you a payout counterparty without screening; creating a vendor gives you a screened sub-merchant with a payee. Use vendors for sub-merchants whose goods or services your buyers pay you for.