---
title: "Create a merchant"
method: POST
path: "/merchants"
tags: ["Merchants"]
---

# Create a merchant

`POST /merchants`

## Request

- Base URL: `https://gateway.pmnts.io/v2/partners`
- URL: `https://gateway.pmnts.io/v2/partners/merchants`
- Auth: HTTP basic

Creates a merchant. By default (no `acquirers` in the body) the merchant
is identity-only: `status` is `pending`, no processing connection is
attached, and a fresh API token is generated. The merchant can't take
payments until a processing connection is boarded and the merchant is
activated. Pass an `acquirers` array to create and board in one call
(see **Combined create-and-board** below).

The response is `201` with the merchant object and a one-time
`credentials.token`. The token is shown once here and never again on
reads — store it.

`username` may be omitted; one is derived from the trading/business
name. Either way the stored username is prefixed with the partner's
reseller prefix.

A create is rejected with `409 conflict` (`"merchant exists"`) when this
partner already has a merchant with the same ABN, business name and
trading name — a repeated submit of the same business. A shared ABN
alone is allowed: it creates a new merchant.

**Combined create-and-board.** When the body carries an `acquirers`
array, the merchant is created, every named acquirer is boarded, and
the merchant is activated — all in one call. If any acquirer can't be
boarded the whole request fails and nothing is created: no merchant,
no connections. The failure is reported the same way as the standalone
board endpoint:

* `422 validation_error` — something the caller can fix: an unsupported
  currency or card type, a duplicate/missing `merchant_id`, no processor
  supports the acquirer for the requested currencies, or a processor
  rejecting a field (e.g. the MID). `fields` names the offending field.
* `422 processor_error` — an unactionable upstream failure: a processor
  was unreachable, busy, or rejected the board for a reason the caller
  can't fix. `fields` is empty; retry or escalate.
* `404 not_found` — an acquirer is unknown or not available to this
  partner.

**Idempotency and retries.** Boarding is synchronous and recovery is
always the partner re-issuing a call. Safe-retry behaviour is built
into the operations themselves:

* **Identity create** dedupes on the triple `(ABN, business name,
  trading name)` — re-posting the same business returns `409 conflict`
  (`"merchant exists"`) instead of producing a duplicate. A shared
  ABN alone is allowed and creates a new merchant.
* **Combined create-and-board** either creates the merchant and every
  requested connection, or creates nothing. On failure the partner
  re-issues the same request — there is no partial state to clean up.
* **Standalone board** (`POST /merchants/{username}/acquirers`) is
  idempotent per acquirer: re-posting the same `acquirer` against a
  merchant that already has it returns the existing connection
  instead of creating a duplicate. A `processor_error` retry is safe
  for the same reason.

**What to do on each failure**:

* `422 validation_error` → read `fields`, correct the named input
  (currency, MID, card type, etc.), POST again. Idempotency makes a
  corrected retry safe.
* `422 processor_error` → the request itself is fine; the upstream
  processor isn't. Back off and re-post the identical request, or
  escalate if it persists. Don't mutate the payload.
* `409 conflict` on create → the merchant already exists for this
  partner; fetch it with `GET /merchants/{username}` instead of
  re-creating.

## Request body

- MerchantCreateRequest: Creates a merchant. Required to CREATE: `name` and `mcc` only. `mcc` has NO default — the merchant's category is never guessed; omitting it is a `422 validation_error`. Two modes: - **Identity-only** (no `acquirers`): creates a `pending` stub with no processing. Board acquirers later via `POST /merchants/{username}/acquirers`. Returns a bare `Merchant`. - **Combined create** (with `acquirers`): also boards each listed acquirer and activates the merchant if at least one boards. Boarding is best-effort — failures don't fail the create; each acquirer's outcome is reported in the `MerchantOnboardingResult`. The merchant is `active` when ≥1 acquirer boards, else stays `pending`. Either way the response is `201` with the token revealed once. Readiness — "required to create" is not "required to transact". To board an acquirer the merchant may need extra business details, depending on how the acquirer is boarded: The partner always supplies the acquirer-assigned MID on the connection (TID is optional). Some acquirers also require additional business details to board — `company_number`, `trading_name` and `address`. Missing fields surface as a `failed` acquirer entry (combined create) or a `422` on `POST /merchants/{username}/acquirers`.
  - `name` string, required: Required. The merchant's legal/business name.
  - `mcc` string, required: Required. Merchant category code (ISO 18245, 4 digits). No default — omitting or blanking it returns `422 validation_error`.
  - `trading_name` string: Optional at create (defaults to `name`). May be required to board some acquirers.
  - `company_number` string: The merchant's company/business registration number (e.g. an Australian Business Number). Optional at create. May be required to board some acquirers.
  - `industry` string: Optional. Free-text industry descriptor for the merchant.
  - `contact` string: Optional. Primary contact person's name.
  - `website` string: Optional.
  - `email` string, email: Optional.
  - `accounts_email` string[]: Optional. Accounts/billing email recipients.
  - `phone` string: Optional.
  - `address` Address
    - `line1` string, nullable: First line of the street address (e.g. `1 Market St`).
    - `line2` string, nullable: Second address line (e.g. `Level 4`).
    - `city` string, nullable: Suburb or city (e.g. `Sydney`).
    - `state` string, nullable: State or territory (e.g. `NSW`).
    - `postcode` string, nullable: Postal code (e.g. `2000`).
    - `country` string, nullable: ISO-3166 alpha-2 country code (e.g. `AU`).
  - `statement_descriptor` string: Optional. Card-acceptor name. Defaults to the trading/business name, truncated to 25 chars.
  - `government_controlled` boolean: Optional. Whether the merchant is government-controlled. Defaults to false.
  - `country_of_origin` string: Optional. ISO-3166 alpha-2 country of origin.
  - `country_code` string: Optional. ISO-3166 numeric country code.
  - `fee_program_indicator` string: Optional. Scheme fee program indicator.
  - `mastercard_iso_id` string: Optional. Mastercard ISO/acquirer identifier.
  - `visa_iso_id` string: Optional. Visa ISO/acquirer identifier.
  - `mastercard_assigned_id` string: Optional. Mastercard Assigned ID (MAID).
  - `visa_merchant_verification_value` string: Optional. Visa Merchant Verification Value (MVV).
  - `visa_marketplace_identifier` string: Optional. Visa Marketplace Identifier (MPI) for marketplace merchants.
  - `visa_payment_facilitator_indicator` string: Optional. Visa payment facilitator indicator for scheme rules.
  - `mastercard_payment_facilitator_indicator` string: Optional. Mastercard payment facilitator indicator for scheme rules.
  - `bill_payment_provider` boolean: Optional. Whether the merchant is a Bill Payment Service Provider (BPSP). Defaults to false.
  - `aggregator_fields_enabled` boolean: Optional. Allow sub-merchant aggregator fields in transaction requests (requires an aggregator agreement with the acquirer). Defaults to false.
  - `customer_support_phone` string: Optional. Customer support phone number shown to cardholders.
  - `card_acceptor_name` string: Optional. Card-acceptor name sent to the card schemes. Defaults to the statement descriptor / trading name when omitted.
  - `card_acceptor_location` string: Optional. Card-acceptor location (city) sent to the card schemes.
  - `card_acceptor_country` string: Optional. Card-acceptor country, ISO-3166 alpha-2.
  - `timezone` string: Optional. IANA timezone identifier the merchant operates in.
  - `merchant_identifier` string: Optional. A partner-assigned identifier for the merchant. Distinct from the acquirer-assigned `merchant_id` (MID) — this is a free-form label the partner uses to track the merchant in their own systems.
  - `username` string: Optional. When omitted, one is derived from the trading/business name. Either way the stored username is prefixed with the partner's reseller prefix. Immutable post-creation.
  - `acquirers` AcquirerBoardRequest[]: Optional. When present, boards the merchant onto each acquirer and activates it (combined create). If any acquirer can't be boarded the whole create fails and nothing is created. See the response `MerchantOnboardingResult`.
    - `acquirer` string, required: Acquirer code (e.g. `bnz`). Must be available to the partner.
    - `merchant_id` string, required: Acquirer-assigned MID. Required.
    - `terminal_id` string: Acquirer-assigned TID. Optional. If you omit it, Fat Zebra generates a deterministic 8-character placeholder from the merchant's trading name (e.g. `ACMEC001`) and uses it across every processor behind this acquirer. The generated value is returned on subsequent reads, and once set — supplied or generated — it is immutable.
    - `currencies` string[]: Optional. Defaults to everything the acquirer supports.
    - `card_types` string[]: Optional. Card schemes the connection should accept. Narrowed to what this acquirer supports — schemes the acquirer can't handle are dropped rather than rejected. Omit to accept every scheme the acquirer supports.
    - `card_categories` string[]: Optional. Card categories the link handles; overrides the link default.
    - `merchant_tier` string: Optional. Merchant tier; used by the EFTPOS Direct acquirer.
    - `mpgs_byo_profile` boolean: Optional. Marks the MPGS link as bring-your-own profile.

## Response `201`

Created merchant, with a one-time token. An identity-only create
(no `acquirers`) returns a bare `Merchant`. A combined create (with
`acquirers`) returns a `MerchantOnboardingResult` — a slim payload of
the merchant's status, username and token plus a per-acquirer
boarding status list. A `201` means the merchant and every requested
acquirer boarded; a boarding failure rolls the whole create back and
returns the relevant error below.

- union
  - Merchant: A merchant under this partner.
    - `id` string, required: The merchant's username (e.g. `acme-store`).
    - `status` 'pending' | 'active' | 'suspended' | 'closed', required: The merchant's lifecycle state.
    - `name` string, nullable: The merchant's legal/registered business name (e.g. `Acme Pty Ltd`).
    - `trading_name` string, nullable: The name the merchant trades under (e.g. `Acme Store`).
    - `company_number` string, nullable: The merchant's company/business registration number (e.g. an Australian Business Number, `51824753556`).
    - `website` string, nullable: The merchant's website URL (e.g. `https://acme.example`).
    - `mcc` string, nullable: Merchant category code — ISO 18245, 4 digits (e.g. `5411`).
    - `email` string, email, nullable: Contact email address (e.g. `ops@acme.example`).
    - `phone` string, nullable: Contact phone number in E.164 format (e.g. `+61730000000`).
    - `address` Address
      - `line1` string, nullable: First line of the street address (e.g. `1 Market St`).
      - `line2` string, nullable: Second address line (e.g. `Level 4`).
      - `city` string, nullable: Suburb or city (e.g. `Sydney`).
      - `state` string, nullable: State or territory (e.g. `NSW`).
      - `postcode` string, nullable: Postal code (e.g. `2000`).
      - `country` string, nullable: ISO-3166 alpha-2 country code (e.g. `AU`).
    - `three_d_secure_enabled` boolean: Whether 3-D Secure is enabled for the merchant.
    - `fraud_screening_enabled` boolean: Whether fraud screening is enabled for the merchant.
    - `network_tokenisation_enabled` boolean: Whether network tokenisation (Visa VTS / Mastercard MDES) is enabled.
    - `wallets` string[]: Digital wallets enabled for the merchant.
    - `surcharging` MerchantSurcharging
      - `enabled` boolean: Whether card surcharging is enabled for the merchant.
    - `statement_descriptor` string, nullable: Card-acceptor name shown on the cardholder's statement, max 25 chars (e.g. `ACME STORE`).
    - `government_controlled` boolean: Whether the merchant is a government-controlled entity.
    - `country_of_origin` string, nullable: ISO-3166 alpha-2 country of origin (e.g. `AU`).
    - `country_code` string, nullable: ISO-3166 numeric country code (e.g. `036` for Australia).
    - `fee_program_indicator` string, nullable: Scheme fee program indicator (e.g. `S`).
    - `mastercard_iso_id` string, nullable: Mastercard ISO/acquirer identifier (e.g. `00001234`).
    - `visa_iso_id` string, nullable: Visa ISO/acquirer identifier (e.g. `00005678`).
    - `mastercard_assigned_id` string, nullable: Mastercard Assigned ID (MAID) (e.g. `MAID12345`).
    - `visa_merchant_verification_value` string, nullable: Visa Merchant Verification Value (MVV) (e.g. `MVV98765`).
    - `customer_support_phone` string, nullable: Customer support phone number shown to cardholders (e.g. `+61 7 1234 5678`).
    - `card_acceptor_name` string, nullable: Card-acceptor name sent to the card schemes (e.g. `ACME STORE`).
    - `card_acceptor_location` string, nullable: Card-acceptor location/city sent to the card schemes (e.g. `BRISBANE`).
    - `card_acceptor_country` string, nullable: Card-acceptor country, ISO-3166 alpha-2 (e.g. `AU`).
    - `timezone` string, nullable: IANA timezone identifier the merchant operates in.
    - `merchant_identifier` string, nullable: A partner-assigned identifier for the merchant. Distinct from the acquirer-assigned `merchant_id` (MID) — this is a free-form label the partner uses to track the merchant in their own systems.
    - `credentials` MerchantCredentialsInline: Credentials embedded on the merchant object. `token` is `null` on reads and only populated once by create and credential-rotate.
      - `username` string, required: The merchant's username (e.g. `acme-store`).
      - `token` string, nullable, required: The live API token (e.g. `tok_live_3b9c1d…`). `null` except on create / rotate.
    - `created_at` string, date-time, nullable: When the merchant was created — ISO 8601 UTC (e.g. `2026-05-29T04:21:00Z`).
    - `updated_at` string, date-time, nullable: When the merchant was last updated — ISO 8601 UTC (e.g. `2026-05-29T04:21:00Z`).
  - MerchantOnboardingResult: Returned by a combined create (`POST /merchants` with `acquirers`). A slim status payload — the merchant's status, username and one-time token, plus a per-acquirer boarding status list. When this result is returned every requested acquirer boarded (`status: success`); a boarding failure fails the whole create and returns an error instead. Read the full merchant via `GET /merchants/{username}` and connections via `GET /merchants/{username}/acquirers`.
    - `status` 'pending' | 'active' | 'suspended' | 'closed', required: `active` — every requested acquirer boarded and the merchant was activated.
    - `username` string, required: The merchant's username.
    - `token` string, nullable: The one-time API token, revealed once on create.
    - `acquirers` object[], required: Per-acquirer boarding outcome — one entry per requested acquirer, all `success`.
      - `acquirer` string, required: The acquirer code from the request (e.g. `nab`).
      - `status` 'success' | 'failed', required: Always `success` on this result — a failure fails the whole create instead.
      - `reason` string: Why boarding failed. Not populated on this result.

## Other responses

- `401`: Missing or invalid HTTP Basic credentials.
- `404`: Resource not found.
- `409`: The request conflicts with the resource's current state.
- `422`: The request couldn't be completed. A `validation_error` is something the caller can fix — a bad payload, a merchant that failed validation, or a processor rejecting a field (e.g. the MID); the reason is in `fields`, keyed by a processor-agnostic field name. A `processor_error` is an unactionable upstream failure (a processor was unreachable, busy, or errored); `fields` is empty and the caller should retry or escalate. Raw upstream detail is never surfaced here — only a parsed, processor-neutral reason.

---

[API](https://skmtc.dev/fatzebra/apis/fat-zebra-partner-api.md) - [All operations](https://skmtc.dev/fatzebra/apis/fat-zebra-partner-api/llms.txt) - [OpenAPI document](https://skmtc.dev/fatzebra/apis/fat-zebra-partner-api/revisions/10f1181ea916?raw)
