openapi: 3.1.0
info:
  title: Merchants
  version: "1"
  description: Create, update and reactivate merchants, and read their details and
    payment configuration.
tags:
  - name: Merchant details
    description: Read a merchant's profile, owner, business and bank details.
  - name: Payment configuration
    description: Read a merchant's payment provider, fees, limits and payout settings.
  - name: Merchant association
    description: Create, reactivate or update the merchants you onboard.
      Authenticated with a Datman-issued partner API key.
paths:
  /v1/merchants/{merchantId}/summary:
    get:
      operationId: getMerchantSummary
      summary: Get merchant summary
      description: Returns the merchant's name, owning reseller, country and the
        per-section onboarding statuses (account, payout, business, owners,
        bank, terms of service), plus whether the merchant is itself a reseller
        and whether it is liable. The merchant must belong to the reseller that
        owns the API key; any other merchant id returns 404. Returns 404 as well
        when the merchant has no onboarding record.
      tags:
        - Merchant details
      security:
        - ApiKeyAuth: []
      parameters:
        - name: merchantId
          in: path
          required: true
          description: Numeric merchant id. Must be a positive integer belonging to your
            reseller.
          schema:
            type: integer
            minimum: 1
          example: 123456
      responses:
        "200":
          description: Merchant summary.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CpMerchantSummaryResponse"
              examples:
                activeMerchant:
                  summary: Fully onboarded merchant
                  value:
                    data:
                      merchant_id: 123456
                      merchant_name: Example Pizza Co
                      canonical_reseller_id: 42
                      country: United Kingdom
                      account_status: ACTIVE
                      payout_status: ACTIVE
                      business_status: VERIFIED
                      owners_status: VERIFIED
                      bank_status: Verified
                      tos_status: ACCEPTED
                      is_reseller: false
                      is_liable: true
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: The merchant does not belong to your reseller, or it has no
            onboarding record.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                notFound:
                  summary: Merchant not found or not in your reseller
                  value:
                    error:
                      code: NOT_FOUND
                      message: Merchant not found
        "422":
          description: The merchantId path segment is not a positive integer.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                invalidMerchantId:
                  summary: Non-numeric merchant id
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: merchantId is required
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"
    servers:
      - url: https://sandbox-portal.datmanlabs.com/api
        description: Sandbox
  /v1/merchants/{merchantId}/payment-config:
    get:
      operationId: getMerchantPaymentConfig
      summary: Get payment configuration
      description: "Returns the merchant's payment provider, fee tier, your reseller
        pricing on top of the tier, gateway settings and transaction limits. The
        effective limits (`max_transaction`, `xpress_sale_limit`) fall back to
        the country default when the merchant-level value is unset or 0. The raw
        `merchant_*` and `country_*` values are returned separately.
        `buying_rate_*` is your reseller's cost rate for this merchant, and is
        null when no rate is on file. Returns `data: {}` when the merchant has
        no gateway customer record. The merchant must belong to your reseller,
        otherwise 404."
      tags:
        - Payment configuration
      security:
        - ApiKeyAuth: []
      parameters:
        - name: merchantId
          in: path
          required: true
          description: Numeric merchant id. Must be a positive integer belonging to your
            reseller.
          schema:
            type: integer
            minimum: 1
          example: 123456
      responses:
        "200":
          description: Payment configuration. `data` is an empty object when the merchant
            has no gateway customer record.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CpMerchantPaymentConfigResponse"
              examples:
                configured:
                  summary: Merchant with a fee tier and a country-default transaction limit
                  value:
                    data:
                      fee_tier_name: Standard
                      fee_tier_percentage: 1.5
                      fee_tier_fixed: 0.2
                      ext_reseller_percentage_fee: 0.25
                      ext_reseller_fixed_fee: 0.05
                      gateway_name: null
                      billing_address: null
                      hide_gpay_apay: null
                      mid_status: null
                      min_transaction: null
                      max_transaction: 5000
                      xpress_sale_limit: 250
                      daily_limit: null
                      merchant_max_transaction: 0
                      merchant_xpress_sale_limit: 250
                      country_max_transaction: 5000
                      country_xpress_sale_limit: 100
                      fee_tier_id: 3
                      buying_rate_percentage: 1.2
                      buying_rate_fixed: 0.15
                noCustomerRecord:
                  summary: No gateway customer record for this merchant
                  value:
                    data: {}
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: The merchant does not belong to your reseller.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                notFound:
                  summary: Merchant not found or not in your reseller
                  value:
                    error:
                      code: NOT_FOUND
                      message: Merchant not found
        "422":
          description: The merchantId path segment is not a positive integer.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                invalidMerchantId:
                  summary: Non-numeric merchant id
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: merchantId is required
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"
    servers:
      - url: https://sandbox-portal.datmanlabs.com/api
        description: Sandbox
  /v1/merchants/{merchantId}/owner-details:
    get:
      operationId: getMerchantOwnerDetails
      summary: Get primary owner details
      description: "Returns the merchant's primary owner: name, contact details, date
        of birth, nationality, ownership percentage and home address.
        `owner_details` is null when the merchant has no primary owner on file.
        The merchant must belong to your reseller, otherwise 404."
      tags:
        - Merchant details
      security:
        - ApiKeyAuth: []
      parameters:
        - name: merchantId
          in: path
          required: true
          description: Numeric merchant id. Must be a positive integer belonging to your
            reseller.
          schema:
            type: integer
            minimum: 1
          example: 123456
      responses:
        "200":
          description: Primary owner details, or null.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CpMerchantOwnerDetailsResponse"
              examples:
                owner:
                  summary: Merchant with a primary owner
                  value:
                    data:
                      owner_details:
                        title: Mr
                        full_name: Alex Example
                        email: owner@example.com
                        telephone_number: "+447700900123"
                        date_of_birth: 1985-04-12T00:00:00.000Z
                        nationality: British
                        ownership_percentage: 100
                        address_line1: 1 Example Street
                        address_line2: null
                        city: London
                        county: Greater London
                        post_code: EC1A 1AA
                        state: null
                        country: United Kingdom
                noOwner:
                  summary: No primary owner on file
                  value:
                    data:
                      owner_details: null
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: The merchant does not belong to your reseller.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                notFound:
                  summary: Merchant not found or not in your reseller
                  value:
                    error:
                      code: NOT_FOUND
                      message: Merchant not found
        "422":
          description: The merchantId path segment is not a positive integer.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                invalidMerchantId:
                  summary: Non-numeric merchant id
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: merchantId is required
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"
    servers:
      - url: https://sandbox-portal.datmanlabs.com/api
        description: Sandbox
  /v1/merchants/{merchantId}/business-details:
    get:
      operationId: getMerchantBusinessDetails
      summary: Get business details
      description: "Returns the merchant's business profile: legal and trading names,
        company and VAT numbers, legal entity type, industry, contact details,
        and the registered and trading addresses. It also includes a short
        summary of the primary owner's contact details. Returns `data: {}` when
        there is no merchant record. Fields inside the nested objects are null
        when the related record is missing. The merchant must belong to your
        reseller, otherwise 404."
      tags:
        - Merchant details
      security:
        - ApiKeyAuth: []
      parameters:
        - name: merchantId
          in: path
          required: true
          description: Numeric merchant id. Must be a positive integer belonging to your
            reseller.
          schema:
            type: integer
            minimum: 1
          example: 123456
      responses:
        "200":
          description: Business details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CpMerchantBusinessDetailsResponse"
              examples:
                limitedCompany:
                  summary: UK limited company
                  value:
                    data:
                      business_details:
                        legal_name: Example Pizza Co Ltd
                        trading_name: Example Pizza Co
                        company_number: "01234567"
                        legal_entity: Limited Company
                        industry: Restaurants
                        vat_number: GB123456789
                        telephone_number: "+442079460000"
                        website_url: https://www.example.com
                        registered_address:
                          address_line1: 1 Example Street
                          address_line2: null
                          city: London
                          county: Greater London
                          post_code: EC1A 1AA
                          state: null
                          country: United Kingdom
                        trading_address:
                          address_line1: 2 Example Road
                          address_line2: Unit 4
                          city: London
                          county: Greater London
                          post_code: EC1A 2BB
                          state: null
                          country: United Kingdom
                      owner_details:
                        full_name: Alex Example
                        email: owner@example.com
                        telephone_number: "+447700900123"
                        address_line1: 1 Example Street
                        address_line2: null
                        city: London
                        county: Greater London
                        post_code: EC1A 1AA
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: The merchant does not belong to your reseller.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                notFound:
                  summary: Merchant not found or not in your reseller
                  value:
                    error:
                      code: NOT_FOUND
                      message: Merchant not found
        "422":
          description: The merchantId path segment is not a positive integer.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                invalidMerchantId:
                  summary: Non-numeric merchant id
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: merchantId is required
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"
    servers:
      - url: https://sandbox-portal.datmanlabs.com/api
        description: Sandbox
  /v1/merchants/{merchantId}/bank-details:
    get:
      operationId: getMerchantBankDetails
      summary: Get bank details
      description: Returns the merchant's payout bank account. Account identifiers
        (sort code, account number, routing number, BSB, transit number and
        financial institution number) are masked, so only the last 3 characters
        are shown, prefixed with `****`. Identifiers that don't apply to the
        account's country are null. `verified_on` is set only when `status` is
        `Verified`. `data` is null when there is no merchant record. The
        merchant must belong to your reseller, otherwise 404.
      tags:
        - Merchant details
      security:
        - ApiKeyAuth: []
      parameters:
        - name: merchantId
          in: path
          required: true
          description: Numeric merchant id. Must be a positive integer belonging to your
            reseller.
          schema:
            type: integer
            minimum: 1
          example: 123456
      responses:
        "200":
          description: Masked bank details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CpMerchantBankDetailsResponse"
              examples:
                ukAccount:
                  summary: Verified UK bank account
                  value:
                    data:
                      name_of_bank: Example Bank
                      account_holder_name: Example Pizza Co Ltd
                      sort_code: "****456"
                      account_number: "****234"
                      routing_number: null
                      bsb_code: null
                      transit_number: null
                      financial_institution_number: null
                      account_type: null
                      country: United Kingdom
                      status: Verified
                      verified_on: 2026-03-01T10:15:00.000Z
                pendingAccount:
                  summary: Bank account awaiting verification
                  value:
                    data:
                      name_of_bank: Example Bank
                      account_holder_name: Example Pizza Co Ltd
                      sort_code: "****456"
                      account_number: "****234"
                      routing_number: null
                      bsb_code: null
                      transit_number: null
                      financial_institution_number: null
                      account_type: null
                      country: United Kingdom
                      status: Pending
                      verified_on: null
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: The merchant does not belong to your reseller.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                notFound:
                  summary: Merchant not found or not in your reseller
                  value:
                    error:
                      code: NOT_FOUND
                      message: Merchant not found
        "422":
          description: The merchantId path segment is not a positive integer.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                invalidMerchantId:
                  summary: Non-numeric merchant id
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: merchantId is required
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/InternalError"
        "503":
          $ref: "#/components/responses/ServiceUnavailable"
    servers:
      - url: https://sandbox-portal.datmanlabs.com/api
        description: Sandbox
  /api/v1/merchants/merchant-association:
    post:
      operationId: merchantAssociation
      summary: Create, reactivate or update a merchant association
      description: Single entry point for partner merchant lifecycle actions selected
        by `action`. `create` onboards a new merchant (or associates a store
        with an existing user), `reactivate` extends an expired signup link, and
        `update` changes the credentials of a user who has not yet completed
        signup.
      tags:
        - Merchant association
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MerchantAssociationRequest"
            examples:
              create:
                summary: Create a merchant for a store
                value:
                  action: create
                  storeId: "123456"
                  isPartner: false
                  email: owner@example.com
                  phoneNumber: "+447700900000"
                  country: United Kingdom
                  firstName: Jane
                  lastName: Doe
                  businessName: Example Foods Ltd
                  tradingName: Example Foods
                  changeOfownership: false
                  isReseller: false
                  businessType: Limited
                  platform:
                    - 1
                    - 2
                  webhookUrl: https://partner.example.com/webhooks/onboarding
              reactivate:
                summary: Reactivate a signup link
                value:
                  action: reactivate
                  merchantId: "1000001"
              update:
                summary: Update pending user credentials
                value:
                  action: update
                  oldCredentials:
                    email: old@example.com
                    phoneNumber: ""
                  newCredentials:
                    email: new@example.com
                    phoneNumber: ""
      responses:
        "200":
          description: Action processed. Note that some business-rule outcomes (for
            example user not found or update limit exhausted on `update`) are
            also returned with HTTP 200 and a Datman internal `statusCode`
            (4005-4009) in the body.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MerchantAssociationResponse"
              examples:
                merchantCreated:
                  summary: New merchant created
                  value:
                    message: New merchant account has been created and has been added to the
                      owner@example.com
                    merchantId: 1000001
                    merchant_status: 0
                    account_verification_status: false
                    bank_verification_status: false
                    email: owner@example.com
                    responseCode: 1001
                    businessName: Example Foods Ltd
                    tradingName: Example Foods
                    signup_link: https://portal.example.com/example-partner
        "400":
          description: Request body failed Joi validation, or a business rule rejected it
            (for example store already associated, reseller country mismatch,
            invalid merchant type configuration).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MerchantAssociationError"
              examples:
                missingEmail:
                  summary: Validation error (email missing on create)
                  value:
                    message: "'email' is a mandatory field when creating a record. Please include
                      your email address."
        "401":
          description: Missing or invalid `api_key` header.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvalidApiKeyError"
        "429":
          description: Rate limit exceeded for repeated requests with the same reference.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RateLimitExceededError"
        "500":
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ServerError"
    servers:
      - url: https://portal-api-sandbox.datmancrm.com/merchants/sandbox
        description: Sandbox
      - url: https://portal-api.datmancrm.com/merchants/prod
        description: Production
  /api/v1/merchants/merchant-associationV2:
    post:
      operationId: merchantAssociationV2
      summary: Create, reactivate, update, patch or upload documents for a merchant (V2)
      description: Version 2 of the merchant association endpoint. The `action` field
        picks the operation. `create` onboards a merchant and also accepts full
        onboarding sections (`bankDetails`, `businessDetails`, `ownerDetails`,
        `tradingDetails`, `businessDealDetails`). `reactivate` extends an
        expired signup link. `update` changes the credentials of a user who has
        not yet completed signup. `patch` fills in onboarding data for an
        existing merchant. `uploadDocuments` queues up to 5 base64-encoded KYC
        documents for the merchant and returns HTTP 202.
      tags:
        - Merchant association
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MerchantAssociationV2Request"
            examples:
              createWithDetails:
                summary: Create a merchant with onboarding details
                value:
                  action: create
                  storeId: "123456"
                  isPartner: false
                  email: owner@example.com
                  phoneNumber: "+447700900000"
                  country: United Kingdom
                  firstName: Jane
                  lastName: Doe
                  businessName: Example Foods Ltd
                  tradingName: Example Foods
                  changeOfownership: false
                  isReseller: false
                  businessType: Limited
                  platform:
                    - 1
                  webhookUrl: https://partner.example.com/webhooks/onboarding
                  bankDetails:
                    accountName: EXAMPLE FOODS LTD
                    bankSortCode: "000000"
                    ibanNumber: ""
                    bsbNumber: ""
                    transitNumber: ""
                    financialInstitutionNumber: ""
                    routingNumber: ""
                    accountNumber: "00000000"
                    bankName: Example Bank
                    address:
                      addressLine1: 1 Example Street
                      addressLine2: ""
                  businessDetails:
                    businessType: Limited
                    companyRegistrationNumber: "00000000"
                    organisationType: Private Company
                    trustType: Other Trust
                    address:
                      addressLine1: 1 Example Street
                      addressLine2: ""
                      state: ""
                      city: London
                      county: Greater London
                      country: United Kingdom
                      postCode: SW1A 1AA
                    contact:
                      phoneNumber: "+447700900000"
                      email: owner@example.com
                      website: https://www.example.com
                  ownerDetails:
                    title: Ms
                    firstName: Jane
                    lastName: Doe
                    citizenship: British
                    dateOfBirth: 1985-01-31
                    abnNumber: ""
                    einNumber: ""
                    ssnNumber: ""
                    personalId: ""
                    ppsNumber: ""
                    vatNumber: ""
                    vatExists: false
                    address:
                      addressLine1: 1 Example Street
                      addressLine2: ""
                      state: ""
                      city: London
                      county: Greater London
                      country: United Kingdom
                      postCode: SW1A 1AA
                    contact:
                      phoneNumber: "+447700900000"
                      email: owner@example.com
                  tradingDetails:
                    name: Example Foods
                    address:
                      addressLine1: 1 Example Street
                      addressLine2: ""
                      state: ""
                      city: London
                      county: Greater London
                      country: United Kingdom
                      postCode: SW1A 1AA
                  businessDealDetails:
                    setupFee: "0"
                    monthlyRent: "0"
                    contractDurationMonths: "12"
                    fixedTransactionFee: "0.20"
                    interchangeRate: "1.50"
              reactivate:
                summary: Reactivate a signup link
                value:
                  action: reactivate
                  merchantId: "1000001"
              update:
                summary: Update pending user credentials
                value:
                  action: update
                  oldCredentials:
                    email: old@example.com
                    phoneNumber: ""
                  newCredentials:
                    email: new@example.com
                    phoneNumber: ""
              patch:
                summary: Fill in missing onboarding fields
                value:
                  action: patch
                  merchantId: "1000001"
                  overrideDetails: false
                  isSyncEnabled: true
                  businessDetails:
                    contact:
                      website: https://www.example.com
                  ownerDetails:
                    dateOfBirth: 1985-01-31
              uploadDocuments:
                summary: Upload a KYC document
                value:
                  action: uploadDocuments
                  merchantId: "1000001"
                  attachments:
                    - documentTypeId: 1
                      filename: passport.pdf
                      content: JVBERi0xLjQKJcfsj6IKMSAwIG9iago8PC9UeXBlL0NhdGFsb2c+PgplbmRvYmoK
      responses:
        "200":
          description: "Action processed (create, reactivate, update or patch). Some
            business-rule outcomes also come back as HTTP 200: `update` with a
            Datman internal `statusCode` 4005-4009, `reactivate` when the
            merchant or link isn't found, and every `patch` failure (merchant
            not found, nothing to update, validation errors)."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MerchantAssociationV2Response"
              examples:
                merchantCreated:
                  summary: New merchant created with onboarding details
                  value:
                    message: New merchant account has been created and has been added to the
                      owner@example.com
                    merchantId: 1000001
                    merchant_status: 0
                    account_verification_status: false
                    bank_verification_status: false
                    email: owner@example.com
                    responseCode: 1002
                    businessName: Example Foods Ltd
                    tradingName: Example Foods
                    signup_link: https://portal.example.com/example-partner
                patchApplied:
                  summary: Patch applied, one existing field skipped
                  value:
                    message: Merchant details updated successfully.
                    merchantId: "1000001"
                    skippedFields:
                      - ownerDetails.dateOfBirth
                    skippedMessage: Patch operation allowed only on empty fields. Existing values
                      are immutable
                patchNothingToUpdate:
                  summary: Patch with no applicable fields
                  value:
                    message: No applicable fields to update.
                    merchantId: "1000001"
                credentialsUpdated:
                  summary: Credentials updated
                  value:
                    message: The user credentials have been successfully updated.
                    statusCode: 6003
        "202":
          description: "`uploadDocuments` accepted. The documents are stored and queued
            for processing. If a webhook is configured, the result is sent
            there."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MerchantUploadDocumentsAccepted"
              examples:
                accepted:
                  summary: Documents accepted
                  value:
                    message: Your document will be attached to this merchant shortly. We will notify
                      you via webhook if configured when processing completes.
                    statusCode: 10005
                acceptedPendingOtherSide:
                  summary: Front of a two-sided document accepted
                  value:
                    message: Your document will be attached to this merchant shortly. We will notify
                      you via webhook if configured when processing completes.
                    reminder: You uploaded the front of your driving licence. Please also upload the
                      back using document type 17 when you can.
                    statusCode: 10006
        "400":
          description: Invalid JSON, failed schema validation, a missing onboarding
            section on `create`, bank details that could not be decrypted, a
            rejected document upload, or a business rule (store already
            associated, invalid reseller ID, reseller country mismatch).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MerchantAssociationV2Error"
              examples:
                validationFailed:
                  summary: Schema validation error
                  value:
                    message: Some of the information you sent could not be accepted. Please review
                      the items below, fix any issues, and try again.
                    statusCode: 10110
                    details:
                      - path: email
                        message: "'email' is a mandatory field when creating a record. Please include
                          your email address."
                missingSection:
                  summary: Onboarding section missing on create
                  value:
                    message:
                      - key: bankDetails
                        error: Bank details are mandatory.
                invalidJson:
                  summary: Body is not valid JSON
                  value:
                    message: Invalid JSON format in request body
                    statusCode: 9001
                storeAlreadyAssociated:
                  summary: Store already associated
                  value:
                    message: This store is already associated with an active merchant!
                    merchantId: 1000001
                documentRejected:
                  summary: Document content does not match its extension
                  value:
                    message: "Attachment content does not match file extension for documentTypeId 1.
                      Allowed extensions: .pdf, .jpg, .jpeg, .png"
                    statusCode: 10111
        "401":
          description: Missing or invalid `api_key` header.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvalidApiKeyError"
              examples:
                invalidKey:
                  summary: Invalid API key
                  value:
                    message: Invalid API key
                    errorCode: 1019
        "429":
          description: Rate limit exceeded for repeated requests with the same store ID or
            client IP.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RateLimitExceededError"
        "500":
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ServerError"
    servers:
      - url: https://portal-api-sandbox.datmancrm.com/merchants/sandbox
        description: Sandbox
      - url: https://portal-api.datmancrm.com/merchants/prod
        description: Production
components:
  schemas:
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable SCREAMING_SNAKE error code.
              examples:
                - UNAUTHORIZED
                - FORBIDDEN
                - VALIDATION_ERROR
                - RATE_LIMITED
                - INTERNAL_ERROR
                - DB_TIMEOUT
                - DB_CLIENT_CLOSED
            message:
              type: string
              description: Human-readable error message.
            details:
              description: Optional extra context about the error.
    CpAddress:
      type: object
      description: Postal address. Every field is null when no address is on file.
      required:
        - address_line1
        - address_line2
        - city
        - county
        - post_code
        - state
        - country
      properties:
        address_line1:
          type:
            - string
            - "null"
        address_line2:
          type:
            - string
            - "null"
        city:
          type:
            - string
            - "null"
        county:
          type:
            - string
            - "null"
        post_code:
          type:
            - string
            - "null"
        state:
          type:
            - string
            - "null"
        country:
          type:
            - string
            - "null"
    CpMerchantSummary:
      type: object
      required:
        - merchant_id
        - merchant_name
        - canonical_reseller_id
        - country
        - account_status
        - payout_status
        - business_status
        - owners_status
        - bank_status
        - tos_status
        - is_reseller
        - is_liable
      properties:
        merchant_id:
          type: integer
          description: Merchant id.
        merchant_name:
          type: string
          description: Merchant name as recorded at onboarding.
        canonical_reseller_id:
          type:
            - integer
            - "null"
          description: Id of the reseller that owns the merchant.
        country:
          type:
            - string
            - "null"
          description: Country name, for example `United Kingdom`.
        account_status:
          type:
            - string
            - "null"
          description: Overall account onboarding status.
        payout_status:
          type:
            - string
            - "null"
          description: Payout onboarding status.
        business_status:
          type:
            - string
            - "null"
          description: Business-details verification status.
        owners_status:
          type:
            - string
            - "null"
          description: Owner verification status.
        bank_status:
          type:
            - string
            - "null"
          description: Bank-account verification status.
        tos_status:
          type:
            - string
            - "null"
          description: Terms-of-service acceptance status.
        is_reseller:
          type: boolean
          description: Whether the merchant is itself a reseller.
        is_liable:
          type: boolean
          description: Whether the merchant is liable (gateway `is_liable` flag).
    CpMerchantSummaryResponse:
      type: object
      required:
        - data
      properties:
        data:
          $ref: "#/components/schemas/CpMerchantSummary"
    CpMerchantPaymentConfig:
      type: object
      description: Payment configuration. Every listed property is present when the
        merchant has a gateway customer record. Otherwise the object is empty.
      properties:
        payment_provider:
          type:
            - string
            - "null"
          description: Code of the payment provider that processes the merchant's payments.
        fee_tier_name:
          type:
            - string
            - "null"
        fee_tier_percentage:
          type:
            - number
            - "null"
          description: Fee tier percentage fee.
        fee_tier_fixed:
          type:
            - number
            - "null"
          description: Fee tier fixed fee per transaction, in major currency units.
        ext_reseller_percentage_fee:
          type:
            - number
            - "null"
          description: Your reseller percentage fee on top of the tier.
        ext_reseller_fixed_fee:
          type:
            - number
            - "null"
          description: Your reseller fixed fee on top of the tier, in major currency units.
        gateway_name:
          type:
            - string
            - "null"
        billing_address:
          type:
            - string
            - "null"
          description: Billing-address setting on the gateway configuration, passed
            through unchanged.
        hide_gpay_apay:
          type:
            - string
            - "null"
          description: Whether Google Pay / Apple Pay are hidden, as stored on the gateway
            configuration.
        mid_status:
          type: "null"
          description: Reserved. Always null.
        min_transaction:
          type: "null"
          description: Reserved. Always null.
        max_transaction:
          type:
            - number
            - "null"
          description: Effective maximum single-transaction value (merchant value, else
            country default).
        xpress_sale_limit:
          type:
            - number
            - "null"
          description: Effective express-sale limit (merchant value, else country default).
        daily_limit:
          type: "null"
          description: Reserved. Always null.
        merchant_max_transaction:
          type:
            - number
            - "null"
          description: Merchant-level maximum single-transaction value. 0 means unset.
        merchant_xpress_sale_limit:
          type:
            - number
            - "null"
          description: Merchant-level express-sale limit. 0 means unset.
        country_max_transaction:
          type:
            - number
            - "null"
          description: Country default maximum single-transaction value.
        country_xpress_sale_limit:
          type:
            - number
            - "null"
          description: Country default express-sale limit.
        fee_tier_id:
          type:
            - integer
            - "null"
        buying_rate_percentage:
          type:
            - number
            - "null"
          description: Your reseller's cost (buying) percentage rate, or null if none is
            on file.
        buying_rate_fixed:
          type:
            - number
            - "null"
          description: Your reseller's cost (buying) fixed rate, or null if none is on file.
    CpMerchantPaymentConfigResponse:
      type: object
      required:
        - data
      properties:
        data:
          $ref: "#/components/schemas/CpMerchantPaymentConfig"
    CpOwnerDetails:
      type: object
      required:
        - title
        - full_name
        - email
        - telephone_number
        - date_of_birth
        - nationality
        - ownership_percentage
        - address_line1
        - address_line2
        - city
        - county
        - post_code
        - state
        - country
      properties:
        title:
          type:
            - string
            - "null"
        full_name:
          type:
            - string
            - "null"
        email:
          type:
            - string
            - "null"
        telephone_number:
          type:
            - string
            - "null"
        date_of_birth:
          type:
            - string
            - "null"
          description: Date of birth as an ISO-8601 timestamp.
        nationality:
          type:
            - string
            - "null"
        ownership_percentage:
          type:
            - number
            - string
            - "null"
          description: Ownership percentage. May be returned as a decimal string.
        address_line1:
          type:
            - string
            - "null"
        address_line2:
          type:
            - string
            - "null"
        city:
          type:
            - string
            - "null"
        county:
          type:
            - string
            - "null"
        post_code:
          type:
            - string
            - "null"
        state:
          type:
            - string
            - "null"
        country:
          type:
            - string
            - "null"
    CpMerchantOwnerDetailsResponse:
      type: object
      required:
        - data
      properties:
        data:
          type: object
          required:
            - owner_details
          properties:
            owner_details:
              oneOf:
                - $ref: "#/components/schemas/CpOwnerDetails"
                - type: "null"
    CpBusinessDetails:
      type: object
      required:
        - legal_name
        - trading_name
        - company_number
        - legal_entity
        - industry
        - vat_number
        - telephone_number
        - website_url
        - registered_address
        - trading_address
      properties:
        legal_name:
          type:
            - string
            - "null"
        trading_name:
          type:
            - string
            - "null"
        company_number:
          type:
            - string
            - "null"
          description: Company registration number.
        legal_entity:
          type:
            - string
            - "null"
          description: Legal entity type name, for example `Limited Company`.
        industry:
          type:
            - string
            - "null"
          description: Business category.
        vat_number:
          type:
            - string
            - "null"
        telephone_number:
          type:
            - string
            - "null"
        website_url:
          type:
            - string
            - "null"
        registered_address:
          $ref: "#/components/schemas/CpAddress"
        trading_address:
          $ref: "#/components/schemas/CpAddress"
    CpBusinessOwnerContact:
      type: object
      required:
        - full_name
        - email
        - telephone_number
        - address_line1
        - address_line2
        - city
        - county
        - post_code
      properties:
        full_name:
          type:
            - string
            - "null"
        email:
          type:
            - string
            - "null"
        telephone_number:
          type:
            - string
            - "null"
        address_line1:
          type:
            - string
            - "null"
        address_line2:
          type:
            - string
            - "null"
        city:
          type:
            - string
            - "null"
        county:
          type:
            - string
            - "null"
        post_code:
          type:
            - string
            - "null"
    CpMerchantBusinessDetailsResponse:
      type: object
      required:
        - data
      properties:
        data:
          type: object
          description: Both properties are present for an existing merchant. Otherwise the
            object is empty.
          properties:
            business_details:
              $ref: "#/components/schemas/CpBusinessDetails"
            owner_details:
              $ref: "#/components/schemas/CpBusinessOwnerContact"
    CpMerchantBankDetails:
      type: object
      required:
        - name_of_bank
        - account_holder_name
        - sort_code
        - account_number
        - routing_number
        - bsb_code
        - transit_number
        - financial_institution_number
        - account_type
        - country
        - status
        - verified_on
      properties:
        name_of_bank:
          type:
            - string
            - "null"
        account_holder_name:
          type:
            - string
            - "null"
        sort_code:
          type:
            - string
            - "null"
          description: Masked UK sort code (last 3 characters), for example `****456`.
        account_number:
          type:
            - string
            - "null"
          description: Masked account number (last 3 characters), for example `****234`.
        routing_number:
          type:
            - string
            - "null"
          description: Masked US routing number.
        bsb_code:
          type:
            - string
            - "null"
          description: Masked Australian BSB code.
        transit_number:
          type:
            - string
            - "null"
          description: Masked Canadian transit number.
        financial_institution_number:
          type:
            - string
            - "null"
          description: Masked Canadian financial institution number.
        account_type:
          type:
            - string
            - "null"
        country:
          type:
            - string
            - "null"
          description: Merchant country name.
        status:
          type:
            - string
            - "null"
          description: Bank-account verification status, for example `Verified`.
        verified_on:
          type:
            - string
            - "null"
          description: ISO-8601 timestamp. Set only when `status` is `Verified`.
    CpMerchantBankDetailsResponse:
      type: object
      required:
        - data
      properties:
        data:
          oneOf:
            - $ref: "#/components/schemas/CpMerchantBankDetails"
            - type: "null"
    MerchantCountry:
      type: string
      description: Supported merchant country.
      enum:
        - United Kingdom
        - Ireland
        - Australia
        - New Zealand
        - Canada
        - United States
        - Mexico
    E164PhoneNumber:
      type: string
      description: Phone number in E.164 format including country code.
      pattern: ^\+\d{7,15}$
    CredentialsPair:
      type: object
      additionalProperties: false
      required:
        - email
        - phoneNumber
      properties:
        email:
          type: string
          format: email
          description: Email address. In `newCredentials` it may be an empty string to
            leave unchanged.
        phoneNumber:
          type: string
          pattern: ^(\+\d{10,15})?$
          description: Phone number as +[country_code][number], or empty string to leave
            unchanged.
    MerchantAssociationRequest:
      type: object
      additionalProperties: false
      description: Fields are conditional on `action`. Fields not listed for an action
        are rejected. Only `create`, `reactivate` and `update` carry
        action-specific fields on this endpoint.
      required:
        - action
      properties:
        action:
          type: string
          enum:
            - create
            - reactivate
            - update
            - patch
            - uploadDocuments
          description: Operation to perform.
        storeId:
          type: string
          pattern: ^\d+$
          maxLength: 10
          description: Numeric store identifier. `create` only; required unless
            `isPartner` is true, and forbidden when `isPartner` is true.
        isPartner:
          type: boolean
          description: "`create` only (required). Set true to onboard a delivery partner
            without a `storeId`; must be true when `storeId` is omitted."
        webhookUrl:
          type: string
          format: uri
          pattern: ^https://
          maxLength: 200
          description: HTTPS URL that receives onboarding webhooks for the merchant
            created with `create`.
        email:
          type: string
          format: email
          maxLength: 254
          description: Merchant owner email. `create` only (required). Lower-cased by the
            server.
        phoneNumber:
          allOf:
            - $ref: "#/components/schemas/E164PhoneNumber"
          description: Merchant owner phone number. `create` only (required).
        country:
          allOf:
            - $ref: "#/components/schemas/MerchantCountry"
          description: Merchant country. `create` only (required).
        firstName:
          type: string
          minLength: 1
          maxLength: 80
          description: Owner first name. `create` only (required).
        lastName:
          type: string
          minLength: 1
          maxLength: 80
          description: Owner last name. `create` only (required).
        businessName:
          type: string
          minLength: 1
          maxLength: 80
          description: Legal business name (Unicode letters, digits and common
            punctuation). `create` only (required).
        tradingName:
          type:
            - string
            - "null"
          maxLength: 80
          description: Trading name. `create` only, optional; empty string or null allowed.
        changeOfownership:
          type: boolean
          description: Whether this is a change of ownership of an existing store.
            `create` only (required).
        isReseller:
          type: boolean
          description: Whether the merchant is a reseller. `create` only (required).
        merchantId:
          type: string
          pattern: ^\d+$
          maxLength: 100
          description: Datman merchant ID whose signup link is reactivated. `reactivate`
            only (required).
        resellerId:
          type: string
          pattern: ^\d{2,7}$
          description: Optional reseller ID (2-7 digits).
        countryOverride:
          type: boolean
          description: "`create` only, optional. When true, skips the check that `country`
            matches the reseller's configured country."
        platform:
          type: array
          uniqueItems: true
          description: IDs of the platforms to onboard on, as agreed with Datman. Defaults
            to all platforms when omitted.
          items:
            type: integer
            enum:
              - 1
              - 2
        businessType:
          type:
            - string
            - "null"
          enum:
            - Limited
            - Partnership
            - Sole Trader
            - Individual
            - Trust
            - Other
            - Corporation
            - ""
            - null
          description: "`create` only, optional. Allowed values depend on `country`:
            UK/Ireland: Limited, Partnership, Sole Trader, Individual;
            Australia: those plus Trust, Other; New Zealand and Mexico: Limited,
            Partnership, Sole Trader, Other, Individual; Canada: Limited, Sole
            Trader, Individual; United States: Limited, Sole Trader,
            Partnership, Corporation, Other, Individual."
        oldCredentials:
          allOf:
            - $ref: "#/components/schemas/CredentialsPair"
          description: Current user credentials. `update` only (required).
        newCredentials:
          allOf:
            - $ref: "#/components/schemas/CredentialsPair"
          description: New user credentials. `update` only (required). Must differ from
            `oldCredentials`; to change only the phone number, keep the same
            email in both and supply both phone numbers.
    MerchantAssociationResponse:
      type: object
      description: Result of the requested action. `create` returns the merchant
        fields; `reactivate` and `update` return `message` (and `statusCode` for
        update outcomes).
      properties:
        message:
          type: string
          description: Human-readable outcome.
        statusCode:
          type: integer
          description: Datman internal outcome code (not an HTTP status), e.g. 6003
            credentials updated, 4005-4009 update not possible.
        merchantId:
          type: integer
          description: Datman merchant ID (`create`).
        merchant_status:
          description: Merchant status value stored on the merchant record (`create`).
        account_verification_status:
          type: boolean
          description: Whether the merchant account is verified (`create`).
        bank_verification_status:
          type: boolean
          description: Whether the merchant bank account is verified (`create`).
        email:
          type: string
          format: email
          description: Owner email (`create`).
        responseCode:
          type: integer
          enum:
            - 1001
            - 1002
          description: Onboarding flow indicator (`create`). 1001 = staggered onboarding
            only; 1002 = extra details may be patched and the account might
            become unverified.
        businessName:
          type: string
          description: Legal business name (`create`).
        tradingName:
          type: string
          description: Trading name (`create`).
        signup_link:
          type: string
          description: Portal link for the new user to complete signup. Only present when
            a new user was created.
    MerchantAssociationError:
      type: object
      required:
        - message
      properties:
        message:
          type: string
          description: Validation or business-rule error message.
        statusCode:
          type: integer
          description: Datman internal error code, when available (e.g. 7003 reseller
            country mismatch).
        merchantId:
          type: integer
          description: Merchant ID, when the store is already associated.
    InvalidApiKeyError:
      type: object
      properties:
        message:
          type: string
          example: Invalid API key
        errorCode:
          type: integer
          example: 1019
    RateLimitExceededError:
      type: object
      properties:
        message:
          type: string
          example: Too many requests with the same reference
        statusCode:
          type: integer
          description: Datman internal code.
          example: 6001
    ServerError:
      type: object
      properties:
        message:
          type: string
          example: Internal server error
    MerchantAssociationV2Request:
      type: object
      description: Fields depend on `action`. The onboarding sections (`bankDetails`,
        `businessDetails`, `ownerDetails`, `tradingDetails`,
        `businessDealDetails`) are required on `create` and optional on `patch`.
        Other top-level fields follow the same per-action rules as the V1
        endpoint, and fields not allowed for an action are rejected.
        `uploadDocuments` accepts only `action`, `merchantId` and `attachments`.
      required:
        - action
      properties:
        action:
          type: string
          enum:
            - create
            - reactivate
            - update
            - patch
            - uploadDocuments
          description: Operation to perform.
        storeId:
          type: string
          pattern: ^\d+$
          maxLength: 10
          description: Numeric store identifier. `create` only. Required unless
            `isPartner` is true, and not allowed when `isPartner` is true.
        isPartner:
          type: boolean
          description: "`create` only (required). Set true to onboard a delivery partner
            without a `storeId`. Must be true when `storeId` is omitted."
        webhookUrl:
          type: string
          format: uri
          pattern: ^https://
          maxLength: 200
          description: HTTPS URL that receives onboarding webhooks for the merchant
            created with `create`.
        email:
          type: string
          format: email
          maxLength: 254
          description: Merchant owner email. `create` only (required). The server converts
            it to lower case.
        phoneNumber:
          allOf:
            - $ref: "#/components/schemas/E164PhoneNumber"
          description: Merchant owner phone number. `create` only (required).
        country:
          allOf:
            - $ref: "#/components/schemas/MerchantCountry"
          description: Merchant country. `create` only (required). Also decides the
            country-specific rules for the onboarding sections.
        firstName:
          type: string
          minLength: 1
          maxLength: 80
          description: Owner first name. `create` only (required).
        lastName:
          type: string
          minLength: 1
          maxLength: 80
          description: Owner last name. `create` only (required).
        businessName:
          type: string
          minLength: 1
          maxLength: 80
          description: Legal business name. `create` only (required).
        tradingName:
          type:
            - string
            - "null"
          maxLength: 80
          description: Trading name. `create` only, optional. Empty string or null is
            allowed.
        changeOfownership:
          type: boolean
          description: Whether this is a change of ownership of an existing store.
            `create` only (required).
        isReseller:
          type: boolean
          description: Whether the merchant is a reseller. `create` only (required).
        merchantId:
          type: string
          pattern: ^\d+$
          maxLength: 100
          description: Datman merchant ID. Required for `reactivate`, `patch` and
            `uploadDocuments`. Must be sent as a string.
        resellerId:
          type: string
          pattern: ^\d{2,7}$
          description: Optional reseller ID (2-7 digits).
        countryOverride:
          type: boolean
          description: "`create` only, optional. When true, skips the check that `country`
            matches the reseller's configured country."
        platform:
          type: array
          uniqueItems: true
          description: IDs of the platforms to onboard on, as agreed with Datman. If
            omitted, the merchant is onboarded on all platforms.
          items:
            type: integer
            enum:
              - 1
              - 2
        businessType:
          type:
            - string
            - "null"
          enum:
            - Limited
            - Partnership
            - Sole Trader
            - Individual
            - Trust
            - Other
            - Corporation
            - ""
            - null
          description: "`create` only, optional. Allowed values depend on `country` (same
            rules as V1)."
        oldCredentials:
          allOf:
            - $ref: "#/components/schemas/CredentialsPair"
          description: Current user credentials. `update` only (required).
        newCredentials:
          allOf:
            - $ref: "#/components/schemas/CredentialsPair"
          description: New user credentials. `update` only (required). Must differ from
            `oldCredentials`.
        overrideDetails:
          type:
            - boolean
            - string
          enum:
            - true
            - false
            - "true"
            - "false"
          default: false
          description: "`patch` only. When false (default), only fields that are empty on
            the merchant are filled in. Fields that already have a value are
            skipped and listed in `skippedFields`. When true, existing values
            are overwritten."
        isSyncEnabled:
          type:
            - boolean
            - string
          enum:
            - true
            - false
            - "true"
            - "false"
          default: true
          description: "`patch` only. When true (default), the patched data is synced to
            the payment provider (transfer instrument, legal entity and business
            line updates)."
        attachments:
          type: array
          minItems: 1
          maxItems: 5
          description: "`uploadDocuments` only (required). At most one attachment per
            `documentTypeId`. File names must not repeat, and the decoded total
            must be 25 MB or less."
          items:
            $ref: "#/components/schemas/MerchantUploadAttachment"
        bankDetails:
          description: 'Bank account details. Required on `create`, optional on `patch`.
            May be sent encrypted as `{ "encryptedData": "..." }`.'
          oneOf:
            - $ref: "#/components/schemas/MerchantBankDetails"
            - $ref: "#/components/schemas/EncryptedBankDetails"
        businessDetails:
          allOf:
            - $ref: "#/components/schemas/MerchantBusinessDetails"
          description: Business details. Required on `create`, optional on `patch`.
            `businessType`, `organisationType` and `trustType` can't be changed
            with `patch`; they are ignored and listed in `ignoredFields`.
        ownerDetails:
          allOf:
            - $ref: "#/components/schemas/MerchantOwnerDetails"
          description: Owner details. Required on `create`, optional on `patch`.
        tradingDetails:
          allOf:
            - $ref: "#/components/schemas/MerchantTradingDetails"
          description: Trading details. Required on `create`, optional on `patch`.
        businessDealDetails:
          allOf:
            - $ref: "#/components/schemas/MerchantBusinessDealDetails"
          description: Commercial terms agreed with the reseller. Required on `create`.
            Validated on `patch` but not stored by it.
    MerchantAddress:
      type: object
      additionalProperties: false
      description: Postal address. On `create`, every key must be present; empty
        strings are allowed except where noted. On `patch` every key is
        optional.
      properties:
        addressLine1:
          type: string
          maxLength: 100
        addressLine2:
          type: string
          maxLength: 100
        state:
          type: string
          maxLength: 100
          description: "For Australia and the United States: required, and must be a valid
            state code. For other countries: free text, may be empty. Required
            in business and owner addresses."
        city:
          type: string
          maxLength: 100
        county:
          type: string
          maxLength: 100
        country:
          type: string
          maxLength: 80
        postCode:
          type: string
          maxLength: 100
    MerchantBankAddress:
      type: object
      description: "On `create` these keys must be present: `addressLine1`,
        `addressLine2`. On `patch` every key is optional."
      additionalProperties: false
      properties:
        addressLine1:
          type: string
          maxLength: 100
        addressLine2:
          type: string
          maxLength: 100
    MerchantBankDetails:
      type: object
      additionalProperties: false
      description: Bank account details. On `create`, every key must be present. Send
        an empty string for fields that don't apply to the merchant's country. A
        value that fails its format check is stored as an empty string instead
        of being rejected. On `patch` every key is optional.
      properties:
        accountName:
          type: string
          maxLength: 100
          description: Account holder name. The server converts it to upper case.
        bankSortCode:
          type: string
          pattern: ^(\d{6})?$
          description: 6-digit sort code (UK, Ireland).
        ibanNumber:
          type: string
          maxLength: 36
          description: IBAN. For Ireland it must be 22 characters (2 letters, 2 digits, 4
            letters, then digits).
        bsbNumber:
          type: string
          pattern: ^(\d{6})?$
          description: 6-digit BSB number (Australia).
        transitNumber:
          type: string
          pattern: ^(\d{5})?$
          description: 5-digit transit number (Canada).
        financialInstitutionNumber:
          type: string
          pattern: ^(\d{3})?$
          description: 3-digit financial institution number (Canada).
        routingNumber:
          type: string
          pattern: ^(\d{9})?$
          description: 9-digit routing number (United States).
        accountNumber:
          type: string
          pattern: ^\d*$
          description: "Account number, digits only. Length rules: UK 8, New Zealand
            15-16, Australia 5-9, United States 3-17, Mexico 18, Canada 7-12,
            other countries up to 30."
        bankName:
          type: string
          maxLength: 100
        address:
          $ref: "#/components/schemas/MerchantBankAddress"
    EncryptedBankDetails:
      type: object
      additionalProperties: false
      required:
        - encryptedData
      properties:
        encryptedData:
          type: string
          description: Encrypted bank details payload. The server decrypts it with the
            partner's encryption key, then validates the result as
            `MerchantBankDetails`.
    MerchantContact:
      type: object
      description: "On `create` these keys must be present: `email`. On `patch` every
        key is optional."
      additionalProperties: false
      properties:
        phoneNumber:
          type: string
          pattern: ^(\+\d{7,15})?$
          description: Phone number in E.164 format, or empty string. Required in
            `ownerDetails.contact`.
        email:
          type: string
          maxLength: 254
          description: Email address, or empty string.
        website:
          type: string
          description: Website URL (http or https), or empty string.
            `businessDetails.contact` only (required there).
    MerchantBusinessDetails:
      type: object
      description: "On `create` these keys must be present: `businessType`,
        `companyRegistrationNumber`, `organisationType`, `trustType`, `address`,
        `contact`. On `patch` every key is optional."
      additionalProperties: false
      properties:
        businessType:
          type: string
          enum:
            - Limited
            - Partnership
            - Sole Trader
            - Individual
            - Trust
            - Other
            - Corporation
          description: Business type. Allowed values depend on `country`.
        companyRegistrationNumber:
          type: string
          maxLength: 30
          pattern: ^\d*$
          description: Company registration number (digits only), or empty string.
        organisationType:
          type: string
          enum:
            - Association Incorporated
            - Governmental Organization
            - Non Profit
            - Partnership Incorporated
            - Private Company
        trustType:
          type: string
          enum:
            - Cash Management Trust
            - Corporate Unit Trust
            - Deceased Estate
            - Discretionary Investment Trust
            - Discretionary Services Management Trust
            - Discretionary Trading Trust
            - First Home Saver Accounts Trust
            - Fixed Trust
            - Fixed Unit Trust
            - Hybrid Trust
            - Listed Public Unit Trust
            - Other Trust
            - Pooled Superannuation Trust
            - Public Trading Trust
            - Unlisted Public Unit Trust
        address:
          $ref: "#/components/schemas/MerchantAddress"
        contact:
          $ref: "#/components/schemas/MerchantContact"
    MerchantOwnerDetails:
      type: object
      additionalProperties: false
      description: Owner details. On `create`, every key must be present. Send an
        empty string for identifiers that don't apply to the merchant's country.
        On `patch` every key is optional.
      properties:
        title:
          type: string
          enum:
            - Mr
            - Miss
            - Mrs
            - Ms
            - ""
        firstName:
          type: string
          maxLength: 80
        lastName:
          type: string
          maxLength: 80
        citizenship:
          type: string
          description: Nationality (e.g. British), from Datman's supported list, or empty
            string.
        dateOfBirth:
          type: string
          pattern: ^(\d{4}-\d{2}-\d{2})?$
          description: Date of birth as YYYY-MM-DD, or empty string.
        abnNumber:
          type: string
          pattern: ^(\d{11})?$
          description: 11-digit ABN (Australia).
        einNumber:
          type: string
          pattern: ^(\d{9})?$
          description: 9-digit EIN (United States).
        ssnNumber:
          type: string
          description: 9-digit SSN (United States).
        personalId:
          type: string
          maxLength: 100
          description: Personal ID, letters and digits only (Mexico).
        ppsNumber:
          type: string
          pattern: ^(\d{7}[A-Z]{1,2})?$
          description: PPS number (Ireland).
        vatNumber:
          type: string
          description: UK VAT number as GB followed by 9 digits, with valid check digits,
            or empty string.
        vatExists:
          type:
            - boolean
            - string
          enum:
            - true
            - false
            - ""
          description: Whether the owner has a VAT number. Boolean or empty string.
        address:
          $ref: "#/components/schemas/MerchantAddress"
        contact:
          $ref: "#/components/schemas/MerchantContact"
    MerchantTradingDetails:
      type: object
      description: "On `create` these keys must be present: `name`, `address`. On
        `patch` every key is optional."
      additionalProperties: false
      properties:
        name:
          type: string
          maxLength: 80
          description: Trading name.
        address:
          $ref: "#/components/schemas/MerchantAddress"
    MerchantBusinessDealDetails:
      type: object
      additionalProperties: false
      description: All values are decimal strings. Empty strings are allowed. On
        `patch` every key is optional.
      properties:
        setupFee:
          type: string
          pattern: ^(\d+(\.\d*)?|\.\d+)?$
        monthlyRent:
          type: string
          pattern: ^(\d+(\.\d*)?|\.\d+)?$
        contractDurationMonths:
          type: string
          pattern: ^\d*$
        fixedTransactionFee:
          type: string
          pattern: ^(\d(\.\d{1,2})?)?$
          description: Fixed fee per transaction, up to 9.99.
        interchangeRate:
          type: string
          pattern: ^(\d{1,2}(\.\d{1,2})?)?$
          description: Percentage fee, up to 99.99.
    MerchantUploadAttachment:
      type: object
      additionalProperties: false
      required:
        - documentTypeId
        - content
        - filename
      properties:
        documentTypeId:
          type: integer
          minimum: 1
          maximum: 17
          description: Datman document type ID. Front and back sides use separate IDs (3
            front / 17 back for a driving licence, 9 front / 10 back for an
            identity card).
        content:
          type: string
          contentEncoding: base64
          description: Base64-encoded file content, up to 10 MB decoded. The content must
            match the file extension.
        filename:
          type: string
          minLength: 1
          maxLength: 255
          pattern: \.(pdf|jpe?g|png)$
          description: File name ending in .pdf, .jpg, .jpeg or .png (case-insensitive).
    MerchantAssociationV2Response:
      type: object
      description: Result of the action. `create` returns the merchant fields.
        `reactivate` returns `message`. `update` returns `message` and
        `statusCode`. `patch` returns `message`, `merchantId` and optionally the
        skipped and ignored field lists.
      properties:
        message:
          description: Human-readable outcome. For a `patch` that fails validation, this
            is an array of field errors.
          oneOf:
            - type: string
            - type: array
              items:
                $ref: "#/components/schemas/FieldValidationError"
        statusCode:
          type: integer
          description: Datman internal outcome code (not an HTTP status), e.g. 6003
            credentials updated, 4005-4009 update not possible.
        merchantId:
          type:
            - integer
            - string
          description: Datman merchant ID. An integer on `create`, a string on `patch`.
        merchant_status:
          description: Merchant status value stored on the merchant record (`create`).
        account_verification_status:
          type: boolean
          description: Whether the merchant account is verified (`create`).
        bank_verification_status:
          type: boolean
          description: Whether the merchant bank account is verified (`create`).
        email:
          type: string
          format: email
          description: Owner email (`create`).
        responseCode:
          type: integer
          enum:
            - 1001
            - 1002
          description: Onboarding flow indicator (`create`). 1001 = staggered onboarding
            only. 1002 = owner or business details were supplied and will be
            applied after onboarding, so the account might become unverified.
        businessName:
          type: string
          description: Legal business name (`create`).
        tradingName:
          type: string
          description: Trading name (`create`).
        signup_link:
          type: string
          description: Portal link for the new user to complete signup. Only present when
            a new user was created.
        skippedFields:
          type: array
          items:
            type: string
          description: "`patch` only. Dot-notation paths of fields not updated because
            they already have a value and `overrideDetails` was false."
        skippedMessage:
          type: string
          description: "`patch` only. Explains `skippedFields`."
        ignoredFields:
          type: array
          items:
            type: string
          description: "`patch` only. Fields that can't be changed with `patch` and were
            ignored (e.g. `businessDetails.businessType`)."
        ignoredMessage:
          type: string
          description: "`patch` only. Explains `ignoredFields`."
    MerchantUploadDocumentsAccepted:
      type: object
      required:
        - message
        - statusCode
      properties:
        message:
          type: string
        reminder:
          type: string
          description: Present when only one side of a two-sided document was uploaded.
        statusCode:
          type: integer
          enum:
            - 10005
            - 10006
          description: Datman internal code. 10005 = accepted. 10006 = accepted, but the
            other side of the document is still needed.
    FieldValidationError:
      type: object
      properties:
        key:
          type: string
          description: Dot-notation path of the field.
        error:
          type: string
          description: Validation message.
    MerchantAssociationV2Error:
      type: object
      required:
        - message
      properties:
        message:
          description: Error message. When required onboarding fields are missing on
            `create`, this is an array of field errors.
          oneOf:
            - type: string
            - type: array
              items:
                $ref: "#/components/schemas/FieldValidationError"
        statusCode:
          type: integer
          description: Datman internal error code, when available (e.g. 9001 invalid JSON,
            10110 validation failed, 10111 document rejected, 7002 invalid
            reseller ID, 7003 reseller country mismatch).
        merchantId:
          type: integer
          description: Merchant ID, when the store is already associated.
        details:
          type: array
          description: Field-level validation problems (with statusCode 10110).
          items:
            type: object
            properties:
              path:
                type: string
                description: Field path, e.g. `attachments[0].filename`.
              message:
                type: string
  responses:
    Unauthorized:
      description: Missing, invalid, expired or revoked credentials.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error:
              code: UNAUTHORIZED
              message: Invalid, expired, or revoked API key
    Forbidden:
      description: The caller may not access this route or reseller (for example the
        API key has no reseller, or the body names a different reseller).
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error:
              code: FORBIDDEN
              message: Reseller not allowed for this caller
    RateLimited:
      description: The per-reseller rate limit was exceeded.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error:
              code: RATE_LIMITED
              message: Rate limit exceeded
    InternalError:
      description: The query or a required configuration failed. Underlying details
        are not returned.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error:
              code: INTERNAL_ERROR
              message: Query failed
    ServiceUnavailable:
      description: The database timed out or closed the connection. Safe to retry.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            error:
              code: DB_TIMEOUT
              message: The database did not respond in time. Please retry.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: api_key
      description: Partner API key issued by Datman.
