openapi: 3.0.3
info:
  title: Merchant API
  description: |
    ## Payment Acceptance Made Easy
    The MerchantAPI allows merchants to interact with and retrieve information from the PayPlaza payment system.
    It allows merchants to retrieve information about how their account has been setup with **Stores** and **Terminals**.
    It allows merchants to retrieve the list and the details of **Transactions** and it allows merchants to initiate a new **Payment**.

    ## Errors
    Error responses, HTTP status 400 and higher, will contain a JSON response body with details about the error.
    We follow the error response format proposed in [RFC 7807](https://tools.ietf.org/html/rfc7807) also known as Problem Details for HTTP APIs.
    As with our normal API responses, your client must be prepared to gracefully handle additional members of the response.

    **Note:** Problem `type` and `instance` identifiers in our APIs are not meant to be resolved.
    RFC 7807 encourages that problem types are URI references that point to human-readable documentation, but we deliberately decided against that, as all important parts of the API are documented.
  contact:
    name: Development
    url: https://www.payplaza.com
    email: development@payplaza.com
  version: 1.9.0
servers:
  - url: /merchant/v1
security:
  - ApiKeyAuth: []
tags:
  - name: Security
    description: For managing API keys
  - name: Stores
    description: Operations related to stores
  - name: Terminals
    description: Operations related to terminals
  - name: Version
    description: Retrieves system information
paths:
  /apikeys:
    get:
      operationId: getApiKeys
      tags:
        - Security
      summary: Retrieve details about the available APIKeys
      responses:
        '200':
          description: The list of APIKeys known
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/GetAPIKeyResponse'
        '400':
          description: Bad request.
        '401':
          description: Not Authorized.
        '500':
          description: Internal server error.
    post:
      operationId: createApiKey
      tags:
        - Security
      summary: Create new API key
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAPIKeyRequest'
        required: true
      responses:
        '201':
          description: An API Key is successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateAPIKeyResponse'
        '400':
          description: Bad request.
        '401':
          description: Not Authorized.
        '500':
          description: Internal server error.
  /apikeys/id/{id}:
    delete:
      operationId: deleteApiKey
      tags:
        - Security
      summary: Delete an API key
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '204':
          description: No content.
        '400':
          description: Bad request.
        '401':
          description: Not Authorized.
        '403':
          description: Forbidden.
        '500':
          description: Internal server error.
  /stores:
    get:
      operationId: listStores
      tags:
        - Stores
      summary: List all stores.
      parameters:
        - name: page
          in: query
          description: The page number of your query result
          required: false
          schema:
            format: int32
            default: 1
            minimum: 1
            type: integer
        - name: size
          in: query
          description: The amount of results (defaults to 10)
          required: false
          schema:
            format: int32
            default: 10
            maximum: 100
            minimum: 1
            type: integer
      responses:
        '200':
          description: OK.
          headers:
            Link:
              description: Multiple links providing information about how to navigate through the entries. Links are seperated by a comma ',' Format is compliant with RFC 8288 Web Linking
              required: true
              allowEmptyValue: true
              style: simple
              schema:
                type: string
            X-Total-Count:
              description: Total number of entries available
              required: true
              allowEmptyValue: false
              style: simple
              schema:
                type: number
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Store'
        '400':
          description: Bad request.
        '500':
          description: Internal server error.
  /terminals:
    get:
      operationId: listTerminals
      tags:
        - Terminals
      summary: List all terminals.
      parameters:
        - name: page
          in: query
          description: The page number of your query result, starting at 1
          required: false
          schema:
            format: int32
            default: 1
            minimum: 1
            type: integer
        - name: size
          in: query
          description: The amount of results per page, maximum 100 (defaults to 10)
          required: false
          schema:
            format: int32
            default: 10
            maximum: 100
            minimum: 1
            type: integer
      responses:
        '200':
          description: OK.
          headers:
            Link:
              description: Multiple links providing information about how to navigate through the entries. Links are seperated by a comma ',' Format is compliant with [https://datatracker.ietf.org/doc/html/rfc8288](RFC 8288 Web Linking)
              required: true
              allowEmptyValue: true
              style: simple
              schema:
                type: string
            X-Total-Count:
              description: Total number of entries available
              required: true
              allowEmptyValue: false
              style: simple
              schema:
                type: number
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Terminal'
        '400':
          description: Bad request.
        '500':
          description: Internal server error.
  /terminals/{manufacturer}-{model}-{serial}:
    get:
      operationId: getTerminal
      tags:
        - Terminals
      summary: Get terminal by manufacturer, model & serial.
      parameters:
        - name: manufacturer
          in: path
          description: Manufacturer name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: model
          in: path
          description: Model name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: serial
          in: path
          description: Serial(number) of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
      responses:
        '200':
          description: OK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Terminal'
        '400':
          description: Bad request.
        '500':
          description: Internal server error.
  /terminals/{manufacturer}-{model}-{serial}/daytotals/today:
    get:
      operationId: getTerminalDayTotals
      tags:
        - Terminals
      summary: Get the day totals for the terminal by manufacturer, model & serial.
      parameters:
        - name: manufacturer
          in: path
          description: Manufacturer name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: model
          in: path
          description: Model name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: serial
          in: path
          description: Serial(number) of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
      responses:
        '200':
          description: OK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Receipt'
        '400':
          description: Bad request.
        '500':
          description: Internal server error.
  /terminals/{manufacturer}-{model}-{serial}/transactions:
    get:
      operationId: listTerminalTransactions
      tags:
        - Terminals
      summary: List transactions by terminal.
      parameters:
        - name: manufacturer
          in: path
          description: Manufacturer name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: model
          in: path
          description: Model name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: serial
          in: path
          description: Serial(number) of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: page
          in: query
          description: The page number of your query result, starting at 1
          required: false
          schema:
            format: int32
            default: 1
            minimum: 1
            type: integer
        - name: size
          in: query
          description: The amount of results per page, maximum 100 (defaults to 10)
          required: false
          schema:
            format: int32
            default: 10
            maximum: 100
            minimum: 1
            type: integer
      responses:
        '200':
          description: OK.
          headers:
            Link:
              description: Multiple links providing information about how to navigate through the entries. Links are seperated by a comma ',' Format is compliant with RFC 8288 Web Linking
              required: true
              allowEmptyValue: true
              style: simple
              schema:
                type: string
            X-Total-Count:
              description: Total number of entries available
              required: true
              allowEmptyValue: false
              style: simple
              schema:
                type: number
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Transaction'
        '400':
          description: Bad request.
        '500':
          description: Internal server error.
    post:
      operationId: createTerminalTransaction
      tags:
        - Terminals
      summary: Create new transaction for terminal.
      description: |-
        The Merchant-API will make sure only one newly created transaction is available for a specific terminal.
                    This means that when creating a new transaction, previous transaction(s) with status CREATED will be aborted.
                    So given transactions A and B, when transaction A has not been retrieved by the terminal when creating transaction B the Merchant API will abort transaction A, and the terminal will receive transaction B.
                
      parameters:
        - name: manufacturer
          in: path
          description: Manufacturer name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: model
          in: path
          description: Model name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: serial
          in: path
          description: Serial(number) of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NewTransaction'
            examples:
              Purchase:
                value:
                  type: PURCHASE
                  merchant_order_reference: '1234'
                  amount:
                    value: 0.01
                    currency: EUR
              Unreferenced refund:
                value:
                  type: REFUND
                  merchant_order_reference: '1234'
                  amount:
                    value: 0.01
                    currency: EUR
              Referenced refund:
                value:
                  type: REFUND
                  merchant_order_reference: '1234'
                  amount:
                    value: 0.01
                    currency: EUR
                  reference:
                    id: '12345678'
      responses:
        '201':
          description: Created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
        '400':
          description: Bad request.
        '500':
          description: Internal server error.
        '501':
          description: Not yet implemented.
  /terminals/{manufacturer}-{model}-{serial}/transactions/{id}:
    get:
      operationId: getTerminalTransaction
      tags:
        - Terminals
      summary: Get transaction by terminal and id.
      parameters:
        - name: manufacturer
          in: path
          description: Manufacturer name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: model
          in: path
          description: Model name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: serial
          in: path
          description: Serial(number) of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: id
          in: path
          description: Identifier of a transaction
          required: true
          schema:
            maxLength: 31
            minLength: 31
            pattern: '[0-9]{31}'
            type: string
      responses:
        '200':
          description: OK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
        '400':
          description: Bad request.
        '404':
          description: Not found.
        '500':
          description: Internal server error.
    delete:
      operationId: deleteTerminalTransaction
      tags:
        - Terminals
      summary: Abort a transaction by terminal and id.
      parameters:
        - name: manufacturer
          in: path
          description: Manufacturer name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: model
          in: path
          description: Model name of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: serial
          in: path
          description: Serial(number) of the terminal
          required: true
          schema:
            maxLength: 255
            minLength: 1
            type: string
        - name: id
          in: path
          description: Identifier of a transaction
          required: true
          schema:
            maxLength: 31
            minLength: 31
            pattern: '[0-9]{31}'
            type: string
      responses:
        '204':
          description: No Content
        '404':
          description: Not found.
        '409':
          description: Conflict. The transaction is in a state that can't be aborted
  /version:
    get:
      operationId: getVersion
      tags:
        - Version
      summary: Retrieving the system version.
      responses:
        '400':
          description: Bad request.
        '500':
          description: Internal server error.
        default:
          description: OK.
          content:
            application/json:
              schema:
                type: string
              example: 1.0.0
components:
  schemas:
    Problem:
      type: object
      properties:
        type:
          format: uri-reference
          description: |
            A URI reference that uniquely identifies the problem type only in the context of the provided API. Opposed to the specification in RFC-7807, it is neither recommended to be dereferenceable and point to a human-readable documentation nor globally unique for the problem type.
          default: about:blank
          type: string
          example: /some/uri-reference
        title:
          description: |
            A short summary of the problem type. Written in English and readable for engineers, usually not suited for non technical stakeholders and not localized.
          type: string
          example: some title for the error situation
        status:
          format: int32
          description: |
            The HTTP status code generated by the origin server for this occurrence of the problem.
          maximum: 600
          exclusiveMaximum: true
          minimum: 100
          type: integer
        detail:
          description: |
            A human readable explanation specific to this occurrence of the problem that is helpful to locate the problem and give advice on how to proceed. Written in English and readable for engineers, usually not suited for non technical stakeholders and not localized.
          type: string
          example: some description for the error situation
        instance:
          format: uri-reference
          description: |
            A URI reference that identifies the specific occurrence of the problem, e.g. by adding a fragment identifier or sub-path to the problem type. May be used to locate the root of this problem in the source code.
          type: string
          example: /some/uri-reference#specific-occurrence-context
    Address:
      required:
        - address
        - zipCode
        - city
        - countryCode
      type: object
      properties:
        address:
          description: Address line, e.g. streetname and number
          maxLength: 255
          minLength: 1
          type: string
        zipCode:
          description: Zip code
          maxLength: 255
          minLength: 1
          type: string
        city:
          description: City name
          maxLength: 255
          minLength: 1
          type: string
        stateCode:
          description: State of province code, according to country local regulations
          maxLength: 255
          minLength: 1
          type: string
          nullable: true
        countryCode:
          description: Alpha-2 Country code according to <a href="https://en.wikipedia.org/wiki/ISO_3166">ISO 3166</a>
          maxLength: 2
          minLength: 2
          type: string
    Amount:
      description: Describes how much money the transaction should be.<br />'value' is a number value with a dot (.) as decimal separator. It should NOT have any digit grouping or thousands separators<br />'currency' is a 3-letter-code, compliant with <a href="https://en.wikipedia.org/wiki/ISO_4217">ISO 4217</a>
      required:
        - value
        - currency
      type: object
      properties:
        value:
          pattern: \d+\.\d{2}
          type: number
        currency:
          description: Currency Code
          enum:
            - EUR
            - USD
            - GBP
          type: string
      example:
        value: 10298.75
        currency: EUR
    CreateAPIKeyRequest:
      required:
        - label
      type: object
      properties:
        label:
          type: string
        validity:
          type: object
          nullable: true
          allOf:
            - $ref: '#/components/schemas/Validity'
    CreateAPIKeyResponse:
      required:
        - id
        - label
        - apikey
      type: object
      properties:
        id:
          maxLength: 15
          minLength: 15
          pattern: \d{15}
          type: string
        label:
          type: string
        apikey:
          maxLength: 50
          minLength: 50
          pattern: '[a-z-A-Z0-9]{50}'
          type: string
    Device:
      required:
        - manufacturer
        - model
        - serial
      type: object
      properties:
        manufacturer:
          description: Manufacturer name of the device
          maxLength: 255
          minLength: 1
          type: string
        model:
          description: Model name of the device
          maxLength: 255
          minLength: 1
          type: string
        serial:
          description: Serial(number) of the device
          maxLength: 255
          minLength: 1
          type: string
    GetAPIKeyResponse:
      required:
        - id
        - label
      type: object
      properties:
        id:
          maxLength: 15
          minLength: 15
          pattern: \d{15}
          type: string
        label:
          description: The label given by the user
          type: string
        lastUsage:
          format: date-time
          type: string
          nullable: true
        validity:
          type: object
          nullable: true
          allOf:
            - $ref: '#/components/schemas/Validity'
    NewTransaction:
      description: Information for Transaction to be created at PayPlaza
      required:
        - merchant_order_reference
        - type
        - amount
      type: object
      properties:
        merchant_order_reference:
          description: Reference provided by the Merchant for future identification of this Transaction<br />This field may contain all letters in lowercase and uppercase, digit, underscore '_' and <a href="https://en.wikipedia.org/wiki/Hyphen-minus">hyphen-minus</a> '-'Usually a unique identifier generated by the Merchant<br />
          maxLength: 14
          minLength: 1
          pattern: ([0-9a-zA-Z]|-|_){1,14}
          type: string
          example: '''TEN-103_1'', ''3987462423900'', ''Q99PM-2QHFW-FQ'''
        type:
          $ref: '#/components/schemas/TransactionType'
        amount:
          $ref: '#/components/schemas/Amount'
        reference:
          type: object
          nullable: true
          allOf:
            - $ref: '#/components/schemas/TransactionReference'
    Receipt:
      required:
        - receipt
      type: object
      properties:
        receipt:
          description: List of lines for the receipt
          type: string
    Store:
      title: Store
      description: Information about Store where merchant can do transactions.
      required:
        - uuid
        - name
        - address
      type: object
      properties:
        uuid:
          allOf:
            - $ref: '#/components/schemas/UUID'
            - description: Identifier of the store
        name:
          description: Name of the store
          maxLength: 255
          minLength: 1
          type: string
        address:
          allOf:
            - $ref: '#/components/schemas/Address'
            - description: The address of the store
    Store1:
      title: StoreSummary
      description: Information about Store where merchant can do transactions.
      required:
        - uuid
        - name
      type: object
      properties:
        uuid:
          allOf:
            - $ref: '#/components/schemas/UUID'
            - description: Identifier of the store
        name:
          description: Name of the store
          maxLength: 255
          minLength: 1
          type: string
    Terminal:
      required:
        - device
      type: object
      properties:
        device:
          $ref: '#/components/schemas/Device'
    Transaction:
      description: A transaction
      required:
        - id
        - creation_datetime
        - merchant_order_reference
        - merchant_id
        - type
        - status
        - store
        - amount
      type: object
      properties:
        id:
          description: Unique identifier generated by PayPlaza for this transaction.<br />Format will be 31 numeric characters
          pattern: '[0-9]{31}'
          type: string
        creation_datetime:
          allOf:
            - $ref: '#/components/schemas/ZonedDateTime'
            - description: 'Datetime identifying the moment the transaction was created at CM.com and in CM.com timezone.<br />The creation date is specified in the <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> format.<br />The date on the receipt is formatted to the store timezone. pattern: "ISO 8601: "YYYY-MM-DD''T''hh:mm:ssZ"'
              example: '2022-01-19T12:58:00Z'
        merchant_order_reference:
          description: Identifier provided by the merchant when creating the transaction.
          maxLength: 14
          minLength: 1
          pattern: ([0-9a-zA-Z]|-|_){1,14}}
          type: string
          example: '''TEN-103_1'', ''3987462423900'', ''Q99PM-2QHFW-FQ'''
        brand:
          description: Optional field, which will only be filled if this transaction is authorized by a processor.<br /><br />Identifies the brand on the bankcard of the consumer, possible values:<br />AMEX, CIRRUS, CUP, DINERS, DISCOVER, JCB, MAESTRO, MASTERCARD, VISA, V_PAY.
          type: string
          nullable: true
        system_trace_audit_number:
          description: Optional field, which will only be filled if this transaction is authorized by a processor.<br /><br />Identifier generated by PayPlaza to trace a transaction through its lifecycle with a processor.<br />* Format is a 6 digit number, but should be treated as a string.<br />* Unique per day per processor, so not unique for merchants.
          type: string
          nullable: true
        receipt:
          description: Optional field, which will only be filled if this transaction cleared or cancelled.<br /><br />Plain text description of the transaction, contains required information needed to print a proof of the transaction of the consumer.
          type: string
          nullable: true
        merchant_receipt:
          description: Optional field.<br /><br />Plain text description of the transaction, contains required information needed to print a proof of the transaction of the merchant.
          type: string
          nullable: true
        original_id:
          description: Optional field, which will only be filled if this transaction is a REFUND.<br /><br />This field contains the id of the original PURCHASE transaction to which this transaction is a refund.
          pattern: '[0-9]{31}'
          type: string
          nullable: true
        authorization_code:
          description: Optional field, which will only be filled if this transaction is authorized by a processor.<br /><br />This field contains the authentication provided by the processor of the transaction.
          pattern: '[0-9]{6}'
          type: string
          nullable: true
        merchant_id:
          description: Identifier of the merchant that initiated this transaction.
          type: string
        processor_terminal_id:
          description: Optional field, which will only be filled after this transaction is authorized.<br /><br />Terminal ID provided by the processor of the transaction.
          type: string
          nullable: true
        type:
          $ref: '#/components/schemas/TransactionType'
        amount:
          $ref: '#/components/schemas/Amount'
        store:
          type: object
          nullable: true
          allOf:
            - $ref: '#/components/schemas/Store1'
        result:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/TransactionResult'
        status:
          $ref: '#/components/schemas/TransactionStatus'
    TransactionReference:
      description: Reference object that represents a unique identifier for a transaction
      type: object
      properties:
        id:
          description: Unique identifier that identifies a transaction
          type: string
    TransactionResult:
      description: Final outcome of processing the transaction.<dl><dt>APPROVED</dt><dd>Indicates that the bank of the consumer authorized the payment.</dd><dt>DECLINED</dt><dd>Indicates that the bank of the consumer does NOT approve the payment.</dd></dl>
      enum:
        - APPROVED
        - DECLINED
      type: string
    TransactionStatus:
      description: <strong>Current state of a transaction.</strong><dl><dt>CREATED</dt><dd>Transaction is created and waiting authorization.</dd><dt>AUTHORIZED</dt><dd>Transaction is authorized and awaiting clearance.</dd><dt>CLEARED</dt><dd>Transaction is cleared and is completed successfully.</dd><dt>CANCELLED</dt><dd>Transaction is cancelled and is completed unsuccessfully.</dd>
      enum:
        - CREATED
        - AUTHORIZED
        - CLEARED
        - CANCELLED
      type: string
    TransactionType:
      description: <dl><dt>PURCHASE</dt><dd>Indicates a purchase where the money will flow from the consumer to the merchant</dd><dt>PRE_AUTH</dt><dd>Indicates a claim on a certain amount of money on the bankaccount of the consumer</dd><dt>REFUND</dt><dd>Indicates a refunds where the money will flow from the merchant back to the consumer</dd></dl>
      enum:
        - PURCHASE
        - PRE_AUTH
        - REFUND
      type: string
    UUID:
      format: uuid
      pattern: '[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}'
      type: string
    Validity:
      type: object
      properties:
        from:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/ZonedDateTime'
        until:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/ZonedDateTime'
    ZonedDateTime:
      format: date-time
      type: string
      example: '2022-03-10T12:15:50-04:00'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      description: Authentication via the API Key provided by PayPlaza
      name: API-Key
      in: header
x-readme:
  explorer-enabled: true
  proxy-enabled: true
