openapi: 3.0.1
info:
  title: Payments REST APIs
  description:  |
    Payments Internal REST APIs
    
    # Mapping for rejection reasons
    
    The rejection reason is mapped based on the failure codes received by the payments service.
    
    The following examples show the mapping between the failure codes and the resulting rejection reason.
    
    ## Case 1
    The failure code starts with:
    ```
    urn:plmr-internal:workflow:payments
    ```
    
    #### Case 1.1
    
    The failure code is:
    ```
    {
      "code": "urn:plmr-internal:workflow:payments:INITIATE_PAYMENT_ORDER:ACCOUNT_ACCESS_RESTRICTED",
      "message": "" // ignored
    }
    ```
    The resulting rejection reason becomes:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:initiation:ACCOUNT_ACCESS_RESTRICTED",
      "message": "Payment rejected due to incorrect IBAN"
    }
    ```

    #### Case 1.2
    
    The failure code is:
    ```
    {
      "code": "urn:plmr-internal:workflow:payments:INITIATE_PAYMENT_ORDER:ACCOUNT_CURRENCY_MISMATCH",
      "message": "" // ignored
    }
    ```
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:initiation:ACCOUNT_CURRENCY_MISMATCH",
      "message": "Payment rejected due to debtor account currency mismatch"
    }
    ```
    
    #### Case 1.3
    
    The failure code doesn't match any of the known failure codes:
    ```
    {
      "code": "urn:plmr-internal:workflow:payments:NOT_HANDLED_ERROR",
      "message": "" // ignored
    }
    ```
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:initiation:INTERNAL_TECHNICAL_ERROR",
      "message": "Internal technical error"
    }
    ```
    
    ## Case 2
    
    The failure code starts with:
    ```
    urn:plmr-internal:transactions:
    ```
    
    #### Case 2.1
    
    The failure code matches the following regular expression:
    ```
    urn:plmr-internal:transactions:.+:INSUFFICIENT_FUNDS
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:transactions:ANY_SOURCE:INSUFFICIENT_FUNDS",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:INSUFFICIENT_FUNDS",
      "message": "Payment rejected due to insufficient funds"
    }
    ```
    
    #### Case 2.2
    
    The failure code matches the following regular expression:
    ```
    urn:plmr-internal:transactions:.+:INVALID_ACCOUNT_STATE
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:transactions:ANY_SOURCE:INVALID_ACCOUNT_STATE",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:INVALID_ACCOUNT_STATE",
      "message": "Payment rejected due to invalid account state"
    }
    ```

    #### Case 2.3
    
    The failure code doesn't match any of the above regular expressions.
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:transactions:NOT_HANDLED",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:BLOCKED_BY_CORE",
      "message": "Payment blocked by the CORE system"
    }
    ```
    
    ## Case 3
    
    The failure code starts with:
    ```
    urn:plmr-internal:transaction-monitoring:
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:transaction-monitoring:MONITORING_EXCEPTION",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:aml:BLOCKED_BY_AML",
      "message": "Payment blocked by the AML system"
    }
    ```
    
    ## Case 4
    
    The failure code starts with:
    ```
    urn:plmr-internal:payment-gateway:
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:payment-gateway:GATEWAY_EXCEPTION",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:pgw:BLOCKED_BY_PGW",
      "message": "Payment blocked by the Payment Gateway"
    }
    ```
    
    ## Case 5
    
    The failure code starts with:
    ```
    urn:plmr:payments:aml:
    ```
    
    #### Case 5.1
    
    The failure code is:
    ```
    {
      "code": "urn:plmr:payments:aml:BLOCKED_BY_FRAUD",
      "message": "The message was blocked by fraud checks."
    }
    ```
    
    For this case, the rejection reason message is the same as the failure message.
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:INSUFFICIENT_FUNDS",
      "message": "The message was blocked by fraud checks." // same as failure message
    }
    ```
    
    #### Case 5.2
    
    The failure code doesn't match any of the codes above.
    ```
    {
      "code": "urn:plmr:payments:aml:UNHANDLED",
      "message": "The message was blocked by fraud checks."
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:initiation:INTERNAL_TECHNICAL_ERROR",
      "message": "Internal technical error"
    }
    ```
    
    ## Case 6
    
    The failure code starts with:
    ```
    urn:plmr-internal:payments:
    ```
    
    #### Case 6.1
    
    The failure code matches the following regular expression:
    ```
    urn:plmr-internal:payments:.+:ACC_NOT_FOUND
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:payments:connector:ACC_NOT_FOUND",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:ACCOUNT_NOT_FOUND",
      "message": "Payment rejected due to account not found"
    }
    ```
    
     #### Case 6.2
    
    The failure code matches the following regular expression:
    ```
    urn:plmr-internal:payments:.+:ACC_BLOCKED
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:payments:connector:ACC_BLOCKED",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:ACCOUNT_BLOCKED",
      "message": "Payment rejected due to blocked account"
    }
    ```
    
     #### Case 6.3
    
    The failure code matches the following regular expression:
    ```
    urn:plmr-internal:payments:.+:ACC_NOT_ACTIVE
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:payments:connector:ACC_NOT_ACTIVE",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:ACCOUNT_NOT_ACTIVE",
      "message": "Payment rejected due to account not active"
    }
    ```
    
    #### Case 6.4
    
    The failure code matches the following regular expression:
    ```
    urn:plmr-internal:payments:.+:INSUFF_FUNDS
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:payments:connector:INSUFF_FUNDS",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:INSUFFICIENT_FUNDS",
      "message": "Payment rejected due to insufficient funds"
    }
    ```
    
    #### Case 6.5
    
    The failure code matches the following regular expression:
    ```
    urn:plmr-internal:payments:.+:TRANSACTION_AMOUNT_RESERVATION_FAILED
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:payments:connector:TRANSACTION_AMOUNT_RESERVATION_FAILED",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:INSUFFICIENT_FUNDS",
      "message": "Payment rejected due to insufficient funds"
    }
    ```
    
    #### Case 6.6
    
    The failure code matches the following regular expression:
    ```
    urn:plmr-internal:payments:.+:RESERVED_TRANSACTION_AMOUNT_REVERSAL_FAILED
    ```
    
    Example:
    ```
    {
      "code": "urn:plmr-internal:payments:connector:RESERVED_TRANSACTION_AMOUNT_REVERSAL_FAILED",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:INSUFFICIENT_FUNDS",
      "message": "Payment rejected due to insufficient funds"
    }
    ```
    
    #### Case 6.7
    
    The failure code doesn't match any of the codes above.
    ```
    {
      "code": "urn:plmr-internal:payments:connector:OTHER_REASON",
      "message": "" // ignored
    }
    ```
    
    The resulting rejection reason:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:core:BLOCKED_BY_CORE",
      "message": "Payment blocked by the CORE system"
    }
    ```
    
    ## Default case
    
    If none of the cases above apply, the rejection reason is:
    ```
    "rejectionReason": {
      "code": "urn:plmr:payments:initiation:INTERNAL_TECHNICAL_ERROR",
      "message": "Internal technical error"
    }
    ```

  version: '1'
servers:
  - url: 'https://api.plumery.com'
    description: Live Server
paths:
  '/internal/v1/parties/{partyId}/payments':
    post:
      tags:
        - PaymentsInternal
      description: |
        Initiate a new payment.
        Payment can be initiated with either ``counterpartyId`` or counterparty details.
        For initiation with counterpartyId, ``counterpartyId`` field is mandatory.
        For initiation with counterparty details, ``creditorAccount`` and ``creditorName`` are mandatory.
        Providing both ``counterpartyId`` and counterparty details like ``creditorAddress`` will result in 400 Bad request response.
      operationId: Initiate Payment
      summary: Initiate Payment
      parameters:
        - $ref: '#/components/parameters/partyId'
        - $ref: '#/components/parameters/plmrIdempotencyKey'
        - $ref: '#/components/parameters/xRequestId'
        - $ref: '#/components/parameters/plmrMfaChallengeId'
        - $ref: '#/components/parameters/plmrMfaSignature'
        - $ref: '#/components/parameters/plmrUserAction'
        - $ref: '#/components/parameters/xDeviceIntegrityToken'
        - $ref: '#/components/parameters/Authorization'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InitiatePaymentRequest'
        required: true
      responses:
        '202':
          description: Payment accepted for processing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InitiatePaymentResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/UnauthorizedMfaRequired'
        '409':
          $ref: '#/components/responses/IdempotencyPayloadError'
        '423':
          $ref: '#/components/responses/IdempotencyProcessingError'
        '500':
          $ref: '#/components/responses/ServerError'
        default:
          description: Unexpected error
      x-plumery-audit-action-type: PaymentInitiated
      x-plumery-audit-action-name: Payment Initiated
      x-plumery-audit-action-description: User initiated payment
      x-internal: true
  '/internal/v1/parties/{partyId}/payments/{paymentId}':
    get:
      tags:
        - PaymentsInternal
      description: |
        Retrieve payment details.
      x-plumery-audit-action-type: PaymentDetailsViewed
      x-plumery-audit-action-name: Payment Details Viewed
      x-plumery-audit-action-description: User viewed detailed payment information
      operationId: Retrieve Payment Details
      summary: Retrieve Payment Details
      parameters:
        - $ref: '#/components/parameters/partyId'
        - $ref: '#/components/parameters/paymentId'
        - $ref: '#/components/parameters/plmrUserAction'
      responses:
        '200':
          description: Get payment details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentDetailsResponse'
        '404':
          description: The payment with the provided ID was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/ServerError'
        default:
          description: Unexpected error
      x-internal: true
  '/internal/v1/parties/{partyId}/payments/{paymentId}/status':
    get:
      tags:
        - PaymentsInternal
      description: |
        Retrieve payment execution status.
      x-plumery-audit-action-type: PaymentStatusViewed
      x-plumery-audit-action-name: Payment Status Viewed
      x-plumery-audit-action-description: User viewed payment execution status
      operationId: Retrieve Payment Execution Status
      parameters:
        - $ref: '#/components/parameters/partyId'
        - $ref: '#/components/parameters/paymentId'
        - $ref: '#/components/parameters/plmrUserAction'
      responses:
        '200':
          description: Get payment execution status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentExecutionStatusResponse'
        '404':
          description: The payment with the provided ID was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/ServerError'
        default:
          description: Unexpected error
      summary: Retrieve Payment Execution Status

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  responses:
    BadRequest:
      description: Invalid request was provided
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    IdempotencyProcessingError:
      description: The initial request is in progress.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/IdempotencyErrorResponse'
    IdempotencyPayloadError:
      description: The idempotency key has already been used with a different payload
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/IdempotencyErrorResponse'
    UnauthorizedMfaRequired:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UnauthorizedResponseMFARequired'
    ServerError:
      description: Internal server error occurred
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  parameters:
    partyId:
      in: path
      name: partyId
      required: true
      example: 6878951b-256b-4baa-9e81-ad4c577adc4e
      schema:
        $ref: "#/components/schemas/PartyId"
      description: |
        The ID of the party that owns the accounts. See PartyId Model.
    paymentId:
      in: path
      name: paymentId
      required: true
      example: 2751d7d9-df79-4412-b4c4-28aaa7075548
      schema:
        $ref: "#/components/schemas/PaymentIdParameter"
      description: |
        The ID of the payment. See PaymentIdParameter model.
    plmrIdempotencyKey:
      in: header
      name: plmr-idempotency-key
      description: |
        The idempotency key for the request. See plmrIdempotencyKey model.
      required: true
      example: 2318951c-356e-3bcd-9e94-ad4c593adc4f
      schema:
        $ref: "#/components/schemas/plmrIdempotencyKey"
    xRequestId:
      in: header
      name: X-Request-ID
      description: |
        Request id is used for tracing, if not provided, a new one will be generated. See xRequestId model.
      required: false
      example: 36a22460-ebc8-4ffe-a213-1683c5a420c5
      schema:
        $ref: "#/components/schemas/xRequestId"
    plmrMfaChallengeId:
      in: header
      name: plmr-mfa-challenge-id
      description: MFA challenge id. See plmrMfaChallengeId model.
      schema:
        $ref: "#/components/schemas/plmrMfaChallengeId"
    plmrMfaSignature:
      in: header
      name: plmr-mfa-signature
      description: MFA signature from 401 response. See plmrMfaSignature model.
      schema:
        $ref: "#/components/schemas/plmrMfaSignature"
    plmrUserAction:
      in: header
      name: plmr-user-action
      description: |
        Header used to indicate whether the request is user initiated request. 
        When set to `true`, the user session gets extended with the default session timeout. 
        When set to `false`, or header is not present the user session is not extended.
        See plmrUserAction model.
      required: false
      schema:
        $ref: "#/components/schemas/plmrUserAction"
    xDeviceIntegrityToken:
      in: header
      name: X-Device-Integrity-Token
      description: Device integrity token obtains from Google/Apple. See xDeviceIntegrityToken model.
      schema:
        $ref: "#/components/schemas/xDeviceIntegrityToken"
    Authorization:
      in: header
      required: true
      name: Authorization
      description: | 
        Authorization JWT access token obtained from keycloak. 
        If the header is missing, has the wrong format or the token is expired 
        an Unauthorized 401 response will be returned. 
        See Authorization model.
      schema:
        $ref: "#/components/schemas/Authorization"
    authSessionCookie:
      in: cookie
      name: auth-session
      description: |
        Authentication session cookie used for user authentication.
        See authSessionCookie model.
      required: true
      schema:
        $ref: "#/components/schemas/authSessionCookie"
  schemas:
    PartyId:
      type: string
      description: The ID of the party that owns the accounts.
      example: 6878951b-256b-4baa-9e81-ad4c577adc4e
    PaymentMethodId:
      type: string
      maxLength: 36
      minLength: 36
      description: The unique Id of a single payment method
    PaymentIdParameter:
      type: string
      description: The ID of the payment.
      example: 2751d7d9-df79-4412-b4c4-28aaa7075548
    plmrIdempotencyKey:
      type: string
      description: The idempotency key for the request.
      example: 2318951c-356e-3bcd-9e94-ad4c593adc4f
    xRequestId:
      type: string
      description: Request id is used for tracing, if not provided, a new one will be generated.
      example: 36a22460-ebc8-4ffe-a213-1683c5a420c5
    plmrMfaChallengeId:
      type: string
      example: 235ea8df-c08d-40ab-bbcb-931dd74846fd
      minLength: 36
      maxLength: 36
      description: MFA challenge id.
    plmrMfaSignature:
      type: string
      example: 84f3b0e7f851c2ff8a4a0b6b8921c778a90184e7927e9412ae0359f1ce8da5cf68eeac4e2851515532fe78e76435e551213635ee42650fd5527ec8cf78ebdb7a
      minLength: 128
      maxLength: 128
      description: MFA signature from 401 response.
    plmrUserAction:
      type: boolean
      example: true
      description: |
        Header used to indicate whether the request is user initiated request. 
        When set to `true`, the user session gets extended with the default session timeout. 
        When set to `false`, or header is not present the user session is not extended.
    xDeviceIntegrityToken:
      type: string
      example: 84f3b0e7f851c2ff8a4a0b6b8921c778a90184e7927e9412ae0359f1ce8da5cf68eea
      description: Device integrity token obtains from Google/Apple.
    Authorization:
      type: string
      example: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJIUkRPaWtqejFMQ0xCVU1Sc1loRUEwcXZDN2NGYVVsN0VrdTNILUUtMHJnIn0.eyJleHAiOjE3NjgzODUzODEsImlhdCI6MTc2ODM4NTA4MSwianRpIjoiYThjZDY1ZDgtZWZhZS00ZGViLWFhNTYtZWZkOGRiNWJjOTU2IiwiaXNzIjoiaHR0cDovL3BsdW1lcnkta2V5Y2xvYWsucGx1bWVyeS1rZXljbG9hay9yZWFsbXMvcGx1bWVyeSIsInN1YiI6Ijc5ODczZjEwLTc5MGItNDNlZS1hODFkLWJiYzY2ZmFiMzE2ZiIsInR5cCI6IkJlYXJlciIsImF6cCI6InBsdW1lcnktY2xpZW50Iiwic2lkIjoiZjBlYzhiNTAtYjBlMy00NGM3LTkwYjQtMTUzMmU0OTI0MzliIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyIvKiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1wbHVtZXJ5Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwic2NvcGUiOiJwaG9uZSBlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiQ2hhZWwgV2Fja3MiLCJwaG9uZV9udW1iZXIiOiIrMzcyMDAwMDA3NjYiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiI4MTExMTEzIiwiZ2l2ZW5fbmFtZSI6IkNoYWVsIiwiZmFtaWx5X25hbWUiOiJXYWNrcyIsImVtYWlsIjoidGVzdC51c2VyMjExQHBsdW1lcnkuY29tIn0.E1RmpxjloqvfKDWzCes1BNPo4H9AJrpru6dHgzc4FPX4vpQhZy_ypqZ9IW94ukn8hrdjB6e3H959q8Kp96jSkknFIWFhfDUyAwh-OHe7dNX6j7IxtzBIupQWbCoOSA_nVfPXJr8Qwgl9ud2mv4ZIZmxZG_4BVsrMA_xM85j9w1v2PTR_f_LBkAXUSJbFtiLlJRTkUwWfd2-eM74Dvj4TVb2DyILiE_ipiXTHpAqsPVLUo_cqa9vXdMqks6QyS2nHx_NpKk7T4L_yBEWiPgOApcThRptSTcsJ1eF0l68203o0aP77sLaIZPMAbx_ZvyXaMr-8wKYjHQiLu99vg33QXg
      description: | 
        Authorization JWT access token obtained from keycloak.
        If the header is missing, has the wrong format or the token is expired
        an Unauthorized 401 response will be returned.
    authSessionCookie:
      type: string
      description: Authentication session cookie used for user authentication.
    MFAErrorCode:
      type: string
      enum:
        - 'urn:plmr:payments:api:MFA_REQUIRED'
      example: 'urn:plmr:payments:api:MFA_REQUIRED'
    PaymentsErrorCode:
      type: string
      enum:
        - 'urn:plmr:payments:api:COUNTERPARTY_INVALID_NAME'
        - 'urn:plmr:payments:api:COUNTERPARTY_ALREADY_EXIST'
        - 'urn:plmr:payments:api:COUNTERPARTY_ACCOUNT_ALREADY_EXIST'
        - 'urn:plmr:payments:api:COUNTERPARTY_PAYMENT_METHOD_ALREADY_EXIST'
        - 'urn:plmr:payments:api:COUNTERPARTY_DETAILS_PROPERTIES_NOT_FOUND'
        - 'urn:plmr:payments:api:COUNTERPARTY_NOT_FOUND'
        - 'urn:plmr:payments:api:PAYMENT_METHOD_NOT_FOUND'
        - 'urn:plmr:payments:api:MISSING_PAYMENT_METHOD_ID'
        - 'urn:plmr:payments:api:INVALID_INIT_PAYMENT_WITH_COUNTERPARTY'
        - 'urn:plmr:payments:api:INVALID_STANDING_ORDER_WITH_COUNTERPARTY'
        - 'urn:plmr:payments:api:INTERNAL_SERVER_ERROR'
        - 'urn:plmr:payments:api:BAD_REQUEST'
        - 'urn:plmr:payments:api:RESOURCE_UNKNOWN'
        - 'urn:plmr:payments:api:UNAUTHORIZED'
        - 'urn:plmr:payments:api:FORBIDDEN'
        - 'urn:plmr:payments:api:INVALID_PARAM'
        - 'urn:plmr:payments:api:WEB_APPLICATION'
        - 'urn:plmr:payments:api:PAYMENT_NOT_FOUND'
        - 'urn:plmr:payments:api:INVALID_IBAN_BANK_IDENTIFIER'
        - 'urn:plmr:payments:api:INVALID_DEBTOR_IBAN'
        - 'urn:plmr:payments:api:INVALID_CREDITOR_IBAN'
        - 'urn:plmr:payments:api:INVALID_AMOUNT_CURRENCY'
        - 'urn:plmr:payments:api:INVALID_DEBTOR_ACCOUNT_CURRENCY'
        - 'urn:plmr:payments:api:INVALID_CREDITOR_ACCOUNT_CURRENCY'
        - 'urn:plmr:payments:api:START_DATE_IN_THE_PAST'
        - 'urn:plmr:payments:api:STANDING_ORDER_ALREADY_STARTED'
        - 'urn:plmr:payments:api:INVALID_ONE_TIME_SCHEDULE'
        - 'urn:plmr:payments:api:INVALID_RECURRENT_SCHEDULE'
        - 'urn:plmr:payments:api:STANDING_ORDER_NOT_FOUND'
        - 'urn:plmr:payments:api:STANDING_ORDER_EXECUTING'
        - 'urn:plmr:payments:api:NO_SCHEDULED_EXECUTIONS'
        - 'urn:plmr:payments:api:IDENTICAL_QUOTE_CURRENCIES'
        - 'urn:plmr:payments:api:NULL_CURRENCY_EXCHANGE_DETAILS'
        - 'urn:plmr:payments:api:AMOUNT_IS_TOO_SMALL'
        - 'urn:plmr:payments:api:CURRENCY_EXCHANGE_TIME_WINDOW_CLOSED'
        - 'urn:plmr:payments:api:INVALID_INSTRUCTED_AMOUNT_CURRENCY'
        - 'urn:plmr:payments:api:DEVICE_INTEGRITY_TOKEN_NOT_FOUND'
      example: 'urn:plmr:payments:api:BAD_REQUEST'
    FieldErrorCode:
      type: string
      enum:
        - 'urn:plmr:payments:api:NOT_BLANK'
        - 'urn:plmr:payments:api:NOT_NULL'
        - 'urn:plmr:payments:api:MUST_BE_NULL'
        - 'urn:plmr:payments:api:INVALID_FIELD_VALUE'
        - 'urn:plmr:payments:api:INVALID_END_DATE'
        - 'urn:plmr:payments:api:POSITIVE'
    IdempotencyErrorCode:
      type: string
      enum:
        - 'urn:plmr:payments:api:IDEMPOTENCY_ERROR'
    FieldError:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/FieldErrorCode'
        message:
          type: string
        field:
          type: string
    ErrorResponse:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/PaymentsErrorCode'
        message:
          type: string
        requestId:
          type: string
        fieldErrors:
          type: array
          items:
            $ref: '#/components/schemas/FieldError'
    IdempotencyErrorResponse:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/IdempotencyErrorCode'
        message:
          type: string
        requestId:
          type: string
    UnauthorizedResponseMFARequired:
      type: object
      title: UnauthorizedResponseMFARequired
      description: 401 response for operation that requires mfa
      example:
        code: 'urn:plmr:payments:api:MFA_REQUIRED'
        message: MFA is required for this operation
        requestId: 235ea8df-c08d-40ab-bbcb-931dd74846fd
        mfaChallenge:
          level: 1
          challengeId: 235ea8df-c08d-40ab-bbcb-931dd74846fd
          signature: 3b7fc7cc370707c1df045c35342f3d64ea7076abd84f8a8c046a7cca2b85901689f3cf4bdc1f5fc232a60456cb9d2f48702bf8f8f1064f9bcc7d70edad9f860e
      properties:
        code:
          $ref: '#/components/schemas/MFAErrorCode'
        message:
          type: string
          example: MFA is required for this operation
        requestId:
          type: string
          minLength: 36
          maxLength: 36
          example: 235ea8df-c08d-40ab-bbcb-931dd74846fd
        mfaChallenge:
          $ref: '#/components/schemas/MFAChallenge'
    MFAChallenge:
      type: object
      title: MFAChallenge
      description: MFA response details
      properties:
        level:
          type: integer
          minimum: 1
          maximum: 3
          example: 1
        challengeId:
          type: string
          minLength: 36
          maxLength: 36
          example: 235ea8df-c08d-40ab-bbcb-931dd74846fd
        signature:
          type: string
          minLength: 128
          maxLength: 128
          example: 3b7fc7cc370707c1df045c35342f3d64ea7076abd84f8a8c046a7cca2b85901689f3cf4bdc1f5fc232a60456cb9d2f48702bf8f8f1064f9bcc7d70edad9f860e
    InitiatePaymentRequest:
      type: object
      description: |
        Generic Body for a payment initiation via JSON.
      allOf:
        - $ref: '#/components/schemas/PaymentsCommonRequest'
        - type: object
      properties:
        counterpartyId:
          type: string
          maxLength: 36
          description: |
            The Id of the counterparty.
          example: 9857dab5-973b-4bf4-8031-e9baa5e61607
        paymentMethodId:
          type: string
          maxLength: 36
          minLength: 36
          description: |
            The Id of the payment method.
          example: 494bbc67-387c-4e5a-b625-00287a8fc5cc
    CreditorAccountReference:
      description: |
        Reference to a creditor account.
      type: object
      properties:
        iban:
          $ref: '#/components/schemas/Iban'
        bban:
          $ref: '#/components/schemas/Bban'
        msisdn:
          $ref: '#/components/schemas/Msisdn'
        other:
          $ref: '#/components/schemas/Other'
        cashAccountType:
          $ref: '#/components/schemas/CashAccountType'
        currency:
          $ref: '#/components/schemas/CurrencyCode'
    DebtorAccountReference:
      description: |
        Reference to a debtor account.
      type: object
      required:
        - iban
        - currency
      properties:
        iban:
          $ref: '#/components/schemas/Iban'
        currency:
          $ref: '#/components/schemas/CurrencyCode'
    Iban:
      description: IBAN of an account.
      type: string
      pattern: '[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}'
      example: FR7612345987650123456789014
    Bban:
      description: Basic Bank Account Number (BBAN) Identifier.
      type: string
      pattern: '[a-zA-Z0-9]{1,30}'
      example: BARC12345612345678
    Msisdn:
      description: Mobile phone number.
      type: string
      maxLength: 35
      example: +49 170 1234567
    Other:
      description: In cases where the specifically defined criteria (IBAN, BBAN, MSISDN) are not provided to identify an instance of the respective account type (e.g. a savings account), the ASPSP shall include a proprietary ID of the respective account that uniquely identifies the account for this ASPSP.
      type: object
      required:
        - identification
      properties:
        identification:
          $ref: '#/components/schemas/Identification'
        schemeNameCode:
          $ref: '#/components/schemas/SchemeNameCode'
        schemeNameProprietary:
          $ref: '#/components/schemas/SchemeNameProprietary'
        issuer:
          $ref: '#/components/schemas/Issuer'
    Identification:
      description: Proprietary identification of the account.
      type: string
      maxLength: 35
    SchemeNameCode:
      description: An entry provided by an external ISO code list.
      type: string
      maxLength: 35
    SchemeNameProprietary:
      description: A scheme name defined in a proprietary way.
      type: string
      maxLength: 35
    Issuer:
      description: A scheme name defined in a proprietary way.
      type: string
      maxLength: 35
    CashAccountType:
      description: ExternalCashAccountType1Code from ISO 20022.
      type: string
    Bicfi:
      description: |
        BICFI
      type: string
      pattern: '[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}'
      example: AAAADEBBXXX
    CreditorName:
      description: Creditor name.
      type: string
      maxLength: 70
      example: Creditor Name
    DebtorName:
      description: Debtor name.
      type: string
      maxLength: 70
      example: Debtor Name
    InitiatePaymentResponse:
      description: Body of the response for a successful payment initiation request.
      type: object
      required:
        - paymentStatus
        - paymentId
      properties:
        paymentStatus:
          $ref: '#/components/schemas/PaymentStatus'
        paymentId:
          $ref: '#/components/schemas/PaymentId'
    Address:
      type: object
      required:
        - country
      properties:
        streetName:
          description: |
            Name of a street or thoroughfare
          type: string
          example: Main St
        buildingNumber:
          description: |
            Number that identifies the position of a building on a street
          type: string
          example: '123'
        buildingName:
          description: |
            Name of the building or house
          type: string
          example: Empire State Building
        floor:
          description: |
            Floor or storey within a building
          type: string
          example: '5'
        postBox:
          description: |
            Numbered box in a post office, assigned to a person or organisation, where letters are kept until called for
          type: string
          example: PO Box 789
        suite:
          description: |
            Building room number
          type: string
          example: Suite 101
        postCode:
          description: |
            Identifier consisting of a group of letters and/or numbers that is added to a postal address to assist the sorting of mail
          type: string
          example: '90210'
        townName:
          description: |
            Name of a built-up area, with defined boundaries, and a local government
          type: string
          example: New York
        townLocationName:
          description: |
            Specific location name within the town
          type: string
          example: Manhattan
        districtName:
          description: |
            Identifies a subdivision within a country sub-division
          type: string
          example: Financial District
        countrySubDivision:
          description: |
            Identifies a subdivision of a country such as state, region, county
          type: string
          example: New York State
        country:
          description: |
            Nation with its own government. ISO 3166, Alpha-2 code
          type: string
          example: US
    RemittanceInformationUnstructured:
      description: |
        Unstructured remittance information.
      type: string
      maxLength: 140
      example: Ref Number Merchant
    RemittanceInformationStructured:
      type: object
      required:
        - reference
      properties:
        reference:
          type: string
        referenceType:
          type: string
        referenceIssuer:
          type: string
    ServiceLevel:
      description: |
        Specifies the service level for the payment
      type: string
      enum:
        - SEPA
        - INTERNAL
        - SDVA
        - OTHER
      example: SEPA
    LocalInstrument:
      description: |
        Specifies the local instrument for the payment.
        allowed values: OTHER, SWIFT, INTERNAL, SCT, INST
      type: string
      example: INST
    CategoryPurpose:
      description: |
        Specifies the category purpose for the payment
      type: string
    RoutingPreference:
      description: |
        Specifies the routing preference for the payment
      type: string
      enum:
        - NONE
        - HIGH_PRIORITY
        - INSTANT
      example: INSTANT
    PaymentType:
      description: |
        Specifies the payment type.
        Allowed values:
        - SEPA Instant payment          
          ```
          "paymentType": {
              "serviceLevel": "SEPA",
              "localInstrument": "INST",
              "categoryPurpose": null,
              "routingPreference": "INSTANT"
             }
          }
          ```
        - SEPA Regular payment
          ```
          "paymentType": {
              "serviceLevel": "SEPA",
              "localInstrument": "SCT",
              "categoryPurpose": null,
              "routingPreference": "NONE"
            }
          }
          ```
        - SEPA Any payment
          ```
          "paymentType": {
              "serviceLevel": "SEPA",
              "localInstrument": null,
              "categoryPurpose": null,
              "routingPreference": "NONE"
             }
          }
          ```
        - Internal payment
          ```
          "paymentType": {
              "serviceLevel": "INTERNAL",
              "localInstrument": "INTERNAL",
              "categoryPurpose": null,
              "routingPreference": "NONE"
              }
           }
            ```
        - SWIFT payment
          ```
          "paymentType": {
              "serviceLevel": "SDVA",
              "localInstrument": "SWIFT",
              "categoryPurpose": null,
              "routingPreference": "HIGH_PRIORITY"
              }
          }
          ```
        - OTHER payment
          ```
          "paymentType": {
              "serviceLevel": "OTHER",
              "localInstrument": "OTHER",
              "categoryPurpose": null,
              "routingPreference": "NONE"
             }
          }
          ```
      type: object
      required:
        - serviceLevel
      properties:
        serviceLevel:
          $ref: '#/components/schemas/ServiceLevel'
        localInstrument:
          $ref: '#/components/schemas/LocalInstrument'
        categoryPurpose:
          $ref: '#/components/schemas/CategoryPurpose'
        routingPreference:
          $ref: '#/components/schemas/RoutingPreference'
    SupplementaryData:
      description: |
        Additional information that cannot be captured in the structured elements and/or any other specific block.
      type: object
      properties:
        amkCode:
          type: string
    CurrencyCode:
      description: |
        ISO 4217 Alpha 3 currency code.
      type: string
      pattern: '[A-Z]{3}'
      example: EUR
      x-field-extra-annotation: '@com.plumery.payments.api.external.models.ValidCurrency'
    Amount:
      type: object
      required:
        - currency
        - amount
      properties:
        currency:
          $ref: '#/components/schemas/CurrencyCode'
        amount:
          $ref: '#/components/schemas/AmountValue'
    AmountValue:
      description: |
        The amount given with fractional digits, where fractions must be compliant to the currency definition.
        Up to 14 significant figures. Negative amounts are signed by minus.
        The decimal separator is a dot.

        **Example:**
        Valid representations for EUR with up to two decimals are:

          * 1056
          * 5768.2
          * -1.50
          * 5877.78
      type: string
      pattern: '-?[0-9]{1,14}(\.[0-9]{1,3})?'
      example: '5877.78'
    PaymentStatus:
      description: |
        The payment status is filled with codes of the ISO 20022 data table:
        - 'ACCC': 'AcceptedSettlementCompleted' -
          Settlement on the creditor's account has been completed.
        - 'RCVD': 'Received' - 
          Payment initiation has been received by the receiving agent.
        - 'RJCT': 'Rejected' - 
          Payment initiation or individual transaction included in the payment initiation has been rejected.
      type: string
      enum:
        - ACCC
        - RCVD
        - RJCT
      example: RCVD
    PaymentId:
      description: Resource identification of the generated payment initiation resource.
      type: string
      example: c7068fec-0c6d-40bf-93fa-ad8ca8aeed4a
    PaymentExecutionStatusResponse:
      description: Body of the response for payment execution status.
      type: object
      properties:
        paymentStatus:
          $ref: '#/components/schemas/PaymentStatus'
        statusDateTime:
          $ref: '#/components/schemas/DateTime'
        rejectionReason:
          $ref: '#/components/schemas/RejectionReason'
        paymentStatusHistory:
          type: array
          items:
            type: object
            properties:
              paymentStatus:
                $ref: '#/components/schemas/PaymentStatus'
              statusDateTime:
                $ref: '#/components/schemas/DateTime'
    DateTime:
      format: date-time
      type: string
      example: '2017-07-21T17:32:28Z'
    RejectionReason:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          enum:
            - 'urn:plmr:payments:initiation:ACCOUNT_ACCESS_RESTRICTED'
            - 'urn:plmr:payments:initiation:ACCOUNT_CURRENCY_MISMATCH'
            - 'urn:plmr:payments:core:BLOCKED_BY_CORE'
            - 'urn:plmr:payments:core:INSUFFICIENT_FUNDS'
            - 'urn:plmr:payments:core:INVALID_ACCOUNT_STATE'
            - 'urn:plmr:payments:aml:BLOCKED_BY_AML'
            - 'urn:plmr:payments:aml:BLOCKED_BY_FRAUD'
            - 'urn:plmr:payments:pgw:BLOCKED_BY_PGW'
            - 'urn:plmr:payments:initiation:INTERNAL_TECHNICAL_ERROR'
          example: 'urn:plmr:payments:core:INSUFFICIENT_FUNDS'
        message:
          type: string
          example: 'Payment rejected due to insufficient funds'
    PaymentDetailsResponse:
      type: object
      properties:
        paymentId:
          $ref: '#/components/schemas/PaymentId'
        counterpartyId:
          type: string
          maxLength: 36
          description: |
            The Id of the counterparty
          example: 9857dab5-973b-4bf4-8031-e9baa5e61607
        paymentStatus:
          $ref: '#/components/schemas/PaymentStatus'
        statusDateTime:
          $ref: '#/components/schemas/DateTime'
        rejectionReason:
          $ref: '#/components/schemas/RejectionReason'
        paymentStatusHistory:
          type: array
          items:
            type: object
            properties:
              paymentStatus:
                $ref: '#/components/schemas/PaymentStatus'
              statusDateTime:
                $ref: '#/components/schemas/DateTime'
        endToEndIdentification:
          type: string
          maxLength: 35
        debtorAccount:
          $ref: '#/components/schemas/DebtorAccountReference'
        instructedAmount:
          $ref: '#/components/schemas/Amount'
        creditorAccount:
          $ref: '#/components/schemas/CreditorAccountReference'
        creditorAgent:
          $ref: '#/components/schemas/Bicfi'
        debtorName:
          $ref: '#/components/schemas/DebtorName'
        creditorName:
          $ref: '#/components/schemas/CreditorName'
        debtorAddress:
          $ref: '#/components/schemas/Address'
        creditorAddress:
          $ref: '#/components/schemas/Address'
        remittanceInformationUnstructured:
          $ref: '#/components/schemas/RemittanceInformationUnstructured'
        remittanceInformationStructured:
          $ref: '#/components/schemas/RemittanceInformationStructured'
        standingOrderId:
          $ref: '#/components/schemas/StandingOrderId'
        paymentType:
          $ref: '#/components/schemas/PaymentType'
        supplementaryData:
          $ref: '#/components/schemas/SupplementaryData'
    PaymentsCommonRequest:
      x-parent: abstract
      type: object
      description: |
        Generic body for updating a standing order.
      required:
        - debtorAccount
        - instructedAmount
      properties:
        endToEndIdentification:
          type: string
          maxLength: 35
        debtorAccount:
          $ref: '#/components/schemas/DebtorAccount'
        instructedAmount:
          $ref: '#/components/schemas/Amount'
        creditorAccount:
          $ref: '#/components/schemas/CreditorAccountReference'
        creditorAgent:
          $ref: '#/components/schemas/Bicfi'
        creditorName:
          $ref: '#/components/schemas/CreditorName'
        debtorAddress:
          $ref: '#/components/schemas/Address'
        creditorAddress:
          $ref: '#/components/schemas/Address'
        remittanceInformationUnstructured:
          $ref: '#/components/schemas/RemittanceInformationUnstructured'
        remittanceInformationStructured:
          $ref: '#/components/schemas/RemittanceInformationStructured'
        paymentType:
          $ref: '#/components/schemas/PaymentType'
        supplementaryData:
          $ref: '#/components/schemas/SupplementaryData'
    StandingOrderId:
      description: Resource identification of the generated standing order creation resource.
      type: string
      example: c7068fec-0c6d-40bf-93fa-ad8ca8aeed4a
    DebtorAccount:
      type: object
      description: Details of the account from which the amount will be debited.
      required:
        - accountId
        - currency
      properties:
        accountId:
          type: string
          description: The ID of the account that will be debited.
          example: 4ec4e5f6-1124-5678-abcd-1234567890ef
        currency:
          $ref: '#/components/schemas/CurrencyCode'