openapi: 3.1.0
info:
  title: Bango Payments API
  version: 6.0.{build_number}
  description: |
    # Change log
    **2025-04-10 | v.1.74.2
    - removed a separate log for successful idempotency requests; replaced requests and responses log objects with full bodies
    **2025-03-03 | v.1.74.0
    -  handle paymentProviderOperationId on CancelAuth
    **2025-02-21 | v.1.73.0
    - support paymentProviderOperationId on refund events
    **2024-10-09 | v.1.70.4
    - allow custom prefixed for partnerPaymentId
    **2024-09-26 | v.1.68.0
    - do not add a prefix to partnerBillingToken if it contains ':' character when calling Alias service
    - support PIT aliases - partnerBillingToken
    - update response to return partnerBillingToken
    **2024-09-18 | v.1.67.0
    - added paymentProviderToMerchant to the shared bucket for authorize approved
    **2024-08-21 | v.1.50.0
    - handle paymentProviderOperationId
    - replaced actions.Idempotency with a shared model
    **2024-04-05 | v.1.43.1
    - remove NamespaceId param from request payload for create payment action
    - remove Url from NotFound error
    - return 404 if param in URI is invalid uuid
    - update action handler to use specific structs for json payload/uri params
    - fixed timeout on CREATE+AUTH flow when CREATE is denied by the Policy Service
    **2024-03-13 | v.1.41.3
    - partnerPaymentId alias for Create+Auth flow is created after an Auth Success / Auth Denied response 
    **2024-02-21 | v.1.37.1
    - fixed allowed value and currency in CANCEL_AUTH request body
    **2024-02-14 | v.1.37.0
    - included locale 
    - udapte action handler to return 400
    **2023-11-28 | v.1.27.4
    - return 200 status code for create + AUTH
    **2023-09-27 | v.1.19.0
    - added CANCEL_AUTH action type.
    - added MaxWaitForResponse config
    - added timeout to message processor.
    - implemented CANCEL_AUTHORIZE happy path
    **2023-08-22 | v.1.16.0
    - Fixed feature file path. 
    - Fixed incorrect table lookup keys
    - Made Amount and Currency fields optional for AUTHORIZE and CAPTURE requests.
    **2023-03-06 | v.1.4.0
    - adding a Unmarshal Error Validation updating tests and changed amount to int
    - Adding validation min and max lengths
    - SaleItem Validation
    **2022-10-26 | v.1.0.0
    - Initial Release
  contact:
    name: Bango Support
    url: https://developer.bango.com
    email: support@bango.com
  servers:
  - url: https://api.bango.com
    description: Production server
paths:
  /ns/{nsid}/payments:
    post:
      operationId: payment-create
      summary: Create a payment
      description: |
        Use this endpoint to create a payment.

        Include the `action` property to send an action immediately after the payment resource is created.

        On a successful creation, the Bango Platform can automatically create an alias that merchants can use to retrieve payments and perform updates. For example, if the merchant sets `partnerPaymentId` to `aoieroiu234oiu` in the create request, it can later use `partnerPaymentId:aoieroiu234oiu` in GET and POST requests in place of the `rid` path parameter. The prefix `partnerPaymentId` is mandatory in this case.

        400 response error codes:
          - `invalid-json` if the request body isn't valid JSON format
          - `missing-parameter` for any mandatory parameter missing from the request body
          - `invalid-parameter` for any parameter that's syntactically or semantically incorrect. For example:
            - If this specification defines a parameter as a string, and an array of strings is supplied
            - If this specification defines a parameter as a datetime, and an invalid datetime is supplied
            - If parameters should be in a particular order (eg chronological datetimes) and they aren't
      parameters:
        - $ref: '#/components/parameters/NamespaceId'
        - $ref: '#/components/parameters/Idempotency-Key'
      requestBody:
        description: |
          Data needed to create a payment.
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                paymentInstrumentToken:
                  $ref: '#/components/schemas/payment-instrument-token'
                saleItem:
                  $ref: '#/components/schemas/sale-item'
                partnerPaymentId:
                  $ref: '#/components/schemas/partnerPaymentId'
                partnerRequestId:
                  $ref: '#/components/schemas/merchant-request-id'
                action:
                  $ref: '#/components/schemas/action'
                shared:
                  $ref: '#/components/schemas/payment-shared'
              required:
                - paymentInstrumentToken
                - saleItem
              additionalProperties: false
      responses:
        '201':
          description: |
            Resource created.
          headers:
            Idempotency-Status:
              schema:
                $ref: '#/components/schemas/idempotency-status'
          content:
            application/vnd.bango.payment.v1+json:
              schema:
                $ref: '#/components/schemas/payment'
              examples:
                Skipping paymentState `creating`:
                  summary: |
                    Example payment after creation, assuming the partner does not see the paymentState `creating`
                  value:
                    rid: 9a84f3fb-d70f-45e6-aff8-311216dc93e1
                    paymentInstrumentToken: 54f23474-18a5-4093-ad22-8f8335878635
                    saleItem:
                      description: Ognab Music
                      category: DIGITAL_GOODS
                      price:
                        amount: 995
                        currency: USD
                    partnerPaymentId: Opaque_String_Of_Any_Format_1234
                    lastUpdate: '2023-02-21T17:45:39Z'
                    balance:
                      authorized:
                        amount: 0
                        currency: USD
                      captured:
                        amount: 0
                        currency: USD
                      refunded:
                        amount: 0
                        currency: USD
                      canceled:
                        amount: 0
                        currency: USD
                    paymentState: new
                    processingState: idle
                    result: null
                    currentAction: null
                With paymentState `creating`:
                  summary: |
                    Example payment after creation, if the partner sees the paymentState `creating`
                  value:
                    rid: 9a84f3fb-d70f-45e6-aff8-311216dc93e1
                    paymentInstrumentToken: 54f23474-18a5-4093-ad22-8f8335878635
                    saleItem:
                      description: Ognab Music
                      category: DIGITAL_GOODS
                      price:
                        amount: 995
                        currency: USD
                    partnerPaymentId: Opaque_String_Of_Any_Format_1234
                    lastUpdate: '2023-02-21T17:45:39Z'
                    balance:
                      authorized:
                        amount: 0
                        currency: USD
                      captured:
                        amount: 0
                        currency: USD
                      refunded:
                        amount: 0
                        currency: USD
                      canceled:
                        amount: 0
                        currency: USD
                    paymentState: creating
                    processingState: processing
                    result: null
                    currentAction: null
        '400':
          $ref: '#/components/responses/IdempotentBadRequestErrorResponse'
        '401':
          $ref: '#/components/responses/IdempotentInvalidCredentialsErrorResponse'
        '403':
          $ref: '#/components/responses/IdempotentPermissionDeniedErrorResponse'
        '404':
          $ref: '#/components/responses/IdempotentNotFoundErrorResponse'
        '409':
          description: |
            The payment resource is not in the correct state for the requested operation.

            This error occurs when the current state of a resource means that some operations are not permitted on the resource, and a request is made to perform one of those operations.
          headers:
            Idempotency-Status:
              schema:
                $ref: '#/components/schemas/idempotency-status'
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: array
                    items:
                      $ref: '#/components/schemas/request-in-progress'
                required:
                  - errors
        '429':
          $ref: '#/components/responses/IdempotentTooManyRequestsErrorResponse'
        '500':
          description: Unexpected internal server error or payment provider error
          headers:
            Idempotency-Status:
              schema:
                $ref: '#/components/schemas/idempotency-status'
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: array
                    items:
                      oneOf:
                        - $ref: '#/components/schemas/internal-server-error'
                        - $ref: '#/components/schemas/payment-provider-failure'
                required:
                  - errors
        '503':
          $ref: '#/components/responses/IdempotentServiceUnavailableErrorResponse'
  /ns/{nsid}/payments/{ridOrAlias}:
    get:
      operationId: payment-get
      summary: Retrieve a payment
      description: |
        Use this endpoint to retrieve a payment. The `paymentState`, `processingState`, and `currentAction` properties of the resource describe the current state of the payment and any operations currently taking place on the payment. These values change over time. Partners can use this endpoint to poll a payment regularly to track asynchronous processes managed by the Bango Platform, such as requests to a downstream payment provider.

        To poll, partners can:
        - Use the `rid` of the payment: this is a unique identifier (UUID v4) created by the Bango Platform
        - Use an alias for the `rid`, for example `partnerPaymentId:ahskdfiu234`. (The Bango Platform creates this alias automatically if the partner specifies a `partnerPaymentId` when creating the payment)
      parameters:
        - $ref: '#/components/parameters/NamespaceId'
        - $ref: '#/components/parameters/ResourceIdOrAlias'
      responses:
        '200':
          description: Resource found
          content:
            application/vnd.bango.payment.v1+json:
              schema:
                $ref: '#/components/schemas/payment'
        '401':
          $ref: '#/components/responses/InvalidCredentialsErrorResponse'
        '403':
          $ref: '#/components/responses/PermissionDeniedErrorResponse'
        '404':
          $ref: '#/components/responses/NotFoundErrorResponse'
        '429':
          $ref: '#/components/responses/TooManyRequestsErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerErrorResponse'
        '503':
          $ref: '#/components/responses/ServiceUnavailableErrorResponse'
  /ns/{nsid}/payments/{ridOrAlias}/actions:
    post:
      operationId: payment-send-action
      summary: Update a payment
      description: |
        Use this endpoint to update a payment and/or to trigger tasks related to a payment.

        API consumers request updates by sending _actions_ to this endpoint. An action specifies what you want to do to the resource. The Bango Platform decides whether the action is permitted, and if so it performs the action. An action might result in a change to the resource's properties, and might cause a side effect. Actions are logged as `*_REQUESTED` events. The Bango Platform also logs events recording whether the action succeeded or failed.

        An action might be syntactically valid but not permitted at the time the partner sends it, depending on various factors. These factors include:
        - Whether the Bango Platform is already processing an action
        - Whether the partner is permitted to perform the action when the payment resource is in its current state (for example, a specific policy applies to the partner that doesn't apply to all partners)
        - Whether the action makes sense in the current state (for example, a request to capture more than authorized will be rejected)

        These types of actions DO NOT cause a 400 error. Instead, the resource returned in the response contains a `result` property. This indicates how the Bango Platform treated the request.

        To send an action, partners can:
        - Use the `rid` of the payment: this is a unique identifier (UUID v4) created by the Bango Platform
        - Use an alias for the `rid`, for example `partnerPaymentId:ahskdfiu234`. (The Bango Platform creates this alias automatically if the partner specifies a `partnerPaymentId` when creating the payment)

        400 response error codes:
          - `invalid-json` if the request body isn't valid JSON format
          - `missing-parameter` if `type` is not present in the request body
          - `invalid-parameter` if `type` is not a valid action type
          - `missing-parameter` if `payload` is required and not present
          - `invalid-parameter` if `payload` is not the expected shape for the type of action (which may mean that `payload` is missing required parameters or some parameters are invalid: check the documentation to find out the expected payload shape for each action type)
      parameters:
        - $ref: '#/components/parameters/NamespaceId'
        - $ref: '#/components/parameters/ResourceIdOrAlias'
        - $ref: '#/components/parameters/Idempotency-Key'
      requestBody:
        description: |
          A request to update a payment and trigger session-related tasks. A request specifies an action `type` and any action-specific data (the `payload`).

          The following action types are available. See each action type schema for detailed information.

          - [`AUTHORIZE`](/schemas/AUTHORIZE): A request to reserve funds from a payment provider's end user (two-step payment, step 1)
          - [`CAPTURE`](/schemas/CAPTURE): A request to capture funds from a payment provider's end user (two-step payment, step 2)
          - [`REFUND`](/schemas/REFUND): A request to refund an amount to a payment provider's end user
          - [`CANCEL_AUTH`](/schemas/CANCEL_AUTH): A request to release funds reserved from a payment provider's end user
          - [`CHARGE`](/schemas/CHARGE): A request to capture funds from a payment provider's end user (one-step payment)

          Whether an action has any effect depends on the current `state` value of the session, and other factors. The response to this request is the session resource: the `state` property might have changed as a result of the request.
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/AUTHORIZE'
                - $ref: '#/components/schemas/CANCEL_AUTH'
                - $ref: '#/components/schemas/CAPTURE'
                - $ref: '#/components/schemas/CHARGE'
                - $ref: '#/components/schemas/REFUND'
      responses:
        '200':
          description: |
            The updated resource.
          headers:
            Idempotency-Status:
              schema:
                $ref: '#/components/schemas/idempotency-status'
          content:
            application/vnd.bango.payment.v1+json:
              schema:
                $ref: '#/components/schemas/payment'
        '400':
          $ref: '#/components/responses/IdempotentBadRequestErrorResponse'
        '401':
          $ref: '#/components/responses/IdempotentInvalidCredentialsErrorResponse'
        '403':
          $ref: '#/components/responses/IdempotentPermissionDeniedErrorResponse'
        '404':
          $ref: '#/components/responses/IdempotentNotFoundErrorResponse'
        '409':
          description: |
            The payment resource is not in the correct state for the requested operation.

            This error occurs when the current state of a resource means that some operations are not permitted on the resource, and a request is made to perform one of those operations.
          headers:
            Idempotency-Status:
              schema:
                $ref: '#/components/schemas/idempotency-status'
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: array
                    items:
                      oneOf:
                        - $ref: '#/components/schemas/request-in-progress'
                        - $ref: '#/components/schemas/incompatible-state'
                required:
                  - errors
        '429':
          $ref: '#/components/responses/IdempotentTooManyRequestsErrorResponse'
        '500':
          description: Unexpected internal server error or payment provider error
          headers:
            Idempotency-Status:
              schema:
                $ref: '#/components/schemas/idempotency-status'
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: array
                    items:
                      oneOf:
                        - $ref: '#/components/schemas/internal-server-error'
                        - $ref: '#/components/schemas/payment-provider-failure'
                required:
                  - errors
        '503':
          $ref: '#/components/responses/IdempotentServiceUnavailableErrorResponse'
components:
  schemas:
    namespace-id:
      title: Namespace ID
      description: |
        Globally unique namespace ID. These IDs are opaque, not guessable, and not sequential.

        Bango provides each Bango partner with a unique set of resource URIs. All resource URI paths start with `/ns/{nsid}`, where `{nsid}` is the namespace ID. No other Bango partner shares this namespace. Partner credentials permit access only to URIs with this namespace.
      type: string
      format: uuid
      examples:
        - 673c74de-ce5b-4f79-9851-2544d1d836cb
    idempotency-key:
      title: Idempotency-Key
      description: |
        A unique identifier to use for idempotency purposes.
      type: string
      format: uuid
      examples:
        - 76aa2331-a96a-4a3b-8c23-019aabb44ed1
    payment-instrument-token:
      title: Payment instrument token
      description: |
        A unique identifier for a payment method used to charge a payment provider's end user.

        To obtain a payment instrument token, use the Bango Identity Verification API.

        To charge an end user using a payment instrument token, use the Bango Payments API.
      type: string
      format: uuid
      examples:
        - 65ea5204-f1c1-463d-9eab-da7977960e2d
    currency-code-iso-4217:
      title: ISO 4217 3-char currency code
      description: |
        A three-character [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) currency code.

        The allowed values are:
        - All current ISO 4217 codes except those for precious metals and bonds
        - ISO 4217 historical codes withdrawn since 2010

        ISO 4217 publication: January 1, 2023
      type: string
      enum:
        - AED
        - AFN
        - ALL
        - AMD
        - ANG
        - AOA
        - ARS
        - AUD
        - AWG
        - AZN
        - BAM
        - BBD
        - BDT
        - BGN
        - BHD
        - BIF
        - BMD
        - BND
        - BOB
        - BOV
        - BRL
        - BSD
        - BTN
        - BWP
        - BYN
        - BYR
        - BZD
        - CAD
        - CDF
        - CHE
        - CHF
        - CHW
        - CLF
        - CLP
        - CNY
        - COP
        - COU
        - CRC
        - CUC
        - CUP
        - CVE
        - CZK
        - DJF
        - DKK
        - DOP
        - DZD
        - EEK
        - EGP
        - ERN
        - ETB
        - EUR
        - FJD
        - FKP
        - GBP
        - GEL
        - GHS
        - GIP
        - GMD
        - GNF
        - GTQ
        - GYD
        - HKD
        - HNL
        - HRK
        - HTG
        - HUF
        - IDR
        - ILS
        - INR
        - IQD
        - IRR
        - ISK
        - JMD
        - JOD
        - JPY
        - KES
        - KGS
        - KHR
        - KMF
        - KPW
        - KRW
        - KWD
        - KYD
        - KZT
        - LAK
        - LBP
        - LKR
        - LRD
        - LSL
        - LTL
        - LVL
        - LYD
        - MAD
        - MDL
        - MGA
        - MKD
        - MMK
        - MNT
        - MOP
        - MRO
        - MRU
        - MUR
        - MVR
        - MWK
        - MXN
        - MXV
        - MYR
        - MZN
        - NAD
        - NGN
        - NIO
        - NOK
        - NPR
        - NZD
        - OMR
        - PAB
        - PEN
        - PGK
        - PHP
        - PKR
        - PLN
        - PYG
        - QAR
        - RON
        - RSD
        - RUB
        - RWF
        - SAR
        - SBD
        - SCR
        - SDG
        - SEK
        - SGD
        - SHP
        - SLE
        - SLL
        - SOS
        - SRD
        - SSP
        - STD
        - STN
        - SVC
        - SYP
        - SZL
        - THB
        - TJS
        - TMT
        - TND
        - TOP
        - TRY
        - TTD
        - TWD
        - TZS
        - UAH
        - UGX
        - USD
        - USN
        - USS
        - UYI
        - UYU
        - UYW
        - UZS
        - VED
        - VEF
        - VES
        - VND
        - VUV
        - WST
        - XAF
        - XCD
        - XDR
        - XFU
        - XOF
        - XPF
        - XSU
        - YER
        - ZAR
        - ZMK
        - ZMW
        - ZWL
      examples:
        - USD
    monetary-value:
      title: Monetary value
      description: |
        A monetary value, including currency.

        The `amount` value is represented as an integer in the minor units of the `currency` value, if any. For example:

        - `amount`: `999` and `currency`: `USD` represents USD 9.99, because USD uses two decimal digits for minor units
        - `amount`: `123` and `currency`: `JPY` represents JPY 123, because JPY has no minor units

        The Bango Platform uses [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) as the source of truth for currency codes, including minor units.
      type: object
      properties:
        amount:
          description: |
            The numeric value, in minor units of the currency. Always an integer.
          type: integer
          examples:
            - 999
        currency:
          $ref: '#/components/schemas/currency-code-iso-4217'
    monetary-value-required:
      allOf:
        - $ref: '#/components/schemas/monetary-value'
        - required:
            - amount
            - currency
    sale-item:
      title: Sale item
      description: |
        An item (product or service) purchased in whole or part by a payment.
      type: object
      properties:
        description:
          description: |
            A description for the item.
          type: string
          minLength: 1
          maxLength: 255
          examples:
            - Ognab Music - 6-month subscription
        category:
          description: |
            An optional category for the item.
          type: string
          minLength: 1
          maxLength: 255
        uniqueId:
          description: |
            The partner's own unique identifier for the item. Ideally globally unique (a UUID).
          type: string
          minLength: 1
          maxLength: 255
          examples:
            - 18c32e64-04dc-4886-83f1-1a7d7ac1a95b
        price:
          allOf:
            - $ref: '#/components/schemas/monetary-value-required'
            - title: |
                The full payment expected for this item.
      required:
        - description
        - price
    partnerPaymentId:
      description: |
        The merchant partner's own unique identifier for the payment. Not necessarily a UUID. The Bango Platform considers this an opaque value but checks for uniqueness when the payment is being created (400 error if not).
      type: string
      minLength: 1
      maxLength: 255
      examples:
        - asdfg-asdfhj-fgrewa-bcczx
    merchant-request-id:
      title: Merchant request ID
      description: |
        Merchant-owned request identifier. Bango considers this identifier opaque, and passes it to the payment provider unchanged (in OPPA request actions, as `merchantPaymentId`).

        In a returned payment resource, the `partnerRequestId` reflects the value specified in the request from the merchant. If a request does not specify a `partnerRequestId` then the response does not include a `partnerRequestId`.
      type: string
      minLength: 1
      maxLength: 255
      examples:
        - zfknveriuouzxcqweff12tgdvxxzb0
    locale-bcp-47:
      title: BCP 47 language tag
      description: |
        A [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) language tag.
      type: string
      minLength: 1
      maxLength: 50
      examples:
        - en-US
        - ar-SA
    AUTHORIZE:
      title: AUTHORIZE API action
      description: |
        A request to reserve funds from a payment provider's end user (two-step payment, step 1). The request may be denied (for example, if the amount to reserve is too great).

        To authorize an amount less than or equal to the payment resource's `saleItem.price` property, set `payload.amount` and `payload.currency` to the amount to authorize.

        To authorize the `saleItem.price`, omit both `payload.amount` and `payload.currency` or set them explicitly to the values in `saleItem.price`.

        The optional `locale` is passed to the payment provider.
      type: object
      properties:
        type:
          const: AUTHORIZE
        payload:
          oneOf:
            - title: Authorize full amount, optional locale
              description: |
                Authorize the full amount specified in the payment resource's `saleItem.price` property, and optionally specify the merchant end user's locale and a request ID
              type: object
              properties:
                partnerRequestId:
                  $ref: '#/components/schemas/merchant-request-id'
                locale:
                  $ref: '#/components/schemas/locale-bcp-47'
                  description: |
                    A [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) language tag representing the locale of the merchant end user, if known.
              additionalProperties: false
            - title: Authorize specific amount, optional locale
              allOf:
                - description: |
                    Authorize the amount specified in the payload, and optionally specify the merchant end user's locale and a request ID
                - $ref: '#/components/schemas/monetary-value-required'
                - type: object
                  properties:
                    partnerRequestId:
                      $ref: '#/components/schemas/merchant-request-id'
                    locale:
                      $ref: '#/components/schemas/locale-bcp-47'
                      description: |
                        A [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) language tag representing the locale of the merchant end user, if known.
      required:
        - type
        - payload
    CHARGE:
      title: CHARGE API action [plan-later]
      description: |
        A request to capture funds from a payment provider's end user (one-step payment). The request may be denied (for example, if the amount to charge is too great).

        To charge an amount less than or equal to the payment resource's `saleItem.price` property, set `payload` to the amount to charge. To charge the `saleItem.price`, set `payload` to the empty object `{}` or the `saleItem.price` explicitly.
      type: object
      properties:
        type:
          const: CHARGE
        payload:
          oneOf:
            - title: Charge full amount
              description: |
                Charge the full amount specified in the payment resource's `saleItem.price` property, with optional request ID
              type: object
              properties:
                partnerRequestId:
                  $ref: '#/components/schemas/merchant-request-id'
              additionalProperties: false
            - title: Charge specific amount
              allOf:
                - description: |
                    Charge the amount specified in the payload, and optionally specify a request ID
                - $ref: '#/components/schemas/monetary-value-required'
                - type: object
                  properties:
                    partnerRequestId:
                      $ref: '#/components/schemas/merchant-request-id'
      required:
        - type
        - payload
    action:
      description: |
        Optional action to send immediately after a successful resource creation.
      oneOf:
        - $ref: '#/components/schemas/AUTHORIZE'
        - $ref: '#/components/schemas/CHARGE'
    payment-shared:
      title: Data shared between merchant and payment provider
      description: |
        Data shared between the merchant partner and the payment provider as part of a payment resource. Supplied to the payment provider with every payment action, such as `AUTHORIZE` or `CHARGE`.
      type: object
      properties:
        merchantToPaymentProvider:
          description: |
            Data the merchant partner owns (read/write access) and the payment provider may consume (read access only).

            Constraints:
            - Between 0 and 255 properties
            - Each property value is either:
              - string (length 0 to 255 inclusive)
              - number (-1048575 to +1048575 inclusive)
              - boolean
              - array (between 0 and 255 items) containing a mixture of:
                - string (length 0 to 255 inclusive)
                - number (-1048575 to +1048575 inclusive)

            Note that nested objects ARE NOT permitted.
          type: object
          maxProperties: 255
          additionalProperties:
            oneOf:
              - type: string
                minLength: 0
                maxLength: 255
              - type: number
                minimum: -1048575
                maximum: 1048575
              - type: boolean
              - type: array
                maxItems: 255
                items:
                  oneOf:
                    - type: string
                      minLength: 0
                      maxLength: 255
                    - type: number
                      minimum: -1048575
                      maximum: 1048575
                    - type: boolean
    idempotency-status:
      title: Idempotency-Status
      description: |
        Returned to the API consumer even if a request has not included the `Idempotency-Key` header.

        Possible values:
        - `ok`: Request processed as normal, because no stored response was found for the request's `Idempotency-Key` header
        - `in-progress`: A stored response was found for the `Idempotency-Key` header, and it is currently being processed. Repeat this request (same `Idempotency-Key`) until the value is `duplicate`
        - `duplicate`: The response contains the stored response for the same `Idempotency-Key`
        - `unavailable`: Idempotency checks could not be completed, and the request was processed as if `Idempotency-Key` was omitted. Do not reuse this `Idempotency-Key` value
        - `not-requested`: No `Idempotency-Key` header was provided. Request was processed as normal
      type: string
      enum:
        - ok
        - in-progress
        - duplicate
        - unavailable
        - not-requested
      examples:
        - duplicate
    resource-id:
      title: Resource ID
      description: |
        Globally unique resource ID. These IDs are opaque, not guessable, and not sequential.

        Each individual resource in a partner's namespace has a unique identifier: this is the identifier immediately after the resource type in the URI path.

        For example, in the URI `/ns/673c74de-ce5b-4f79-9851-2544d1d836cb/elephants/581b2e40-741c-4683-ae66-46c9fe6f4d5e`:
        - The namespace id is `673c74de-ce5b-4f79-9851-2544d1d836cbde`
        - `elephants` indicates the resource type is `elephant`
        - The resource id is `581b2e40-741c-4683-ae66-46c9fe6f4d5e`

        Every resource has a read-only property `rid` that contains the resource ID, for convenience.
      type: string
      format: uuid
      examples:
        - 581b2e40-741c-4683-ae66-46c9fe6f4d5e
    payment-provider-payment-id:
      title: Payment provider payment ID
      description: |
        The payment provider's own unique identifier for the payment. Not necessarily a UUID. Bango assumes it is unique.

        The payment provider may supply this value in response to a request from the Bango Platform. Subsequent requests to the payment provider include the value where relevant, and responses to the Bango Platform may replace the value.

        The current value is given to the merchant in the payment resource.
      type: string
      minLength: 1
      maxLength: 255
      examples:
        - 345hkjhsgdkfgh43k5hjkhk1
    lastUpdate:
      type: string
      format: date-time
      description: |
        RFC 3339 datetime of the last update to this resource
      examples:
        - '2022-12-21T08:59:32Z'
    balance:
      description: |
        The total amounts currently authorized, captured, refunded, and canceled for the payment, taking all successful actions into account. Values exclude any requests awaiting a response from the downstream payment provider.

        For one-step payments (the `CHARGE` action), the `authorized` and `captured` values are always identical.
      type: object
      properties:
        authorized:
          $ref: '#/components/schemas/monetary-value-required'
        captured:
          $ref: '#/components/schemas/monetary-value-required'
        refunded:
          $ref: '#/components/schemas/monetary-value-required'
        canceled:
          $ref: '#/components/schemas/monetary-value-required'
      required:
        - authorized
        - captured
        - refunded
        - canceled
    paymentState:
      description: |
        The high-level view of the progress of the payment through the standard lifecycle. Allowed values are:

        - `creating` - the partner requested a new payment resource but the request has not yet been approved
        - `new` - the payments system approved a request to create a payment resource and there are no approved authorization/capture/charge/refund events. Balances: `authorized == 0, captured == 0, refunded == 0`
        - `authorized` - the payments system approved a request to create a payment resource and there's at least one approved authorization event, but no captures, charges, or refunds. Balances: `authorized > 0, captured == 0, refunded == 0`
        - `captured` - the payments system approved a request to create a payment resource and there's at least one approved authorization/capture/charge event, and maybe some refunds, and the payment isn't fully refunded. Balances: `authorized > 0, captured > 0, refunded >= 0, captured > refunded`
        - `refunded` - the payments system approved a request to create a payment resource and the payment is fully refunded. Balances: `authorized > 0, captured > 0, refunded > 0, captured == refunded`
        - `closed` - the payment resource is effectively frozen. No actions will be processed.
      type: string
      enum:
        - creating
        - new
        - authorized
        - captured
        - refunded
        - closed
    processingState:
      description: |
        Indicates whether the Bango Platform is:

        - `preparing`: preparing to process a partner action, and NOT ready to receive a new action
        - `processing`: processing a partner action (including waiting for a response from the downstream payment provider), and NOT ready to receive a new action
        - `idle`: NOT currently processing a partner action, and ready to receive a new action

        While `processingState` is `preparing` or `processing`, the Bango Platform will reject any new action for this payment resource.
      type: string
      enum:
        - idle
        - preparing
        - processing
    missing-parameter:
      title: missing-parameter
      description: A required parameter is missing from the request
      type: object
      properties:
        code:
          const: missing-parameter
        meta:
          description: Additional information to help identify the specific error case
          type: object
          properties:
            param:
              description: The name of the missing parameter
              type: string
          required:
            - param
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - A required parameter was missing from the request
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/missing-parameter
      required:
        - code
        - meta
        - message
    invalid-parameter:
      title: invalid-parameter
      description: A request parameter is invalid
      type: object
      properties:
        code:
          const: invalid-parameter
        meta:
          description: Additional information to help identify the specific error case
          type: object
          properties:
            param:
              description: The name of the invalid parameter
              type: string
            reason:
              description: Optional human-readable information to explain why the parameter is invalid. Code must not rely on the content of this string.
              type: string
              examples:
                - 'Expected format: YYYY-MM-DD'
          required:
            - param
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - A parameter in the request was not valid
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/invalid-parameter
      required:
        - code
        - meta
        - message
    balances-not-zero:
      title: balances-not-zero
      description: |
        A request to authorize a payment failed because an authorization has already been approved. Only one successful authorization is permitted per payment.
      type: object
      properties:
        code:
          type: string
          const: balances-not-zero
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected all balances zero'
      required:
        - code
        - meta
        - message
    cancelation-window-exceeded:
      title: cancelation-window-exceeded
      description: |
        A request to cancel authorization for a payment failed because it occurred too long after successful authorization.
      type: object
      properties:
        code:
          type: string
          const: cancelation-window-exceeded
        meta:
          description: Details of the cancelation window
          type: object
          properties:
            duration:
              description: Duration of the cancelation period, in [ISO 8601 Duration](https://en.wikipedia.org/wiki/ISO_8601#Durations) format
              type: string
              examples:
                - P21D12H
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected cancelation within cancelation window'
      required:
        - code
        - meta
        - message
    capture-window-exceeded:
      title: capture-window-exceeded
      description: |
        A request to capture a payment failed because it occurred too long after successful authorization.
      type: object
      properties:
        code:
          type: string
          const: capture-window-exceeded
        meta:
          description: Details of the capture window
          type: object
          properties:
            duration:
              description: Duration of the capture period, in [ISO 8601 Duration](https://en.wikipedia.org/wiki/ISO_8601#Durations) format
              type: string
              examples:
                - P21D12H
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected capture within capture window'
      required:
        - code
        - meta
        - message
    invalid-amount:
      title: invalid-amount
      description: |
        A request to perform an action failed because the amount specified was below the minimum amount permitted.
      type: object
      properties:
        code:
          type: string
          const: invalid-amount
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected amount >= 0'
      required:
        - code
        - meta
        - message
    limit-exceeded:
      title: limit-exceeded
      description: |
        A request to authorize a payment failed because the amount was greater than the limit defined for this currency for the payment route.
      type: object
      properties:
        code:
          type: string
          const: limit-exceeded
        meta:
          description: Details of the limit exceeded by the request
          type: object
          properties:
            limit:
              description: The maximum amount that may be authorized, in the minor units of the currency
              type: integer
              minimum: 0
            currency:
              description: The three-letter ISO 4217 currency code for which the limit applies
              type: string
              examples:
                - USD
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected amount <= limit'
      required:
        - code
        - meta
        - message
    not-greater-than-saleitem-price:
      title: not-greater-than-saleitem-price
      description: |
        A request to perform an action failed because the amount was greater than the sale item price.
      type: object
      properties:
        code:
          type: string
          const: not-greater-than-saleitem-price
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: action amount should not be greater than the sale item price'
      required:
        - code
        - meta
        - message
    payment-already-captured:
      title: payment-already-captured
      description: |
        One of the following applies:
        - A request to capture a payment failed because the payment is already fully captured
        - A request to capture a payment failed because the payment is partially captured and no more captures are permitted
        - A request to cancel authorization for a payment failed because the payment is fully captured (nothing can be canceled)
      type: object
      properties:
        code:
          type: string
          const: payment-already-captured
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected captured balance = 0'
      required:
        - code
        - meta
        - message
    payment-already-refunded:
      title: payment-already-refunded
      description: |
        A request to refund a payment failed for one of these reasons:
        - Payment is already fully refunded
        - Only a single refund is permitted, and this has already occurred
      type: object
      properties:
        code:
          type: string
          const: payment-already-refunded
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected refunded balance = 0'
      required:
        - code
        - meta
        - message
    payment-auth-already-canceled:
      title: payment-auth-already-canceled
      description: |
        One of the following applies:
        - A request to capture a payment failed because authorization has been canceled
        - A request to cancel authorization for a payment failed because it's already been canceled (only one cancel is permitted)
      type: object
      properties:
        code:
          type: string
          const: payment-auth-already-canceled
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected captured balance = 0'
      required:
        - code
        - meta
        - message
    payment-authorized-balance-exceeded:
      title: payment-authorized-balance-exceeded
      description: |
        A request to capture a payment failed because the amount was greater than permitted. The amount must be less than the total currently authorized but not yet captured. For example, if payment balances are

        - authorized: 1000
        - captured: 400

        then the maximum permitted capture amount is (1000 - 400) = 600.
      type: object
      properties:
        code:
          type: string
          const: payment-authorized-balance-exceeded
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected amount <= authorized balance not yet captured'
      required:
        - code
        - meta
        - message
    payment-capture-full-only:
      title: payment-capture-full-only
      description: |
        A request to capture a payment failed because only full captures are permitted, and the request specified a partial capture.
      type: object
      properties:
        code:
          type: string
          const: payment-capture-full-only
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected full capture'
      required:
        - code
        - meta
        - message
    payment-captured-balance-exceeded:
      title: payment-captured-balance-exceeded
      description: |
        A request to refund a payment failed because the amount was greater than permitted. The amount must be less than the total currently captured but not yet refunded. For example, if payment balances are

        - captured: 1000
        - refunded: 400

        then the maximum permitted refund amount is (1000 - 400) = 600.
      type: object
      properties:
        code:
          type: string
          const: payment-captured-balance-exceeded
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected amount <= captured balance not yet refunded'
      required:
        - code
        - meta
        - message
    payment-is-closed:
      title: payment-is-closed
      description: |
        A request to perform an action failed because the payment state was closed.
      type: object
      properties:
        code:
          type: string
          const: payment-is-closed
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected state not to be closed'
      required:
        - code
        - meta
        - message
    payment-not-authorized:
      title: payment-not-authorized
      description: |
        One of the following applies:
        - A request to capture a payment failed because a successful authorization has not yet occurred
        - A request to cancel authorization for a payment failed because a successful authorization has not yet occurred
      type: object
      properties:
        code:
          type: string
          const: payment-not-authorized
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected authorized balance > 0'
      required:
        - code
        - meta
        - message
    payment-not-captured:
      title: payment-not-captured
      description: |
        A request to refund a payment failed because a successful capture has not yet occurred.
      type: object
      properties:
        code:
          type: string
          const: payment-not-captured
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected captured balance > 0'
      required:
        - code
        - meta
        - message
    payment-refund-full-only:
      title: payment-refund-full-only
      description: |
        A request to refund a payment failed because only full refunds are permitted, and the request specified a partial refund.
      type: object
      properties:
        code:
          type: string
          const: payment-refund-full-only
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected full refund'
      required:
        - code
        - meta
        - message
    payment-refunds-not-allowed:
      title: payment-refunds-not-allowed
      description: |
        A request to refund a payment failed because refunds are not permitted.
      type: object
      properties:
        code:
          type: string
          const: payment-refunds-not-allowed
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: refunds not permitted'
      required:
        - code
        - meta
        - message
    refund-window-exceeded:
      title: refund-window-exceeded
      description: |
        A request to refund a payment failed because it occurred too long after the most recent successful capture.
      type: object
      properties:
        code:
          type: string
          const: refund-window-exceeded
        meta:
          description: Details of the refund window
          type: object
          properties:
            duration:
              description: Duration of the refund period, in [ISO 8601 Duration](https://en.wikipedia.org/wiki/ISO_8601#Durations) format
              type: string
              examples:
                - P21D12H
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: expected refund within refund window'
      required:
        - code
        - meta
        - message
    incompatible-state:
      title: incompatible-state
      description: |
        Incompatible state.

        This is a generic error used when a more specific error is not available. The `meta.reason` may give a human-readable description of the error.
      type: object
      properties:
        code:
          const: incompatible-state
        meta:
          description: Additional information to help identify the specific error case
          type: object
          properties:
            reason:
              description: Human-readable information to explain in detail why the operation cannot be permitted in the current state. Code must not rely on the content of this string.
              type: string
              examples:
                - Operation is permitted in state "active" only
        message:
          description: Human-readable message describing the error
          const: The resource is not in the correct state for the requested operation
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/incompatible-state
      required:
        - code
        - meta
        - message
    internal-server-error:
      title: internal-server-error
      description: Internal server error
      type: object
      properties:
        code:
          const: internal-server-error
        meta:
          description: Additional information to help identify the specific error case
          type: object
          properties:
            canRetry:
              description: Whether the request can be retried
              type: boolean
              default: true
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - The server encountered an unexpected condition which prevented it from fulfilling the request
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/internal-server-error
      required:
        - code
        - meta
        - message
    payment-provider-failure:
      title: payment-provider-failure
      description: |
        An error occurred with the downstream payment provider, and the Bango Platform was unable to fulfil the request.

        This might be a transient error or a persistent error. The `meta.paymentProviderCode` value indicates the type of response received by the Bango Platform from the payment provider.

        The `meta.canRetry` boolean indicates whether the payment provider believes the merchant can retry the request.
      type: object
      properties:
        code:
          const: payment-provider-failure
        meta:
          description: Additional information to help identify the specific error case
          type: object
          properties:
            paymentProviderCode:
              description: |
                Code indicating the type of response the Bango Platform received from the payment provider. Not all codes apply to all requests from the Bango Platform.

                Possible values:
                - `service-unavailable`: the payment provider returned an HTTP 503 response to a request from the Bango Platform
                - `internal-server-error`: the payment provider returned another HTTP 5xx response to a request from the Bango Platform
                - `mt-message-send-request-failure`: the payment provider was unable to send an MT flow message to an end user's device
                - `otp-request-failure`: the payment provider was unable to send an OTP to an end user's device, or verify an OTP provided by an end user
              type: string
              enum:
                - internal-server-error
                - service-unavailable
                - mt-message-send-request-failure
                - otp-request-failure
            canRetry:
              description: Whether the payment provider believes the request can be retried
              type: boolean
          required:
            - paymentProviderCode
            - canRetry
        message:
          description: Human-readable message describing the error
          const: An error occurred at the payment provider
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/payment-provider-failure
      required:
        - code
        - meta
        - message
    operation-not-supported:
      title: operation-not-supported
      description: |
        The payment provider denied a requested action because it does not support the operation.
      type: object
      properties:
        code:
          const: operation-not-supported
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/operation-not-supported
      required:
        - code
        - meta
        - message
    denied:
      title: denied
      description: |
        The payment provider denied a requested action without supplying a specific error code. The `message` may contain more information.
      type: object
      properties:
        code:
          const: denied
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/denied
      required:
        - code
        - meta
        - message
    expired:
      title: expired
      description: |
        The payment provider denied a requested action because the authority to perform the action has expired.

        For example, if too much time has passed since a payment was authorized, the payment provider might return an `expired` error.
      type: object
      properties:
        code:
          const: expired
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/expired
      required:
        - code
        - meta
        - message
    user-invalid:
      title: user-invalid
      description: |
        The payment provider denied a requested action because the user does not exist or is invalid in some way.
      type: object
      properties:
        code:
          const: user-invalid
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/user-invalid
      required:
        - code
        - meta
        - message
    user-barred:
      title: user-barred
      description: |
        The requested action was denied because the user has been barred.
      type: object
      properties:
        code:
          const: user-barred
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/user-barred
      required:
        - code
        - meta
        - message
    user-suspended:
      title: user-suspended
      description: |
        The payment provider denied a requested action because the user has been suspended.
      type: object
      properties:
        code:
          const: user-suspended
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/user-suspended
      required:
        - code
        - meta
        - message
    user-not-enabled:
      title: user-not-enabled
      description: |
        The requested action was denied because the user is not currently enabled.
      type: object
      properties:
        code:
          const: user-not-enabled
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/user-not-enabled
      required:
        - code
        - meta
        - message
    user-insufficient-credit:
      title: user-insufficient-credit
      description: |
        The payment provider denied a requested action because the user does not have sufficient credit.
      type: object
      properties:
        code:
          const: user-insufficient-credit
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/user-insufficient-credit
      required:
        - code
        - meta
        - message
    user-spend-limit-exceeded:
      title: user-spend-limit-exceeded
      description: |
        The requested action was denied because the user's spend limit has been exceeded.
      type: object
      properties:
        code:
          const: user-spend-limit-exceeded
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/user-spend-limit-exceeded
      required:
        - code
        - meta
        - message
    payment-unknown:
      title: payment-unknown
      description: |
        The payment provider denied a requested action because it couldn't find the payment in its internal systems.
      type: object
      properties:
        code:
          const: payment-unknown
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/payment-unknown
      required:
        - code
        - meta
        - message
    already-in-progress:
      title: already-in-progress
      description: |
        The payment provider denied a requested action because it's already in progress.
      type: object
      properties:
        code:
          const: already-in-progress
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          type: string
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/already-in-progress
      required:
        - code
        - meta
        - message
    currency-not-supported:
      title: currency-not-supported
      description: |
        A request to create a payment failed because a saleItem currency is not in the list of permitted currencies.
      type: object
      properties:
        code:
          type: string
          const: currency-not-supported
        meta:
          description: Details of permitted currencies
          type: object
          properties:
            currencies:
              description: List of permitted currencies
              type: array
              items:
                oneOf:
                  - type: string
              examples:
                - |
                  - EUR
                  - GBP
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: provided currency is not supported'
      required:
        - code
        - meta
        - message
    currency-not-allowed:
      title: currency-not-allowed
      description: |
        A request to create a payment failed because a saleItem currency is in the list of prohibited currencies.
      type: object
      properties:
        code:
          type: string
          const: currency-not-allowed
        meta:
          description: Details of prohibited currencies
          type: object
          properties:
            currencies:
              description: List of prohibited currencies
              type: array
              items:
                oneOf:
                  - type: string
              examples:
                - |
                  - EUR
                  - GBP
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: provided currency is not allowed'
      required:
        - code
        - meta
        - message
    pit-state-not-allowed:
      title: pit-state-not-allowed
      description: |
        A request to perform an action with payment failed because the payment instrument token (PIT) is not in the list of allowed states.
      type: object
      properties:
        code:
          type: string
          const: pit-state-not-allowed
        meta:
          description: Details of allowed states
          type: object
          properties:
            allowedStates:
              description: List of allowed states
              type: array
              items:
                oneOf:
                  - type: string
              examples:
                - |
                  - ACTIVE
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: provided Payment Instrument Token state is not allowed'
      required:
        - code
        - meta
        - message
    pit-state-denied:
      title: pit-state-denied
      description: |
        A request to perform an action with payment failed because the payment instrument token (PIT) is in the list of denied states.
      type: object
      properties:
        code:
          type: string
          const: pit-state-denied
        meta:
          description: Details of denied states
          type: object
          properties:
            deniedStates:
              description: List of denied states
              type: array
              items:
                oneOf:
                  - type: string
              examples:
                - |
                  - CANCELED
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: provided Payment Instrument Token state denied'
      required:
        - code
        - meta
        - message
    eligibility-status-not-allowed:
      title: eligibility-status-not-allowed
      description: |
        A request to perform an action with payment failed because the payment eligibility status is not in the list of allowed statuses.
      type: object
      properties:
        code:
          type: string
          const: eligibility-status-not-allowed
        meta:
          description: Details of allowed statuses
          type: object
          properties:
            allowedStatuses:
              description: List of allowed statuses
              type: array
              items:
                oneOf:
                  - type: string
              examples:
                - |
                  - ACTIVE
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: provided payment eligibility status is not allowed'
      required:
        - code
        - meta
        - message
    eligibility-status-denied:
      title: eligibility-status-denied
      description: |
        A request to perform an action with payment failed because the payment eligibility status is in the list of denied statuses.
      type: object
      properties:
        code:
          type: string
          const: eligibility-status-denied
        meta:
          description: Details of denied statuses
          type: object
          properties:
            deniedStatuses:
              description: List of denied statuses
              type: array
              items:
                oneOf:
                  - type: string
              examples:
                - |
                  - CANCELED
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - 'Policy failed: provided payment eligibility status denied'
      required:
        - code
        - meta
        - message
    result:
      description: |
        The result of the most recent action, if any.
      oneOf:
        - title: No action result to report
          description: |
            null - there is no action result to report.
          type: 'null'
        - title: Result of the most recent action
          description: |
            The result of the most recent action. There are three outcomes for an action:

            1. The action was performed and completed with a positive outcome (for example, the payment provider approved a request to authorize a transfer of funds)
            2. The action was performed and completed with a negative outcome (for example, the payment provider denied a request to authorize a transfer of funds)
            3. The action was not performed because a required constraint was not met or a service error occurred (for example, the action asked to capture more funds than authorized)

            The result `code` indicates which outcome applied and is always a string in `lower-kebab-case`.

            The result `reasons` indicates any additional explanations available for the outcome (outcomes 2 and 3 above). For outcome 1 above, `reasons` is an empty array.
          type: object
          properties:
            code:
              description: |
                The outcome of the most recent action. This value gives you a high-level idea of _what happened_.
              type: string
              enum:
                - create-approved
                - create-denied
                - create-failed
                - authorize-denied
                - authorize-failed
                - authorize-approved
                - capture-denied
                - capture-failed
                - capture-approved
                - charge-denied
                - charge-failed
                - charge-approved
                - refund-denied
                - refund-failed
                - refund-approved
                - cancel-auth-denied
                - cancel-auth-failed
                - cancel-auth-approved
              examples:
                - charge-denied
            reasons:
              description: |
                Any explanations available to describe the outcome of the most recent action
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/missing-parameter'
                  - $ref: '#/components/schemas/invalid-parameter'
                  - $ref: '#/components/schemas/balances-not-zero'
                  - $ref: '#/components/schemas/cancelation-window-exceeded'
                  - $ref: '#/components/schemas/capture-window-exceeded'
                  - $ref: '#/components/schemas/invalid-amount'
                  - $ref: '#/components/schemas/limit-exceeded'
                  - $ref: '#/components/schemas/not-greater-than-saleitem-price'
                  - $ref: '#/components/schemas/payment-already-captured'
                  - $ref: '#/components/schemas/payment-already-refunded'
                  - $ref: '#/components/schemas/payment-auth-already-canceled'
                  - $ref: '#/components/schemas/payment-authorized-balance-exceeded'
                  - $ref: '#/components/schemas/payment-capture-full-only'
                  - $ref: '#/components/schemas/payment-captured-balance-exceeded'
                  - $ref: '#/components/schemas/payment-is-closed'
                  - $ref: '#/components/schemas/payment-not-authorized'
                  - $ref: '#/components/schemas/payment-not-captured'
                  - $ref: '#/components/schemas/payment-refund-full-only'
                  - $ref: '#/components/schemas/payment-refunds-not-allowed'
                  - $ref: '#/components/schemas/refund-window-exceeded'
                  - $ref: '#/components/schemas/incompatible-state'
                  - $ref: '#/components/schemas/internal-server-error'
                  - $ref: '#/components/schemas/payment-provider-failure'
                  - $ref: '#/components/schemas/operation-not-supported'
                  - $ref: '#/components/schemas/denied'
                  - $ref: '#/components/schemas/expired'
                  - $ref: '#/components/schemas/user-invalid'
                  - $ref: '#/components/schemas/user-barred'
                  - $ref: '#/components/schemas/user-suspended'
                  - $ref: '#/components/schemas/user-not-enabled'
                  - $ref: '#/components/schemas/user-insufficient-credit'
                  - $ref: '#/components/schemas/user-spend-limit-exceeded'
                  - $ref: '#/components/schemas/payment-unknown'
                  - $ref: '#/components/schemas/already-in-progress'
                  - $ref: '#/components/schemas/currency-not-supported'
                  - $ref: '#/components/schemas/currency-not-allowed'
                  - $ref: '#/components/schemas/pit-state-not-allowed'
                  - $ref: '#/components/schemas/pit-state-denied'
                  - $ref: '#/components/schemas/eligibility-status-not-allowed'
                  - $ref: '#/components/schemas/eligibility-status-denied'
          required:
            - code
            - reasons
    CREATE:
      title: CREATE pseudo-API action
      description: |
        An internal action that occurs automatically when the merchant partner creates the payment. A merchant can't send this action explicitly.
      type: object
      properties:
        type:
          const: CREATE
        payload:
          description: Empty object
          type: object
          additionalProperties: false
      required:
        - type
        - payload
    CANCEL_AUTH:
      title: CANCEL_AUTH API action
      description: |
        A request to release funds reserved from a payment provider's end user. The request may be denied (for example, if the route does not permit this operation). If no capture has occurred, this releases all funds reserved. If a partial capture has occurred, this releases the funds reserved but not captured. If a full capture has occurred, this has no effect.
      type: object
      properties:
        type:
          const: CANCEL_AUTH
        payload:
          description: |
            Release all reserved funds not yet captured, with optional request ID
          type: object
          properties:
            partnerRequestId:
              $ref: '#/components/schemas/merchant-request-id'
          additionalProperties: false
      required:
        - type
        - payload
    CAPTURE:
      title: CAPTURE API action
      description: |
        A request to capture funds from a payment provider's end user (two-step payment, step 2). The request may be denied (for example, if the amount to capture is too great).

        Some routes may permit partial captures (capturing less than authorized). To request a partial capture, set `payload` to the amount to capture. To capture the total amount authorized but not captured, set `payload` to the empty object `{}` or that amount explicitly. For example, if USD 15 has been authorized and USD 5 has already been captured, then setting `payload` to the empty object would capture the remaining USD 10.
      type: object
      properties:
        type:
          const: CAPTURE
        payload:
          oneOf:
            - title: Capture maximum amount
              description: |
                Capture the total amount authorized and not yet captured, with optional request ID
              type: object
              properties:
                partnerRequestId:
                  $ref: '#/components/schemas/merchant-request-id'
              additionalProperties: false
            - title: Capture specific amount
              allOf:
                - description: |
                    Capture the amount specified in the payload, and optionally specify a request ID
                - $ref: '#/components/schemas/monetary-value-required'
                - type: object
                  properties:
                    partnerRequestId:
                      $ref: '#/components/schemas/merchant-request-id'
      required:
        - type
        - payload
    REFUND:
      title: REFUND API action
      description: |
        A request to refund an amount to a payment provider's end user. The request may be denied (for example, if the refund requested exceeds the amount captured).

        Some routes may permit partial refunds (refunding less than captured). To request a partial refund, set `payload` to the amount to refund. To refund the total amount captured but not yet refunded, set `payload` to the empty object `{}` or that amount explicitly. For example, if USD 15 has been captured and USD 5 has already been refunded, then setting `payload` to the empty object would refund the remaining USD 10.
      type: object
      properties:
        type:
          const: REFUND
        payload:
          oneOf:
            - title: Refund maximum amount
              description: |
                Refund the total amount captured and not yet refunded, with optional request ID
              type: object
              properties:
                partnerRequestId:
                  $ref: '#/components/schemas/merchant-request-id'
              additionalProperties: false
            - title: Refund specific amount
              allOf:
                - description: |
                    Refund the amount specified in the payload, and optionally specify a request ID
                - $ref: '#/components/schemas/monetary-value-required'
                - type: object
                  properties:
                    partnerRequestId:
                      $ref: '#/components/schemas/merchant-request-id'
      required:
        - type
        - payload
    currentAction:
      oneOf:
        - type: 'null'
          description: |
            No action is currently being processed by the Bango Platform or downstream payment provider.
        - $ref: '#/components/schemas/CREATE'
        - $ref: '#/components/schemas/AUTHORIZE'
        - $ref: '#/components/schemas/CANCEL_AUTH'
        - $ref: '#/components/schemas/CAPTURE'
        - $ref: '#/components/schemas/CHARGE'
        - $ref: '#/components/schemas/REFUND'
    payment:
      title: Payment
      description: |
        A payment resource.
      type: object
      properties:
        rid:
          $ref: '#/components/schemas/resource-id'
        paymentInstrumentToken:
          $ref: '#/components/schemas/payment-instrument-token'
        saleItem:
          $ref: '#/components/schemas/sale-item'
        partnerPaymentId:
          $ref: '#/components/schemas/partnerPaymentId'
        partnerRequestId:
          $ref: '#/components/schemas/merchant-request-id'
        paymentProviderPaymentId:
          $ref: '#/components/schemas/payment-provider-payment-id'
        shared:
          $ref: '#/components/schemas/payment-shared'
        lastUpdate:
          $ref: '#/components/schemas/lastUpdate'
        balance:
          $ref: '#/components/schemas/balance'
        paymentState:
          $ref: '#/components/schemas/paymentState'
        processingState:
          $ref: '#/components/schemas/processingState'
        result:
          $ref: '#/components/schemas/result'
        currentAction:
          $ref: '#/components/schemas/currentAction'
      additionalProperties: false
      required:
        - rid
        - paymentInstrumentToken
        - saleItem
        - lastUpdate
        - balance
        - paymentState
        - processingState
        - result
        - currentAction
    CommonErrorResponse:
      type: object
      required:
        - errors
    invalid-json:
      title: invalid-json
      description: The request body is not valid JSON
      type: object
      properties:
        code:
          const: invalid-json
        meta:
          description: Additional information to help identify the specific error case (empty in this case)
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - The request body is not valid JSON
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/invalid-json
      required:
        - code
        - meta
        - message
    BadRequest:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/invalid-json'
                  - $ref: '#/components/schemas/missing-parameter'
                  - $ref: '#/components/schemas/invalid-parameter'
    invalid-credentials:
      title: invalid-credentials
      description: Authentication error - invalid credentials
      type: object
      properties:
        code:
          const: invalid-credentials
        meta:
          description: Additional information to help identify the specific error case (empty in this case)
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - The supplied credentials are not valid
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/invalid-credentials
      required:
        - code
        - meta
        - message
    InvalidCredentials:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/invalid-credentials'
    permission-denied:
      title: permission-denied
      description: Authorization error - permission denied
      type: object
      properties:
        code:
          const: permission-denied
        meta:
          description: Additional information to help identify the specific error case (empty in this case)
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - The client is not permitted to perform this operation
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/permission-denied
      required:
        - code
        - meta
        - message
    PermissionDenied:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/permission-denied'
    not-found:
      title: not-found
      description: Not found or access denied
      type: object
      properties:
        code:
          const: not-found
        meta:
          description: Additional information to help identify the specific error case (empty in this case)
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - The requested resource was not found
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/not-found
      required:
        - code
        - meta
        - message
    NotFound:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/not-found'
    request-in-progress:
      title: request-in-progress
      description: |
        The Bango Platform received a request with an Idempotency-Key header, and there's already a request in progress with the same header value. No response is available yet: the API consumer should wait and then try the request again.
      type: object
      properties:
        code:
          const: request-in-progress
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          const: 'Request currently in progress: try again after a short delay'
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/request-in-progress
      required:
        - code
        - meta
        - message
    too-many-requests:
      title: too-many-requests
      description: Too many requests
      type: object
      properties:
        code:
          const: too-many-requests
        meta:
          description: Additional information to help identify the specific error case (empty in this case)
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - Request limit reached. Please try again later
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/too-many-requests
      required:
        - code
        - meta
        - message
    TooManyRequests:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/too-many-requests'
    service-unavailable:
      title: service-unavailable
      description: Service is unavailable
      type: object
      properties:
        code:
          const: service-unavailable
        meta:
          description: Additional information to help identify the specific error case (empty in this case)
          type: object
        message:
          description: Human-readable message describing the error
          type: string
          examples:
            - The service is undergoing maintenance and is not available. Please try again later
        url:
          description: URL to more information about the error type
          type: string
          format: url
          examples:
            - https://developer.bango.com/error-codes/service-unavailable
      required:
        - code
        - meta
        - message
    ServiceUnavailable:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/service-unavailable'
    alias-string:
      title: Alias string
      description: |
        A string that acts as an alternative identifier for another string.

        An alias always has two parts, in this order, separated by a colon:

        - A type
        - A unique ID corresponding to that type

        For example, `my-special-id:adrfhaerhu2`.

        A type may contain only alphanumeric characters and `-` characters, and must not be empty. IDs may be any non-empty string. The maximum length of an alias string, including type and ID, is 1000 bytes (encoded as UTF-8).

        For each partner namespace, the alias must be unique. For example, one namespace can contain aliases `abc:123` and `xyz:123`, but can't contain two aliases both called `abc:123` even if they correspond to different Bango-owned IDs. It's OK for two different namespaces each to contain an alias `abc:123`.
      type: string
      pattern: ^[-a-zA-Z0-9]+:.+$
      maxLength: 1000
      examples:
        - my-special-id:adrfhaerhu2
    InternalServerError:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/internal-server-error'
  parameters:
    NamespaceId:
      in: path
      name: nsid
      required: true
      schema:
        $ref: '#/components/schemas/namespace-id'
    Idempotency-Key:
      in: header
      name: Idempotency-Key
      schema:
        $ref: '#/components/schemas/idempotency-key'
    ResourceIdOrAlias:
      in: path
      name: ridOrAlias
      required: true
      schema:
        oneOf:
          - $ref: '#/components/schemas/resource-id'
          - $ref: '#/components/schemas/alias-string'
  responses:
    IdempotentBadRequestErrorResponse:
      description: Bad request
      headers:
        Idempotency-Status:
          schema:
            $ref: '#/components/schemas/idempotency-status'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BadRequest'
    IdempotentInvalidCredentialsErrorResponse:
      description: |
        Authentication error - invalid credentials
      headers:
        Idempotency-Status:
          schema:
            $ref: '#/components/schemas/idempotency-status'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/InvalidCredentials'
    IdempotentPermissionDeniedErrorResponse:
      description: |
        User is not authorized for this operation.

        This error occurs when you try to perform an operation on a resource, and you have permission to access the resource - but you don't have permission to perform the operation. For example, you may be authorized to `GET` the resource but not update it.

        (If you try to perform any operation on a resource you're not authorized to access, the API returns a 404 error.)
      headers:
        Idempotency-Status:
          schema:
            $ref: '#/components/schemas/idempotency-status'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PermissionDenied'
    IdempotentNotFoundErrorResponse:
      headers:
        Idempotency-Status:
          schema:
            $ref: '#/components/schemas/idempotency-status'
      description: |
        The requested resource was not found or access was denied.

        The API returns an identical error in both scenarios for data privacy reasons: API consumers can't find out anything about resources they aren't authorized to access.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/NotFound'
    IdempotentTooManyRequestsErrorResponse:
      description: |
        Request limit reached. The request was not processed.

        This error occurs when you send too many requests in a short period of time. You should pause before sending further requests.
      headers:
        Idempotency-Status:
          schema:
            $ref: '#/components/schemas/idempotency-status'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TooManyRequests'
    IdempotentServiceUnavailableErrorResponse:
      description: Service unavailable
      headers:
        Idempotency-Status:
          schema:
            $ref: '#/components/schemas/idempotency-status'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ServiceUnavailable'
    InvalidCredentialsErrorResponse:
      description: |
        Authentication error - invalid credentials
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/InvalidCredentials'
    PermissionDeniedErrorResponse:
      description: |
        User is not authorized for this operation.

        This error occurs when you try to perform an operation on a resource, and you have permission to access the resource - but you don't have permission to perform the operation. For example, you may be authorized to `GET` the resource but not update it.

        (If you try to perform any operation on a resource you're not authorized to access, the API returns a 404 error.)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PermissionDenied'
    NotFoundErrorResponse:
      description: |
        The requested resource was not found or access was denied.

        The API returns an identical error in both scenarios for data privacy reasons: API consumers can't find out anything about resources they aren't authorized to access.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/NotFound'
    TooManyRequestsErrorResponse:
      description: |
        Request limit reached. The request was not processed.

        This error occurs when you send too many requests in a short period of time. You should pause before sending further requests.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TooManyRequests'
    InternalServerErrorResponse:
      description: Unexpected internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/InternalServerError'
    ServiceUnavailableErrorResponse:
      description: Service unavailable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ServiceUnavailable'
