openapi: 3.2.0 info: title: Fat Zebra Partner Acquirer connections API version: 1.0.0 summary: Partner-facing API for boarding and managing sub-merchants and their acquirer connections. description: "The Partner API lets you (a Fat Zebra partner) create and manage your own\nmerchants, board them onto acquirers, and manage the resulting acquirer\nconnections. You pick an acquirer (your bank relationship); Fat Zebra\ndecides which processors carry it.\n\n## Base URL\n\n```\nhttps://gateway.pmnts.io/v2/partners\n```\n\nAll paths below are relative to that base. Sandbox and staging hosts are in\nthe server list; pick the one for your environment.\n\n## Auth\n\nHTTP Basic. Send your reseller **username** as the Basic username and your\nreseller API **token** as the Basic password\n(`Authorization: Basic `). Every endpoint requires\nit.\n\n## Boarding is synchronous\n\nBoarding a merchant onto an acquirer is synchronous: an acquirer connection\nexists only once it is boarded, so it is always live. A board that can't\ncomplete is reported inline as the POST's `422` error response.\n\n## Envelopes\n\n* **Single resource** — returned as the resource itself, no wrapper.\n* **List** — `{ \"items\": [...], \"next_cursor\": }`. A `null`\n `next_cursor` means the last page; otherwise pass its value as\n `starting_after` to fetch the next page. List query params are `limit`\n (default 25, max 100) and `starting_after=`.\n* **Error** — `{ \"error\": { \"type\", \"message\", \"fields\", \"request_id\" } }`.\n `type` is the coarse class; the specific reason lives in `fields`, keyed by\n a processor-agnostic field name (e.g. `mid`, `tid`, `currencies`) so you\n never read a switch's native field paths. `type` values and statuses:\n `authentication_error` (401), `not_found` (404), `conflict` (409),\n `validation_error` (422 — something the caller can fix, including a\n processor rejecting a field like the MID/TID), `processor_error` (422 —\n an unactionable upstream failure: a processor was unreachable, busy, or\n rejected us for a reason the caller can't fix; retry or escalate,\n `fields` is empty).\n\nTimestamps are ISO 8601 UTC. Merchants and partners are addressed by their\n`username`. An acquirer connection's `id` is a derived merchant+acquirer\nvirtual id of the form `-ACQ-` (e.g.\n`042-ACQ-NAB`) — not a stored id. Wallets and users carry a stable generated\nid of the form `--` (e.g. `042-WAL-9f3k2m8q`).\nAcquirers are slug codes (e.g. `nab`, `cba`, `anz`).\n" servers: - url: https://gateway.pmnts.io/v2/partners description: Production - url: https://gateway.pmnts-sandbox.io/v2/partners description: Sandbox - url: https://gateway.pmnts-staging.io/v2/partners description: Staging - url: https://gateway.test/v2/partners description: Local development security: - PartnerBasicAuth: [] tags: - name: Acquirer connections description: A merchant's connections to acquirers — board, list, update, enable/disable. paths: /merchants/{username}/acquirers: parameters: - $ref: '#/components/parameters/Username' get: tags: - Acquirer connections summary: List a merchant's acquirer connections description: 'Returns the merchant''s acquirer connections newest-first in the list envelope. ' operationId: listAcquirerConnections parameters: - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/StartingAfter' responses: '200': description: Acquirer connections list envelope. content: application/json: schema: $ref: '#/components/schemas/AcquirerConnectionListEnvelope' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' post: tags: - Acquirer connections summary: Board a merchant onto an acquirer (synchronous) description: "Boards the merchant onto an acquirer synchronously and returns the\nresulting connection with `201`. There is no pending state.\n\nYou name an `acquirer` (your bank relationship) and the\nacquirer-assigned `merchant_id` (MID), plus the\n`terminal_id` (TID) when the acquirer needs one. Fat Zebra validates the MID/TID and `currencies`\nagainst its config and boards the merchant onto every processor behind\nthat acquirer that can carry a requested currency — you never name a\nprocessor. Omit `currencies` to board everything the acquirer supports.\n\nBoarding is idempotent: re-posting the same acquirer returns the\nexisting connection rather than creating a duplicate.\n\nFailures are reported inline:\n\n* `422 validation_error` — an unsupported currency, a missing\n `merchant_id`, or no\n processor supports the acquirer for the requested currencies. The\n offending fields are listed under `error.fields`.\n* `422 processor_error` — an underlying processor board was rejected or\n errored upstream.\n* `404 not_found` — the acquirer is unknown or not available to this\n partner.\n" operationId: boardAcquirer requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AcquirerConnectionCreateRequest' responses: '201': description: The boarded connection. content: application/json: schema: $ref: '#/components/schemas/AcquirerConnection' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/ValidationError' /merchants/{username}/acquirers/{conn_id}: parameters: - $ref: '#/components/parameters/Username' - $ref: '#/components/parameters/ConnId' get: tags: - Acquirer connections summary: Show an acquirer connection operationId: showAcquirerConnection responses: '200': description: The acquirer connection. content: application/json: schema: $ref: '#/components/schemas/AcquirerConnection' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: tags: - Acquirer connections summary: Update an acquirer connection description: 'Patches the mutable fields only: `priority`, `currencies`, `card_types`. Changing `currencies` / `card_types` re-evaluates which underlying processors stay active. `card_types` is narrowed to each processor''s routable set, so a PATCH can''t enable a scheme the acquirer can''t settle. The `acquirer` and the MID/TID (`merchant_id` / `terminal_id`) are immutable once the connection exists. ' operationId: updateAcquirerConnection requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AcquirerConnectionUpdateRequest' responses: '200': description: The updated connection. content: application/json: schema: $ref: '#/components/schemas/AcquirerConnection' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/ValidationError' /merchants/{username}/acquirers/{conn_id}/enable: parameters: - $ref: '#/components/parameters/Username' - $ref: '#/components/parameters/ConnId' post: tags: - Acquirer connections summary: Enable an acquirer connection description: 'Flips `enabled` to `true` across the underlying links. The routing toggle only — config and MID/TID are untouched. No body is expected. ' operationId: enableAcquirerConnection responses: '200': description: The enabled connection. content: application/json: schema: $ref: '#/components/schemas/AcquirerConnection' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /merchants/{username}/acquirers/{conn_id}/disable: parameters: - $ref: '#/components/parameters/Username' - $ref: '#/components/parameters/ConnId' post: tags: - Acquirer connections summary: Disable an acquirer connection description: 'Flips `enabled` to `false` across the underlying links — turns a boarded connection off for routing without deleting it. Config and MID/TID are untouched. No body is expected. ' operationId: disableAcquirerConnection responses: '200': description: The disabled connection. content: application/json: schema: $ref: '#/components/schemas/AcquirerConnection' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' components: parameters: StartingAfter: in: query name: starting_after description: Cursor — the id of the last item from the previous page. Omit for the first page. required: false schema: type: string Limit: in: query name: limit description: Page size. Defaults to 25, capped at 100. required: false schema: type: integer minimum: 1 maximum: 100 default: 25 ConnId: in: path name: conn_id description: Acquirer-connection id — the derived merchant+acquirer virtual id (e.g. `042-ACQ-NAB`). required: true schema: type: string Username: in: path name: username description: The merchant's username (e.g. `acme-store`). required: true schema: type: string schemas: Error: type: object required: - error properties: error: type: object required: - type - message - fields - request_id properties: type: type: string description: Machine-readable error category. enum: - authentication_error - not_found - conflict - validation_error - processor_error message: type: string description: Human-readable explanation of the error. fields: type: object additionalProperties: type: array items: type: string description: Per-field validation messages. Empty object when not field-specific. request_id: type: - string - 'null' description: Correlation id for this request, for support and tracing (e.g. `req_a1b2c3`). AcquirerConnectionListEnvelope: allOf: - $ref: '#/components/schemas/ListEnvelope' - type: object properties: items: type: array items: $ref: '#/components/schemas/AcquirerConnection' AcquirerConnectionUpdateRequest: type: object description: 'Only `priority`, `currencies` and `card_types` are mutable. Changing `currencies` / `card_types` re-evaluates which underlying processors stay active. The `acquirer` and the MID/TID are immutable. ' example: priority: 10 currencies: - AUD - NZD card_types: - visa - mastercard properties: priority: type: integer currencies: type: array items: type: string pattern: ^[A-Za-z]{3}$ description: ISO-4217 currency code (e.g. `AUD`). card_types: type: array description: 'Narrowed to the acquirer''s routable set; schemes the acquirer can''t settle are dropped rather than applied. ' items: type: string AcquirerConnection: type: object description: 'The combined state across every acquirer link provisioned for one acquirer. Boarding is synchronous, so a connection that exists is always boarded. ' required: - acquirer_name - status properties: acquirer_name: type: - string - 'null' description: The acquirer's display name (e.g. `NAB`). merchant_id: type: - string - 'null' description: The acquirer-assigned MID (e.g. `ent_a1b2c3d4`). terminal_id: type: - string - 'null' description: 'The acquirer-assigned TID (e.g. `T0001`), or a Fat Zebra-generated 8-character placeholder (e.g. `ACMEC001`) if none was supplied at board time. Immutable once set. ' currencies: type: array description: Currencies the connection can transact. items: type: string description: ISO-4217 currency code (e.g. `AUD`). schemes: type: array description: Networks the merchant can transact for this acquirer. items: type: string description: Card scheme name (e.g. `Visa`, `Mastercard`). modes: type: array description: Transaction modes the connection supports. items: type: string description: Transaction mode (e.g. `Purchase`, `Auth/Capture`). wallets: type: array description: Wallets the connection accepts. items: type: string description: Wallet type (e.g. `ApplePay`, `GooglePay`, or `ALL`). three_ds_enabled: type: boolean description: Whether a boarded processor for this acquirer supports 3DS. status: type: string enum: - enabled - disabled description: Routing toggle across the underlying links — disable to turn the connection off without deleting it. AcquirerConnectionCreateRequest: type: object required: - acquirer - merchant_id description: 'Board onto an acquirer. Name the `acquirer` and send the acquirer-assigned `merchant_id` (MID); `terminal_id` (TID) is optional. Fat Zebra validates the MID/TID and `currencies` against its config and boards the merchant onto every supporting processor behind the acquirer — you never name a processor. ' example: acquirer: nab merchant_id: MID0012345 terminal_id: '12345678' currencies: - AUD properties: acquirer: type: string description: Required. Acquirer code (e.g. `nab`). merchant_id: type: string description: The acquirer-assigned MID. Required. terminal_id: type: string description: 'The acquirer-assigned TID. Optional. If omitted, 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: type: array description: Optional. Defaults to every currency the acquirer supports. items: type: string pattern: ^[A-Za-z]{3}$ description: ISO-4217 currency code (e.g. `AUD`). ListEnvelope: type: object required: - items - next_cursor properties: items: type: array description: The page of results. Each list endpoint overrides the item type. next_cursor: type: - string - 'null' description: Id to pass as `starting_after` for the next page; `null` on the last page. responses: Unauthorized: description: Missing or invalid HTTP Basic credentials. content: application/json: schema: $ref: '#/components/schemas/Error' examples: invalidToken: value: error: type: authentication_error message: Invalid or missing token fields: {} request_id: req_a1b2c3 NotFound: description: Resource not found. content: application/json: schema: $ref: '#/components/schemas/Error' examples: notFound: value: error: type: not_found message: Couldn't find merchant fields: {} request_id: req_a1b2c3 ValidationError: description: '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. ' content: application/json: schema: $ref: '#/components/schemas/Error' examples: merchantValidation: summary: The merchant details were rejected value: error: type: validation_error message: the merchant details were rejected fields: company_name: - can't be blank postcode: - is not a valid postcode request_id: req_a1b2c3 unsupportedCurrency: summary: A currency the acquirer can't carry value: error: type: validation_error message: currency not supported by this acquirer fields: currencies: - NZD is not supported by this acquirer request_id: req_a1b2c3 missingConnectionFields: summary: Missing a required connection field value: error: type: validation_error message: 'missing required connection fields: merchant_id, terminal_id' fields: merchant_id: - is required terminal_id: - is required request_id: req_a1b2c3 noSupportingProcessor: summary: No processor can carry the acquirer for the requested currencies value: error: type: validation_error message: no processor can carry this acquirer for the requested currencies fields: acquirer: - cannot be boarded for the requested currencies request_id: req_a1b2c3 processorRejectedMid: summary: A processor rejected a field (here, the MID) — caller-fixable value: error: type: validation_error message: the connection details were rejected fields: mid: - is not supported request_id: req_a1b2c3 processorUnavailable: summary: A processor is busy/errored — not the caller's to fix value: error: type: processor_error message: a processor is temporarily unavailable fields: {} request_id: req_a1b2c3 securitySchemes: PartnerBasicAuth: type: http scheme: basic description: 'HTTP Basic. Send your reseller **username** as the Basic username and your reseller API **token** as the Basic password. Required on every endpoint. '