openapi: 3.1.0
info:
  title: Transactions
  version: "1"
  description: List, search and look up the transactions of the merchants you manage.
tags:
  - name: Transactions
    description: List and search payment transactions for the reseller bound to the
      caller's API key.
  - name: Transaction details
    description: Full detail, splits, refunds and webhook deliveries for one transaction.
paths:
  /v1/transactions/list:
    post:
      operationId: listTransactions
      summary: List transactions in a date range
      description: Returns a cursor-paginated page of transactions for the caller's
        reseller between fromDate and toDate (calendar dates in the caller's
        timezone), newest first. For API key callers the reseller is always
        taken from the key; a different resellerId in the body is rejected with
        403.
      tags:
        - Transactions
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TransactionListRequest"
            examples:
              dateRange:
                summary: Transactions for a date range
                value:
                  fromDate: 2026-10-01
                  toDate: 2026-10-14
                  limit: 25
                  timezone: Europe/London
              merchantStatusFilter:
                summary: One merchant, successful and refunded only
                value:
                  fromDate: 2026-10-01
                  toDate: 2026-10-14
                  merchantId: 123456
                  status:
                    - SUCCESS
                    - REFUND
                  limit: 10
                  cursor: eyJ0IjoiMjAyNi0xMC0xNCAwOToxMjo0NyIsInBJZCI6MTAwMjMwLCJjSWQiOm51bGx9
      responses:
        "200":
          description: "A page of transactions. When the reseller has no configuration an
            empty page is returned (without data.timezone). When merchantId
            refers to a liable merchant the body also carries `isLiable: true`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TransactionListResponse"
              examples:
                transactionsFound:
                  summary: Transactions found
                  value:
                    data:
                      transactions:
                        - id: p_100231
                          source: payments
                          transactionTime: 2026-10-14 13:45:12
                          orderRef: "987654321"
                          amount: 24.5
                          currencyCode: GBP
                          status: SUCCESS
                          merchantId: 123456
                          merchantName: Example Pizza Co
                          resellerOrderId: ORD-10045
                          paymentMethod: New Card
                          transactionModeId: 1
                          internalReference: REF-10045
                          last4Digits: "1111"
                          shopperId: null
                          net: 23.9
                          deductions: 0.6
                          datman_fee: 0.6
                      timezone: Europe/London
                    pagination:
                      hasMore: true
                      nextCursor: eyJ0IjoiMjAyNi0xMC0xNCAwOToxMjo0NyIsInBJZCI6MTAwMjMwLCJjSWQiOm51bGx9
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          description: The request body failed validation.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                invalidFromDate:
                  summary: fromDate is not YYYY-MM-DD
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: fromDate must be YYYY-MM-DD
        "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/transactions/by-order-id:
    post:
      operationId: searchTransactionsByOrderId
      summary: Search transactions by order identifier
      description: Looks up all transactions matching an identifier, keyed by searchBy
        (order ID by default, or merchant reference, reseller order ID, or
        merchant ID). The merchantId search is bounded by fromDate/toDate,
        defaulting to yesterday through today in the caller's timezone.
      tags:
        - Transactions
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OrderSearchRequest"
            examples:
              byOrderId:
                summary: Search by order ID
                value:
                  query: "987654321"
                  searchBy: orderId
              byMerchantId:
                summary: Search by merchant ID within a date window
                value:
                  query: "123456"
                  searchBy: merchantId
                  fromDate: 2026-10-13
                  toDate: 2026-10-14
                  limit: 25
                  timezone: Europe/London
      responses:
        "200":
          description: "Matching transactions. No match (or no reseller configuration)
            returns an empty page. For a liable merchant (searchBy merchantId)
            the body carries `isLiable: true` and a top-level `timezone` instead
            of `data.timezone`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrderSearchResponse"
              examples:
                transactionsFound:
                  summary: Transactions found
                  value:
                    data:
                      transactions:
                        - id: p_100231
                          source: payments
                          transactionTime: 2026-10-14 13:45:12
                          orderRef: "987654321"
                          amount: 24.5
                          currencyCode: GBP
                          status: SUCCESS
                          merchantId: 123456
                          merchantName: Example Pizza Co
                          resellerOrderId: ORD-10045
                          paymentMethod: New Card
                          transactionModeId: 1
                          internalReference: REF-10045
                          last4Digits: "1111"
                          shopperId: null
                          net: 23.9
                          deductions: 0.6
                          datman_fee: 0.6
                      timezone: Europe/London
                    pagination:
                      hasMore: false
                      nextCursor: null
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          description: The request body failed validation.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                missingQuery:
                  summary: query is missing or empty
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: query 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/transactions/refund-details:
    get:
      operationId: getRefundDetails
      summary: Get refunds recorded against a transaction
      description: Returns the refunds (amount and time) recorded against one payment,
        newest first. For `source=payments` (the default for any value other
        than `card_payment`) the lookup is keyed on orderRef. For
        `source=card_payment` it is keyed on pspReference (the legacy
        CrossReference), or on orderId when isLiable is true. For API key
        callers the merchant that owns the record must belong to the key's
        reseller; otherwise, or when no such record exists, the response is 404.
        This route is registered before `GET /v1/transactions/{orderRef}`, so
        the literal path `/v1/transactions/refund-details` always reaches this
        handler, never the transaction detail lookup.
      tags:
        - Transaction details
      security:
        - ApiKeyAuth: []
      parameters:
        - name: source
          in: query
          required: true
          description: Which table the payment lives in. `card_payment` is the legacy
            table; any other non-empty value is treated as `payments`.
          schema:
            type: string
            examples:
              - payments
              - card_payment
        - name: orderRef
          in: query
          required: false
          description: Datman order reference. Required when source is `payments`. The
            snake_case alias `order_ref` is also accepted.
          schema:
            type: string
          example: "987654321"
        - name: pspReference
          in: query
          required: false
          description: Legacy card_payment CrossReference. Required when source is
            `card_payment` and isLiable is not true. The snake_case alias
            `psp_reference` is also accepted.
          schema:
            type: string
        - name: orderId
          in: query
          required: false
          description: card_payment order ID. Required when source is `card_payment` and
            isLiable is true.
          schema:
            type: string
        - name: isLiable
          in: query
          required: false
          description: Only the exact string `true` enables liable-account lookup; any
            other value means false.
          schema:
            type: string
            enum:
              - "true"
              - "false"
            default: "false"
        - name: timezone
          in: query
          required: false
          description: IANA timezone to render refund times in. Not validated; an unknown
            name results in a 500. When omitted, times are Europe/London.
          schema:
            type: string
          example: Europe/London
      responses:
        "200":
          description: The refunds for the transaction (an empty array when there are
            none). The timezone the times are expressed in is returned in
            `meta.timezone`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CpRefundDetailsResponse"
              examples:
                refundsFound:
                  summary: One partial refund on a payments transaction
                  value:
                    data:
                      - amount: -5
                        time: 2026-10-14 15:02:10
                    meta:
                      timezone: Europe/London
                noRefunds:
                  summary: No refunds recorded
                  value:
                    data: []
                    meta:
                      timezone: Europe/London
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: No record matches the identifier, or (for API key callers) its
            merchant does not belong to the key's reseller. The two cases are
            deliberately indistinguishable.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                transactionNotFound:
                  summary: Unknown or out-of-scope transaction
                  value:
                    error:
                      code: NOT_FOUND
                      message: Transaction not found
        "422":
          description: source is missing, or the identifier that source/isLiable require
            is missing. The message is the same for every case.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                missingParams:
                  summary: A required query parameter is missing
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: Missing required query params
        "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/transactions/{orderRef}:
    get:
      operationId: getTransaction
      summary: Get full details of a transaction
      description: Returns every payment row recorded under an order reference,
        together with its refunds, chargebacks, revenue splits and shopper. For
        API key callers the merchant on the transaction must belong to the key's
        reseller; an unknown order reference and one outside the reseller's
        scope both return 404. Pass `timezone` to get timestamps as `YYYY-MM-DD
        HH:MM:SS` in that zone (see the timestamp notes on the schema).
      tags:
        - Transaction details
      security:
        - ApiKeyAuth: []
      parameters:
        - name: orderRef
          in: path
          required: true
          description: Datman order reference.
          schema:
            type: string
          example: "987654321"
        - name: timezone
          in: query
          required: false
          description: IANA timezone to render timestamps in. Invalid names are ignored.
            When no timezone is resolved, `timezone` in the response is
            Europe/London and timestamps are raw ISO strings.
          schema:
            type: string
          example: Europe/London
      responses:
        "200":
          description: The transaction, its refunds, chargebacks, splits and shopper.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CpTransactionDetailResponse"
              examples:
                transactionWithRefund:
                  summary: A successful payment with a partial refund (timezone=Europe/London)
                  value:
                    data:
                      transactions:
                        - id: 100231
                          order_ref: "987654321"
                          amount: "24.5000"
                          net: "23.9000"
                          fee: "0.6000"
                          datman_fee: 0.6
                          transaction_time: 2026-10-14 13:45:12
                          refund_reason_id: null
                          reason: null
                          currency_code: GBP
                          status_id: 1
                          status: SUCCESS
                          merchant_id: 123456
                          internal_reference: REF-10045
                          shopper_id: null
                          last4_digits: "1111"
                          transaction_mode_id: 1
                          payment_method: New Card
                      refunds:
                        - amount: "-5.0000"
                          net: "-5.0000"
                          fee: "0.0000"
                          internal_reference: REF-10045-R1
                          transaction_time: 2026-10-14 15:02:10
                          reason: Customer request
                      chargebacks: []
                      shopper:
                        first_name: Alex
                        last_name: Example
                        email: alex@example.com
                        address: 1 Example Street
                      splits: []
                      timezone: Europe/London
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: "API key callers only: no transaction exists for the order
            reference, it has no attributable merchant, or the merchant is
            outside the key's reseller."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                transactionNotFound:
                  summary: Unknown or out-of-scope order reference
                  value:
                    error:
                      code: NOT_FOUND
                      message: Transaction not found
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          description: A query failed. The underlying message is logged, not returned.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                databaseError:
                  summary: Detail query failed
                  value:
                    error:
                      code: INTERNAL_ERROR
                      message: Database error
        "503":
          $ref: "#/components/responses/ServiceUnavailable"
    servers:
      - url: https://sandbox-portal.datmanlabs.com/api
        description: Sandbox
  /v1/transactions/{orderRef}/splits:
    get:
      operationId: getTransactionSplits
      summary: Get the revenue split breakdown for a transaction
      description: Returns the split-commission rows recorded for an order (one per
        partner share), including how much of each share has been refunded. For
        API key callers the order's merchant must belong to the key's reseller;
        otherwise, or when the order does not exist, the response is 404. An
        order with no splits returns an empty array.
      tags:
        - Transaction details
      security:
        - ApiKeyAuth: []
      parameters:
        - name: orderRef
          in: path
          required: true
          description: Datman order reference.
          schema:
            type: string
          example: "987654321"
      responses:
        "200":
          description: The split rows for the order (possibly empty).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CpTransactionSplitsResponse"
              examples:
                splitsFound:
                  summary: Order split between the merchant and a partner
                  value:
                    data:
                      - amount: "22.0500"
                        amount_refunded: "0.0000"
                        commission_type: merchant
                        merchant_id: 123456
                      - amount: "2.4500"
                        amount_refunded: "0.0000"
                        commission_type: partner
                        merchant_id: 123457
                noSplits:
                  summary: Order without splits
                  value:
                    data: []
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: "API key callers only: the order does not exist or its merchant is
            outside the key's reseller."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                transactionNotFound:
                  summary: Unknown or out-of-scope order reference
                  value:
                    error:
                      code: NOT_FOUND
                      message: Transaction not found
        "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/transactions/{id}/webhook-payload:
    get:
      operationId: getTransactionWebhookPayloads
      summary: Get webhook deliveries for a transaction
      description: "Returns the webhook calls Datman made for a payment and for every
        payment that shares its order reference: the URL called, the event
        action, the payload sent, the HTTP status received, and when it was
        sent. Any key named `token` is removed from payloads. For API key
        callers the payment's merchant must belong to the key's reseller;
        otherwise, or when the payment does not exist, the response is 404."
      tags:
        - Transaction details
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: Numeric payment ID (payments.id).
          schema:
            type: integer
            minimum: 1
          example: 100231
      responses:
        "200":
          description: Webhook delivery log rows (an empty array when there are none, or
            when the payment exists but has no order reference).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CpWebhookPayloadResponse"
              examples:
                deliveriesFound:
                  summary: One successful delivery
                  value:
                    data:
                      - card_payment_id: 100231
                        webhook_url: https://example.com/webhooks/datman
                        action: payment_success
                        payload:
                          order_id: "987654321"
                          amount: "24.50"
                        created_at: 2026-10-14T13:45:14.000Z
                        http_response_code: 200
                        omt: REF-10045
                noDeliveries:
                  summary: No webhooks recorded
                  value:
                    data: []
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          description: "API key callers only: the payment does not exist or its merchant
            is outside the key's reseller."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                transactionNotFound:
                  summary: Unknown or out-of-scope payment ID
                  value:
                    error:
                      code: NOT_FOUND
                      message: Transaction not found
        "422":
          description: The id is not a positive integer.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
              examples:
                invalidId:
                  summary: id is not a positive integer
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: id must be a positive integer
        "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
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.
    TransactionStatusFilter:
      type: string
      description: A status value accepted in the `status` filter. Any other value is
        rejected with 422.
      enum:
        - SUCCESS
        - REFUND
        - DECLINE
        - RISK-CHECK-DECLINE
        - FAILED
        - ERROR
        - 3DS-PROGRESS
        - PRE_AUTH
        - AUTHORISED
        - CANCELLED
        - DISPUTES
    Pagination:
      type: object
      required:
        - hasMore
        - nextCursor
      properties:
        hasMore:
          type: boolean
          description: Whether more results exist after this page.
        nextCursor:
          type:
            - string
            - "null"
          description: Opaque cursor to pass as `cursor` for the next page; null when
            hasMore is false.
    Transaction:
      type: object
      description: A normalized transaction row. Fields present can vary by reseller
        query type.
      required:
        - id
        - source
        - transactionTime
      additionalProperties: true
      properties:
        id:
          type: string
          description: Transaction identifier (usually prefixed `p_` for payments or `c_`
            for legacy card payments).
        source:
          type: string
          enum:
            - payments
            - card_payment
          description: Source table of the transaction.
        transactionTime:
          type: string
          description: Transaction timestamp, converted to the response timezone when one
            is resolved.
        orderRef:
          type: string
          description: Datman order reference.
        amount:
          type: number
          description: Gross amount in major currency units.
        currencyCode:
          type: string
          description: ISO currency code.
        status:
          type: string
          enum:
            - SUCCESS
            - REFUNDED
            - DECLINE
            - RISK-CHECK-DECLINE
            - FAILED
            - ERROR
            - 3DS-PROGRESS
            - PRE_AUTH
            - AUTHORISED
            - CANCELLED
            - DISPUTES
        merchantId:
          type:
            - integer
            - string
            - "null"
          description: Merchant identifier.
        merchantName:
          type:
            - string
            - "null"
        customerType:
          type:
            - string
            - "null"
        resellerOrderId:
          type:
            - string
            - "null"
          description: The reseller's original order ID, when an ID mapping exists.
        paymentMethod:
          type: string
        transactionModeId:
          type:
            - integer
            - "null"
        internalReference:
          type:
            - string
            - "null"
          description: Merchant reference.
        pspReference:
          type:
            - string
            - "null"
        last4Digits:
          type:
            - string
            - "null"
        shopperId:
          type:
            - string
            - "null"
        net:
          type:
            - number
            - "null"
        deductions:
          type:
            - number
            - "null"
          description: Fees deducted.
        datman_fee:
          type:
            - number
            - "null"
        amountRefunded:
          type:
            - number
            - "null"
          description: Present on liable-merchant results.
    TransactionListRequest:
      type: object
      required:
        - fromDate
        - toDate
      properties:
        fromDate:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: Start calendar date (YYYY-MM-DD), inclusive, in the request timezone.
        toDate:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: End calendar date (YYYY-MM-DD), inclusive, in the request timezone.
        limit:
          type: number
          maximum: 50
          default: 25
          description: Page size. Values above 50 are rejected with 422.
        cursor:
          type: string
          description: The `pagination.nextCursor` value from a previous page.
        status:
          type: array
          items:
            $ref: "#/components/schemas/TransactionStatusFilter"
          description: Only return transactions with these statuses.
        merchantId:
          type: integer
          description: Restrict to one merchant. Non-integer values are ignored.
        timezone:
          type: string
          description: IANA timezone used to interpret the dates and render timestamps.
            Defaults to Europe/London.
          examples:
            - Europe/London
        resellerId:
          type: integer
          description: Optional for API key callers (the key's reseller is always used);
            if supplied it must match, otherwise 403.
    TransactionListResponse:
      type: object
      required:
        - data
        - pagination
      properties:
        data:
          type: object
          required:
            - transactions
          properties:
            transactions:
              type: array
              items:
                $ref: "#/components/schemas/Transaction"
            timezone:
              type: string
              description: Timezone the timestamps are expressed in (Europe/London when none
                resolved).
        pagination:
          $ref: "#/components/schemas/Pagination"
        isLiable:
          type: boolean
          description: Present (true) only when merchantId is a liable merchant.
    OrderSearchRequest:
      type: object
      required:
        - query
      properties:
        query:
          type: string
          minLength: 1
          maxLength: 200
          description: The value to search for (trimmed). The legacy field name `orderId`
            is accepted when `query` is absent.
        searchBy:
          type: string
          enum:
            - orderId
            - merchantReference
            - resellerOrderId
            - merchantId
          default: orderId
          description: Which identifier `query` is matched against. For merchantId,
            `query` must be numeric.
        cursor:
          type: string
          description: The `pagination.nextCursor` value from a previous page.
        limit:
          type: number
          minimum: 1
          maximum: 100
          default: 25
          description: Page size. Values outside 1-100 fall back to 25.
        status:
          type: array
          items:
            $ref: "#/components/schemas/TransactionStatusFilter"
          description: Only return transactions with these statuses.
        timezone:
          type: string
          description: IANA timezone used to render timestamps (and the merchantId date
            window).
          examples:
            - Europe/London
        fromDate:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: searchBy merchantId only. Start calendar date; defaults to yesterday.
        toDate:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: searchBy merchantId only. End calendar date; defaults to today.
    OrderSearchResponse:
      type: object
      required:
        - data
        - pagination
      properties:
        data:
          type: object
          required:
            - transactions
          properties:
            transactions:
              type: array
              items:
                $ref: "#/components/schemas/Transaction"
            timezone:
              type: string
              description: Timezone the timestamps are expressed in. Omitted on empty results.
        pagination:
          $ref: "#/components/schemas/Pagination"
        isLiable:
          type: boolean
          description: Present (true) only for a liable-merchant result.
        timezone:
          type: string
          description: Present only on liable-merchant results with rows, in place of
            data.timezone.
    CpDecimal:
      type:
        - string
        - number
      description: A MySQL DECIMAL computed in SQL. The shared DB client (mysql2
        without decimalNumbers) returns these as strings such as "24.5000";
        parse them as numbers.
    CpDbTimestamp:
      type: string
      description: A transaction timestamp. When a timezone was resolved it is
        "YYYY-MM-DD HH:MM:SS" in that timezone. Otherwise it is an ISO string
        such as "2026-10-14T13:45:12.000Z" whose digits are Europe/London
        wall-clock time, despite the Z suffix.
    CpRefundDetail:
      type: object
      required:
        - amount
        - time
      properties:
        amount:
          type:
            - number
            - string
          description: Refund amount in major units, negative. For source=payments it is
            computed in JS (number); for source=card_payment it is the raw
            card_payment.total column.
        time:
          type: string
          description: Refund time, "YYYY-MM-DD HH:MM:SS" in meta.timezone.
    CpRefundDetailsResponse:
      type: object
      required:
        - data
        - meta
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CpRefundDetail"
        meta:
          type: object
          required:
            - timezone
          properties:
            timezone:
              type: string
              description: Timezone the times are expressed in (Europe/London when none
                given).
    CpTransactionDetailPayment:
      type: object
      description: One payments row recorded under the order reference.
      required:
        - id
        - order_ref
        - amount
        - transaction_time
      properties:
        id:
          type: integer
          description: Payment ID (payments.id). Use it with the webhook-payload endpoint.
        order_ref:
          type: string
        amount:
          $ref: "#/components/schemas/CpDecimal"
        net:
          oneOf:
            - $ref: "#/components/schemas/CpDecimal"
            - type: "null"
        fee:
          oneOf:
            - $ref: "#/components/schemas/CpDecimal"
            - type: "null"
        datman_fee:
          type:
            - number
            - "null"
          description: Datman fee in major units, computed from the fee tier; null when no
            fee configuration is found.
        transaction_time:
          $ref: "#/components/schemas/CpDbTimestamp"
        refund_reason_id:
          type:
            - integer
            - "null"
        reason:
          type:
            - string
            - "null"
          description: Decline or refund reason. Always null for successful positive
            payments.
        currency_code:
          type:
            - string
            - "null"
        status_id:
          type:
            - integer
            - "null"
          description: Raw transaction_status_id.
        status:
          type:
            - string
            - "null"
          enum:
            - SUCCESS
            - REFUNDED
            - DECLINE
            - RISK-CHECK-DECLINE
            - FAILED
            - ERROR
            - 3DS-PROGRESS
            - PRE_AUTH
            - AUTHORISED
            - CANCELLED
            - null
        merchant_id:
          type:
            - integer
            - "null"
        internal_reference:
          type:
            - string
            - "null"
          description: Merchant reference.
        shopper_id:
          type:
            - string
            - "null"
        last4_digits:
          type:
            - string
            - "null"
        transaction_mode_id:
          type:
            - integer
            - "null"
        payment_method:
          type:
            - string
            - "null"
          description: Display label for the payment method (for example New Card, Apple
            Pay, Card on File).
    CpTransactionDetailRefund:
      type: object
      required:
        - amount
        - transaction_time
      properties:
        amount:
          $ref: "#/components/schemas/CpDecimal"
        net:
          oneOf:
            - $ref: "#/components/schemas/CpDecimal"
            - type: "null"
        fee:
          oneOf:
            - $ref: "#/components/schemas/CpDecimal"
            - type: "null"
        internal_reference:
          type:
            - string
            - "null"
        transaction_time:
          $ref: "#/components/schemas/CpDbTimestamp"
        reason:
          type:
            - string
            - "null"
    CpTransactionDetailChargeback:
      type: object
      required:
        - amount
        - transaction_time
        - journal_type
        - status_badge
      properties:
        amount:
          $ref: "#/components/schemas/CpDecimal"
        internal_reference:
          type:
            - string
            - "null"
        transaction_time:
          $ref: "#/components/schemas/CpDbTimestamp"
        transaction_mode_id:
          type:
            - integer
            - "null"
        journal_type:
          type: string
          enum:
            - Chargeback
            - Initial Chargeback
            - Chargeback Reverse
            - Second Chargeback
        status_badge:
          type: string
          enum:
            - Chargeback
            - Chargeback Won
            - 2nd Chargeback
        last4_digits:
          type:
            - string
            - "null"
    CpTransactionShopper:
      type: object
      description: The shopper, from the shoppers table when the payment has a
        shopper_id, otherwise from the billing details on the payment. address
        is always null in the first case.
      properties:
        first_name:
          type:
            - string
            - "null"
        last_name:
          type:
            - string
            - "null"
        email:
          type:
            - string
            - "null"
        address:
          type:
            - string
            - "null"
    CpTransactionSplit:
      type: object
      required:
        - amount
        - amount_refunded
        - commission_type
        - merchant_id
      properties:
        amount:
          $ref: "#/components/schemas/CpDecimal"
        amount_refunded:
          $ref: "#/components/schemas/CpDecimal"
        commission_type:
          type: string
          description: Commission type name from split_commission_types.
        merchant_id:
          type:
            - integer
            - "null"
          description: The partner merchant that receives this share.
    CpTransactionDetail:
      type: object
      required:
        - transactions
        - refunds
        - chargebacks
        - shopper
        - splits
        - timezone
      properties:
        transactions:
          type: array
          description: Payment rows for the order, newest first. Empty for an unknown
            order (portal callers only; API key callers get 404).
          items:
            $ref: "#/components/schemas/CpTransactionDetailPayment"
        refunds:
          type: array
          items:
            $ref: "#/components/schemas/CpTransactionDetailRefund"
        chargebacks:
          type: array
          items:
            $ref: "#/components/schemas/CpTransactionDetailChargeback"
        shopper:
          oneOf:
            - $ref: "#/components/schemas/CpTransactionShopper"
            - type: "null"
        splits:
          type: array
          items:
            $ref: "#/components/schemas/CpTransactionSplit"
        timezone:
          type: string
          description: Timezone the timestamps are expressed in (Europe/London when none
            resolved).
    CpTransactionDetailResponse:
      type: object
      required:
        - data
      properties:
        data:
          $ref: "#/components/schemas/CpTransactionDetail"
    CpTransactionSplitsResponse:
      type: object
      required:
        - data
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CpTransactionSplit"
    CpWebhookDelivery:
      type: object
      required:
        - card_payment_id
        - webhook_url
        - action
        - payload
        - created_at
        - http_response_code
        - omt
      properties:
        card_payment_id:
          type: integer
          description: The payment ID (payments.id) the webhook was sent for.
        webhook_url:
          type: string
        action:
          type: string
          description: Webhook event name.
          examples:
            - payment_success
        payload:
          description: The payload that was sent, parsed from JSON when possible
            (otherwise the raw string), with any `token` key removed. Its keys
            are snake_cased by the response writer.
          oneOf:
            - type: object
              additionalProperties: true
            - type: string
        created_at:
          type: string
          description: When the webhook was sent (ISO string).
        http_response_code:
          type:
            - integer
            - "null"
          description: HTTP status returned by the webhook endpoint.
        omt:
          type:
            - string
            - "null"
          description: The payment's internal (merchant) reference.
    CpWebhookPayloadResponse:
      type: object
      required:
        - data
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CpWebhookDelivery"
  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.
