> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bango.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Update an identity verification session

> Use this endpoint to update an identity verification session and/or to trigger tasks related to an identity verification session.

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 (you can fetch events for a resource using a separate endpoint). The Bango Platform also logs events recording whether the action succeeded or failed.

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)




## OpenAPI

````yaml /openapi/current/dcb-payments/merchant-to-bango/identity-verification/openapi.yaml post /ns/{nsid}/identity/verifications/{rid}/actions
openapi: 3.1.0
info:
  title: Bango Identity Verification API
  version: 1.0.{build_number}
  contact:
    name: Bango Support
    url: https://developer.bango.com
    email: support@bango.com
servers:
  - url: https://some-prod-tbd.bango.com
    description: Production server
security:
  - BasicAuth: []
tags:
  - name: env-production
    description: Currently deployed to prod env
  - name: plan-later
    description: Not yet planned
paths:
  /ns/{nsid}/identity/verifications/{rid}/actions:
    post:
      tags:
        - env-production
      summary: Update an identity verification session
      description: >
        Use this endpoint to update an identity verification session and/or to
        trigger tasks related to an identity verification session.


        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 (you can fetch events for a resource using a separate endpoint).
        The Bango Platform also logs events recording whether the action
        succeeded or failed.


        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)
      operationId: identity-verification-send-action
      parameters:
        - $ref: '#/components/parameters/NamespaceId'
        - $ref: '#/components/parameters/ResourceId'
      requestBody:
        description: >
          A request to update an identity verification session and trigger
          session-related tasks. A request specifies an action `type` and any
          action-specific data (the `payload`).


          Available action types:

          - `START_TRUSTED_FLOW`: A request to obtain a payment instrument token
          using the Trusted flow.

          - `START_NEGOTIATED_FLOW`: A request to obtain a payment instrument
          token using the Negotiated flow.

          - `START_MO_FLOW`: A request to obtain a payment instrument token
          using the MO flow.

          - `START_MT_FLOW`: A request to obtain a payment instrument token
          using the MT flow.

          - `VERIFY_OTP`: A request to check an end user's candidate OTP against
          the expected OTP.

          - `RESEND_OTP`: A request to resend the current OTP.

          - `RESET_OTP`: A request to resend/reset the OTP.

          - `CONFIRM_SESSION_IDENTITY`: Confirm that an end user was properly
          identified.

          - `REJECT_SESSION_IDENTITY`: Reject a tentative end user
          identification.

          - `UPDATE_SESSION_DATA`: A request to update private or shared data
          related to the identity verification session.


          Whether an action has any effect depends on the current `flow` and
          `state` properties of the session, and other factors. The response to
          this request is the session resource: the `flow` and `state`
          properties might have changed as a result of the request.
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/START_TRUSTED_FLOW'
                - $ref: '#/components/schemas/START_NEGOTIATED_FLOW'
                - $ref: '#/components/schemas/START_MO_FLOW'
                - $ref: '#/components/schemas/START_MT_FLOW'
                - $ref: '#/components/schemas/VERIFY_OTP'
                - $ref: '#/components/schemas/RESEND_OTP'
                - $ref: '#/components/schemas/RESET_OTP'
                - $ref: '#/components/schemas/CONFIRM_SESSION_IDENTITY'
                - $ref: '#/components/schemas/REJECT_SESSION_IDENTITY'
                - $ref: '#/components/schemas/UPDATE_SESSION_DATA'
                - $ref: '#/components/schemas/CANCEL_SESSION'
      responses:
        '200':
          description: |
            The updated resource.
          content:
            application/vnd.bango.identity.verification.v1+json:
              schema:
                $ref: '#/components/schemas/session'
        '400':
          $ref: '#/components/responses/BadRequestErrorResponse'
        '401':
          $ref: '#/components/responses/InvalidCredentialsErrorResponse'
        '403':
          $ref: '#/components/responses/PermissionDeniedErrorResponse'
        '404':
          $ref: '#/components/responses/NotFoundErrorResponse'
        '409':
          $ref: '#/components/responses/ConflictErrorResponse'
        '429':
          $ref: '#/components/responses/TooManyRequestsErrorResponse'
        '500':
          description: Unexpected internal server error
          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/ServiceUnavailableErrorResponse'
components:
  parameters:
    NamespaceId:
      in: path
      name: nsid
      required: true
      schema:
        $ref: '#/components/schemas/namespace-id'
    ResourceId:
      in: path
      name: rid
      required: true
      schema:
        $ref: '#/components/schemas/resource-id'
  schemas:
    START_TRUSTED_FLOW:
      title: START_TRUSTED_FLOW action
      description: |
        A request to use the Trusted flow to obtain a payment instrument token.
      type: object
      properties:
        type:
          const: START_TRUSTED_FLOW
        payload:
          description: |
            Data needed for the START_TRUSTED_FLOW action.
          type: object
          properties:
            account:
              $ref: '#/components/schemas/payment-instrument-account-properties'
            paymentProviderId:
              $ref: '#/components/schemas/payment-provider-id'
            private:
              allOf:
                - $ref: '#/components/schemas/simple-object-patch'
                - $ref: '#/components/schemas/private'
                - title: >-
                    Patch object for the private data related to the identity
                    verification session
          required:
            - phoneNumber
            - paymentProviderId
      required:
        - type
        - payload
    START_NEGOTIATED_FLOW:
      title: START_NEGOTIATED_FLOW action
      description: >
        A request to use the Negotiated flow to obtain a payment instrument
        token.
      type: object
      properties:
        type:
          const: START_NEGOTIATED_FLOW
        payload:
          description: |
            Data needed for the START_NEGOTIATED_FLOW action.
          type: object
          properties:
            paymentProviderId:
              $ref: '#/components/schemas/payment-provider-id'
            private:
              allOf:
                - $ref: '#/components/schemas/simple-object-patch'
                - $ref: '#/components/schemas/private'
                - title: >-
                    Patch object for the private data related to the identity
                    verification session
            shared:
              description: >
                Update to the data shared from the merchant partner to the
                payment provider. Data in `merchantToPaymentProvider` is merged
                into the existing data.
              type: object
              properties:
                nextAction:
                  $ref: '#/components/schemas/nextAction'
                merchantToPaymentProvider:
                  $ref: '#/components/schemas/merchantToPaymentProvider'
          required:
            - paymentProviderId
      required:
        - type
        - payload
    START_MO_FLOW:
      title: START_MO_FLOW action
      description: |
        A request to use the MO flow to obtain a payment instrument token.
      type: object
      properties:
        type:
          const: START_MO_FLOW
        payload:
          description: |
            Data needed for the START_MO_FLOW action.
          type: object
          properties:
            paymentProviderId:
              $ref: '#/components/schemas/payment-provider-id'
            private:
              allOf:
                - $ref: '#/components/schemas/simple-object-patch'
                - $ref: '#/components/schemas/private'
                - title: >-
                    Patch object for the private data related to the identity
                    verification session
          required:
            - paymentProviderId
      required:
        - type
        - payload
    START_MT_FLOW:
      title: START_MT_FLOW action
      description: |
        A request to use the MT flow to obtain a payment instrument token.
      type: object
      properties:
        type:
          const: START_MT_FLOW
        payload:
          description: |
            Data needed for the START_MT_FLOW action.
          type: object
          properties:
            paymentProviderId:
              $ref: '#/components/schemas/payment-provider-id'
            account:
              $ref: '#/components/schemas/payment-instrument-account-properties'
            message:
              description: >
                Details of the message template and values that replace
                placeholder fields in the template.


                All `message` properties are optional, with default values
                determined by the Bango Platform.
              type: object
              properties:
                template:
                  description: >
                    Text for the message sent to the end user's device,
                    including placeholders in braces. The Bango Platform
                    replaces these placeholders with appropriate values when it
                    sends the message to the end user's device.


                    Available placeholders:

                    - `{otp}` - mandatory - replaced with the appropriate OTP

                    - `{merchantName}` - optional - replaced with the value of
                    `message.merchantName` if present, or the merchant name in
                    the billing route configuration, or the merchant partner
                    name defined in the Bango Platform for the namespace ID in
                    the request URL


                    Default value: the template defined in the billing route
                    configuration, or a hardcoded template.
                  type: string
                  minLength: 5
                  maxLength: 500
                  pattern: '{otp}'
                  example: '{otp} is the PIN for {merchantName}'
                merchantName:
                  description: >
                    Merchant name to display in the message sent to the end
                    user's device.


                    Default value: the merchant name in the billing route
                    configuration, or the merchant partner name defined in the
                    Bango Platform for the namespace ID in the request URL
                  type: string
                  minLength: 1
                  maxLength: 100
                  example: Aussie Apps
                locale:
                  $ref: '#/components/schemas/locale-bcp-47'
                  description: >
                    A [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag)
                    language tag. The Bango Platform uses this value to select
                    the most appropriate message template if `message.template`
                    is omitted.


                    Default value: the locale defined in the billing route
                    configuration, or en-US
              additionalProperties: false
            private:
              allOf:
                - $ref: '#/components/schemas/simple-object-patch'
                - $ref: '#/components/schemas/private'
                - title: >-
                    Patch object for the private data related to the identity
                    verification session
          additionalProperties: false
          required:
            - paymentProviderId
            - account
      additionalProperties: false
      required:
        - type
        - payload
    VERIFY_OTP:
      title: VERIFY_OTP action
      description: >
        A request to check an end user's candidate OTP (typically typed into a
        merchant form) against the expected OTP associated with the identity
        verification session.


        The route configuration determines how many attempts a user has to enter
        an OTP correctly, and how many times the final failed attempt for that
        OTP will reset the OTP, generating a new set of attempts against a new
        OTP. The session resource includes the current counts of available
        retries (attempts at the same OTP) and resets (new OTPs).


        How it works:


        - If the candidate OTP matches the expected OTP, the Bango Platform
        automatically generates or locates the appropriate payment instrument
        token and includes it in the session resource returned to the merchant
        in the response (HTTP 200). In this case, the session state will be
        `succeeded`.


        - If the candidate OTP does not match the expected OTP, and the user has
        the right to retry or reset, the Bango Platform returns HTTP 200 with
        the session resource, and the session state will be `awaiting-user-otp`.
        The Bango Platform automatically resets the OTP after the last failed
        retry if any resets are available. The route configuration determines
        whether the Bango Platform automatically sends the new OTP to the end
        user (if not, the merchant can use RESEND_OTP to do so).


        - If the candidate OTP does not match the expected OTP, and the user has
        no retries and no resets available, the Bango Platform returns HTTP 200
        with the session resource, and the session state will be `failed`. The
        merchant must create a new identity verification session to identify the
        end user.


        HTTP 400 is returned ONLY if the request body does not match the schema
        defined here. HTTP 400 does NOT mean "the user typed the incorrect OTP".
      type: object
      properties:
        type:
          const: VERIFY_OTP
        payload:
          description: |
            Data needed for the VERIFY_OTP action.
          type: object
          properties:
            account:
              $ref: '#/components/schemas/payment-instrument-account-properties'
            candidate:
              description: |
                The end user's candidate OTP.
              type: string
              minLength: 1
              maxLength: 100
          additionalProperties: false
          required:
            - candidate
      additionalProperties: false
      required:
        - type
        - payload
    RESEND_OTP:
      title: RESEND_OTP action
      description: >
        A request to resend the current OTP to the end user, if it hasn't
        expired and if route configuration permits.


        If the OTP has expired, or if route configuration does not allow the
        current OTP to be sent again, this action behaves the same as
        `RESET_OTP`.
      type: object
      properties:
        type:
          const: RESEND_OTP
        payload:
          description: |
            Data needed for the RESEND_OTP action (none in this case)
          type: object
          properties:
            account:
              $ref: '#/components/schemas/payment-instrument-account-properties'
          additionalProperties: false
      additionalProperties: false
      required:
        - type
        - payload
    RESET_OTP:
      title: RESET_OTP action
      description: >
        A request to reset the OTP (generate a new OTP with a new expiry time)
        and send it the end user, if any resets are available. The route
        configuration determines how many times the merchant may reset an OTP
        within an identity verification session.


        If no resets are available, this action has no effect.
      type: object
      properties:
        type:
          const: RESET_OTP
        payload:
          description: |
            Data needed for the RESET_OTP action (none in this case)
          type: object
          properties:
            account:
              $ref: '#/components/schemas/payment-instrument-account-properties'
          additionalProperties: false
      additionalProperties: false
      required:
        - type
        - payload
    CONFIRM_SESSION_IDENTITY:
      title: CONFIRM_SESSION_IDENTITY action
      description: >
        A request to let the merchant confirm that the end user was properly
        identified. Used with the MO flow.
      type: object
      properties:
        type:
          const: CONFIRM_SESSION_IDENTITY
        payload:
          description: |
            Data needed for the CONFIRM_SESSION_IDENTITY action.
          type: object
          properties:
            partnerBillingToken:
              description: >
                An optional partner billing token to be used later by the
                partner in payment transactions.
              type: string
              minLength: 1
              maxLength: 100
          additionalProperties: false
      additionalProperties: false
      required:
        - type
        - payload
    REJECT_SESSION_IDENTITY:
      title: REJECT_SESSION_IDENTITY action
      description: >
        A request to let the merchant reject the tentative identification of an
        end user, with a reason
      type: object
      properties:
        type:
          const: REJECT_SESSION_IDENTITY
        payload:
          description: |
            Data needed for the REJECT_SESSION_IDENTITY action.
          type: object
          properties:
            code:
              description: >
                A machine-readable code that indicates why the merchant rejected
                the identity verification session.


                The merchant can use the generic code `rejected` if a more
                specific code is not available. In this case, it's a good idea
                to include more details in the `message` field.


                In most cases, the code is reported to the merchant partner in
                the session resource, in the `result.reasons` array. But note:

                - `adapter-failure` is transformed to `internal-server-error`
                (because adapters are Bango code, and problems in Bango code are
                all internal server errors from the merchant's perspective)

                - `merchant-internal-server-error` and
                `merchant-service-unavailable` are both transformed to
                `merchant-failure`, with the value of `meta.merchantCode` set
                appropriately


                **NOTE** List subject to change.
              type: string
              enum:
                - user-canceled
                - expired
                - merchant-internal-server-error
                - merchant-service-unavailable
                - adapter-failure
                - rejected
            message:
              description: >
                An optional human-readable message describing why the merchant
                rejected the identity verification session.
              type: string
              minLength: 1
              maxLength: 255
          required:
            - code
      required:
        - type
        - payload
    UPDATE_SESSION_DATA:
      title: UPDATE_SESSION_DATA action [ENG-1950]
      description: >
        See [ENG-1950](https://bangonet.atlassian.net/browse/ENG-1950)


        An identity verification session can store:

        - Private merchant partner data, which is not presented to the payment
        provider

        - Shared data, which is passed between the merchant partner and the
        payment provider


        This action lets the merchant partner request to update the private data
        and/or the shared data.
      type: object
      properties:
        type:
          const: UPDATE_SESSION_DATA
        payload:
          type: object
          properties:
            private:
              allOf:
                - $ref: '#/components/schemas/simple-object-patch'
                - $ref: '#/components/schemas/private'
                - title: Patch to private data
                - description: >-
                    Patch object to modify the merchant-private data in the
                    session
            shared:
              title: Update to data shared to payment provider
              description: >
                Update to the data shared from the merchant partner to the
                payment provider. Data in `merchantToPaymentProvider` is merged
                into the existing data.
              type: object
              properties:
                nextAction:
                  $ref: '#/components/schemas/nextAction'
                merchantToPaymentProvider:
                  $ref: '#/components/schemas/merchantToPaymentProvider'
      required:
        - type
        - payload
    CANCEL_SESSION:
      title: CANCEL_SESSION action [plan-later]
      description: >
        A request to cancel the session. Any flow currently in progress is
        ended, and the `state` moves to `closed`.
      type: object
      properties:
        type:
          const: CANCEL_SESSION
        payload:
          description: Empty object
          type: object
          additionalProperties: false
      required:
        - type
        - payload
    session:
      title: Identity Verification session
      description: |
        An identity verification session resource.
      oneOf:
        - $ref: '#/components/schemas/session-flow-none'
        - $ref: '#/components/schemas/session-flow-trusted'
        - $ref: '#/components/schemas/session-flow-negotiated'
        - $ref: '#/components/schemas/session-flow-mo'
        - $ref: '#/components/schemas/session-flow-mt'
    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
          example: >-
            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
          example: 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
          example: https://developer.bango.com/error-codes/payment-provider-failure
      required:
        - code
        - meta
        - message
    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
      example: 673c74de-ce5b-4f79-9851-2544d1d836cb
    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
      example: 581b2e40-741c-4683-ae66-46c9fe6f4d5e
    payment-instrument-account-properties:
      title: Payment instrument account properties
      description: >
        Properties of a payment instrument that identify the account with the
        payment provider. In many cases, this is a phone number.


        MUST contain at least one property. MAY contain more than one property.
        All property values MUST be strings.


        The `phoneNumber` property defined here MUST be used IF the payment
        provider identifies the account using a phone number that can be
        expressed in E.164 format with a leading `+`. Otherwise, the property
        MUST NOT be used (use a property with a different name instead).
      type: object
      minProperties: 1
      maxProperties: 50
      unevaluatedProperties:
        type: string
        minLength: 1
        maxLength: 512
      properties:
        phoneNumber:
          $ref: '#/components/schemas/phone-number'
      example:
        phoneNumber: '+447700900123'
        anyPropertyNeededByThePaymentProvider: some-string
    payment-provider-id:
      title: Payment provider ID
      description: >
        Friendly unique identifier for the payment provider.


        Internally, corresponds to the `accountKey` property in the
        route-config-server's partner_namespaces table.
      x-bango-public-description: |
        Friendly unique identifier for the payment provider.
      type: string
      example: OGNABTEL
      minLength: 2
      maxLength: 50
    simple-object-patch:
      title: Simple object patch mechanism
      description: >
        Extend an existing object schema with this schema to enable a simple way
        to patch an object.


        The extended schema has two special properties:

        - $replace: boolean. If present, and if true, then this means "remove
        all existing properties from the object before applying updates"

        - $remove: an array of property names. If present, then this means
        "remove properties with these names from the object before applying
        updates"


        This extended schema now lets you define a patch object, which specifies
        operations to perform on an existing object to make a new object. In the
        patch object, `$replace` and `$remove` (applied first) remove existing
        properties from the original object, and other properties update the
        original object.


        Nested objects might themselves be extended this way: patches are
        applied recursively.


        Examples


        Imagine a schema ABC defining three optional properties `a`, `b`, and
        `c` whose values are all strings. Consider this object matching schema
        ABC:


        ```json

        {
          "a": "xyz",
          "b": "qwerty",
          "c": "plplpl"
        }

        ```


        Extend ABC with this schema (adding `$remove` and `$replace`) to get
        ABC_Patchable. Here's a patch object matching ABC_Patchable:


        ```json

        {
          "$remove": ["b"],
          "a": "aaaaaaa"
        }

        ```


        Applying the patch - combining the original object with the patch object
        - gives this object:


        ```json

        {
          "a": "aaaaaaa",
          "c": "plplpl"
        }

        ```


        - The property `b` was removed (because of `$remove` in the patch
        object)

        - The property `a` was updated (because it was specified in the patch
        object)

        - The property `c` was unchanged (because it wasn't mentioned in the
        patch object)


        Another example of a patch object:


        ```json

        {
          "$replace": true,
          "b": "bbbbbbb"
        }

        ```


        The result after patching the original object would be:


        ```json

        {
          "b": "bbbbbbb"
        }

        ```


        - All existing properties were removed (because `$replace` was set to
        true in the patch object)

        - The property `b` was updated (because it was specified in the patch
        object)


        Now imagine a schema GH defining two properties `g` and `h`, where the
        value of `g` is a string and the value of `h` is an object (matching
        schema XY) with optional properties `x` and `y`, both strings. Consider
        this object matching schema GH:


        ```json

        {
          "g": "ggg",
          "h": {
            "x": "xxx",
            "y": "yyy"
          }
        }

        ```


        Extend both GH and the nested XY schemas with this schema, making
        GH_Patchable. Here's a patch object matching GH_Patchable:


        ```json

        {
          "$remove": ['g'],
          "h": {
            "$replace": true,
            "x": "aaa"
          }
        }

        ```


        The result after patching the object above would be:


        ```json

        {
          "h": {
            "x": "aaa"
          }
        }

        ```


        - The property `g` was removed (because of `$remove` in the patch
        object)

        - The properties `x` and `y` were removed (because `$replace` was set to
        true in the inner patch object)

        - The property `x` was updated (because it was specifed in the inner
        patch object)
      type: object
      properties:
        $replace:
          description: >
            If true, removes all existing properties from the object before
            applying any property updates.
          type: boolean
          default: false
        $remove:
          description: >
            If present, removes the properties named in the array before
            applying any property updates.


            It is NOT an error if an array member references a property that
            does not exist in the object being patched.


            It is NOT an error if an array member references a property not
            defined in the schema of the object being patched.


            It is NOT an error to include a property in the array and also to
            update its value.
          type: array
          items:
            type: string
    private:
      description: >
        A place for the merchant partner to store private data related to the
        identity verification session. Once the payment instrument token is
        generated, this data is associated with the token.


        Merchant partners can initialize the data when creating a session, and
        can patch this data later when starting a flow or using an
        UPDATE_SESSION_DATA action.


        Supports any data (constraints TBD). This schema defines some commonly
        used properties.
      type: object
      properties:
        partnerCustomerId:
          description: >
            Optional. The partner's unique identifier for the end user. Bango
            treats this as an opaque string, which must not be empty.
          type: string
          minLength: 1
          example: 6789812A
        OTHER:
          description: >
            Any other private data. TBD: constraints; other common properties,
            if any.
    nextAction:
      description: >
        An optional next action for either the merchant partner or the payment
        provider. This string, read/write for both parties, allows either party
        to send an explicit signal to the other using a well-defined property.
        Either party may set the string as part of an "update shared data"
        operation.


        Typically the string is used by one party to inform the other party that
        there is session data for them to process to progress the negotation.
        That session data should provide additional context as needed.


        For flexibility, this schema specifies any string. Bango recommends
        using these strings:

        - `none`: No next action is currently defined

        - `merchant`: A signal for the merchant partner to take the next action

        - `payment-provider`: A signal for the payment provider to take the next
        action
      type: string
      minLength: 1
      default: none
    merchantToPaymentProvider:
      description: >
        Data the merchant partner owns (read/write access) and the payment
        provider may consume (read access only).


        This specification defines some properties that merchant partners and
        payment providers MAY use for certain purposes. These properties are
        optional, but if specified MUST match the schemas defined here.


        Merchant partners and payment providers MAY use other properties not
        defined here.
      type: object
      properties:
        authSuccessRedirectUrl:
          description: >
            The merchant URL to which the payment provider should redirect the
            end user after a successful authentication.
          type: string
          format: url
          example: https://example.com/merchant/user-login-ok
        authFailureRedirectUrl:
          description: >
            The merchant URL to which the payment provider should redirect the
            end user after a failed authentication.
          type: string
          format: url
          example: https://example.com/merchant/user-login-failed
    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
    session-flow-none:
      title: Identity verification session - no flow selected
      description: |
        An identity verification session when no flow has been selected.
      type: object
      properties:
        rid:
          $ref: '#/components/schemas/resource-id'
        lastUpdate:
          $ref: '#/components/schemas/lastUpdate'
        partnerSessionId:
          $ref: '#/components/schemas/partnerSessionId'
        private:
          $ref: '#/components/schemas/private'
        shared:
          $ref: '#/components/schemas/identity-session-shared'
        flow:
          $ref: '#/components/schemas/flow-none'
        state:
          $ref: '#/components/schemas/state-flow-none'
        result:
          $ref: '#/components/schemas/result-flow-any'
      additionalProperties: false
      required:
        - rid
        - lastUpdate
        - flow
        - state
    session-flow-trusted:
      title: Identity verification session - Trusted flow selected
      description: >
        An identity verification session when the Trusted flow has been
        selected.
      type: object
      properties:
        rid:
          $ref: '#/components/schemas/resource-id'
        lastUpdate:
          $ref: '#/components/schemas/lastUpdate'
        partnerSessionId:
          $ref: '#/components/schemas/partnerSessionId'
        paymentProviderId:
          $ref: '#/components/schemas/payment-provider-id'
        private:
          $ref: '#/components/schemas/private'
        shared:
          $ref: '#/components/schemas/identity-session-shared'
        flow:
          $ref: '#/components/schemas/flow-trusted'
        state:
          $ref: '#/components/schemas/state-flow-trusted'
        result:
          $ref: '#/components/schemas/result-flow-any'
        paymentInstrumentToken:
          $ref: '#/components/schemas/paymentInstrumentToken-flow-trusted'
      additionalProperties: false
      required:
        - rid
        - lastUpdate
        - flow
        - state
    session-flow-negotiated:
      title: Identity verification session - Negotiated flow selected
      description: >
        An identity verification session when the Negotiated flow has been
        selected.
      type: object
      properties:
        rid:
          $ref: '#/components/schemas/resource-id'
        lastUpdate:
          $ref: '#/components/schemas/lastUpdate'
        partnerSessionId:
          $ref: '#/components/schemas/partnerSessionId'
        paymentProviderId:
          $ref: '#/components/schemas/payment-provider-id'
        private:
          $ref: '#/components/schemas/private'
        shared:
          $ref: '#/components/schemas/identity-session-shared'
        flow:
          $ref: '#/components/schemas/flow-negotiated'
        state:
          $ref: '#/components/schemas/state-flow-negotiated'
        result:
          $ref: '#/components/schemas/result-flow-any'
        paymentInstrumentToken:
          $ref: '#/components/schemas/paymentInstrumentToken-flow-negotiated'
      additionalProperties: false
      required:
        - rid
        - lastUpdate
        - flow
        - state
    session-flow-mo:
      title: Identity verification session - MO flow selected
      description: |
        An identity verification session when the MO flow has been selected.
      type: object
      properties:
        rid:
          $ref: '#/components/schemas/resource-id'
        lastUpdate:
          $ref: '#/components/schemas/lastUpdate'
        partnerSessionId:
          $ref: '#/components/schemas/partnerSessionId'
        paymentProviderId:
          $ref: '#/components/schemas/payment-provider-id'
        private:
          $ref: '#/components/schemas/private'
        shared:
          $ref: '#/components/schemas/identity-session-shared'
        flow:
          $ref: '#/components/schemas/flow-mo'
        state:
          $ref: '#/components/schemas/state-flow-mo'
        shortcode:
          $ref: '#/components/schemas/shortcode-flow-mo'
        messageBody:
          $ref: '#/components/schemas/messageBody-flow-mo'
        transport:
          $ref: '#/components/schemas/mo-transport'
        result:
          $ref: '#/components/schemas/result-flow-any'
        paymentInstrumentToken:
          $ref: '#/components/schemas/paymentInstrumentToken-flow-mo'
        partnerBillingToken:
          $ref: '#/components/schemas/partner-billing-token'
      additionalProperties: false
      required:
        - rid
        - lastUpdate
        - flow
        - state
    session-flow-mt:
      title: Identity verification session - MT flow selected
      description: |
        An identity verification session when the MT flow has been selected.
      type: object
      additionalProperties: false
      properties:
        rid:
          $ref: '#/components/schemas/resource-id'
        lastUpdate:
          $ref: '#/components/schemas/lastUpdate'
        partnerSessionId:
          $ref: '#/components/schemas/partnerSessionId'
        paymentProviderId:
          $ref: '#/components/schemas/payment-provider-id'
        private:
          $ref: '#/components/schemas/private'
        shared:
          $ref: '#/components/schemas/identity-session-shared'
        flow:
          $ref: '#/components/schemas/flow-mt'
        state:
          $ref: '#/components/schemas/state-flow-mt'
        otp:
          $ref: '#/components/schemas/otp-flow-mt'
        result:
          $ref: '#/components/schemas/result-flow-mt'
        paymentInstrumentToken:
          $ref: '#/components/schemas/paymentInstrumentToken-flow-mt'
      required:
        - rid
        - lastUpdate
        - flow
        - state
    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'
    InvalidCredentials:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/invalid-credentials'
    PermissionDenied:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/permission-denied'
    NotFound:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/not-found'
    Conflict:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/incompatible-state'
    TooManyRequests:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/too-many-requests'
    ServiceUnavailable:
      allOf:
        - $ref: '#/components/schemas/CommonErrorResponse'
        - properties:
            errors:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/service-unavailable'
    phone-number:
      title: Phone number (E.164)
      description: >
        A phone number in E.164 format, with a leading `+` sign. No spaces or
        symbols are permitted.
      type: string
      pattern: ^\+[1-9]?[0-9]{7,14}$
      example: '+447700900123'
    lastUpdate:
      type: string
      format: date-time
      description: |
        RFC 3339 datetime of the last update to this resource
      example: '2022-12-21T08:59:32Z'
    partnerSessionId:
      description: >
        A session ID supplied by the partner. This is assumed to be unique
        across all the partner's identity verification sessions.
      type: string
      minLength: 1
      example: e9342a9f-ff3f-44ad-8e30-8a6f9a820060
    identity-session-shared:
      title: Shared identity verification session properties
      description: >
        Data shared between the merchant partner and the payment provider as
        part of an identity verification session.
      type: object
      properties:
        nextAction:
          description: >
            An optional next action for either the merchant partner or the
            payment provider. This string, read/write for both parties, allows
            either party to send an explicit signal to the other using a
            well-defined property. Either party may set the string as part of an
            "update shared data" operation.


            Typically the string is used by one party to inform the other party
            that there is session data for them to process to progress the
            negotation. That session data should provide additional context as
            needed.


            For flexibility, this schema specifies any string. Bango recommends
            using these strings:

            - `none`: No next action is currently defined

            - `merchant`: A signal for the merchant partner to take the next
            action

            - `payment-provider`: A signal for the payment provider to take the
            next action
          type: string
          minLength: 1
          default: none
        merchantToPaymentProvider:
          description: >
            Data the merchant partner owns (read/write access) and the payment
            provider may consume (read access only).


            This specification defines some properties that merchant partners
            and payment providers MAY use for certain purposes. These properties
            are optional, but if specified MUST match the schemas defined here.


            Merchant partners and payment providers MAY use other properties not
            defined here.
          type: object
          properties:
            authSuccessRedirectUrl:
              description: >
                The merchant URL to which the payment provider should redirect
                the end user after a successful authentication.
              type: string
              format: url
              example: https://example.com/merchant/user-login-ok
            authFailureRedirectUrl:
              description: >
                The merchant URL to which the payment provider should redirect
                the end user after a failed authentication.
              type: string
              format: url
              example: https://example.com/merchant/user-login-failed
        paymentProviderToMerchant:
          description: >
            Data the payment provider owns (read/write access) and the merchant
            partner may consue (read access only)
          type: object
          properties:
            authRedirectUrl:
              description: >
                The payment provider URL to which the merchant should redirect
                the end user to authenticate to the payment provider.
              type: string
              format: url
              example: https://example.com/payment-provider/login
    flow-none:
      const: none
      description: |
        No flow has been selected
    state-flow-none:
      description: >
        Describes the state of the resource when no flow has been selected.


        `state` is one of:

        - `authorizing` - the Bango Platform is checking for permission to
        create the session

        - `new` - the session is created and the Bango Platform is ready for the
        partner to select a flow

        - `failed` - the Bango Platform has denied the request to create the
        session

        - `closed` - the partner has decided to cancel the session without
        selecting a flow


        Typically partners see only `new`. `authorizing` is very short-lived,
        `failed` is possible but unlikely, and `closed` is only entered at the
        partner's request.
      type: string
      enum:
        - authorizing
        - new
        - failed
        - closed
    result-flow-any:
      title: Action result, if any
      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

        2. The action was performed and completed with a negative outcome

        3. The action was not performed because a required constraint was not
        met


        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-denied
            - create-failed
            - flow-denied
            - flow-failed
            - token-created
          example: token-created
        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/incompatible-state'
              - $ref: '#/components/schemas/internal-server-error'
              - $ref: '#/components/schemas/service-unavailable'
              - $ref: '#/components/schemas/user-canceled'
              - $ref: '#/components/schemas/expired'
              - $ref: '#/components/schemas/payment-provider-failure'
              - $ref: '#/components/schemas/merchant-failure'
              - $ref: '#/components/schemas/user-invalid'
              - $ref: '#/components/schemas/user-barred'
              - $ref: '#/components/schemas/user-suspended'
              - $ref: '#/components/schemas/user-not-enabled'
              - $ref: '#/components/schemas/rejected'
              - $ref: '#/components/schemas/operation-not-supported'
              - $ref: '#/components/schemas/denied'
              - $ref: '#/components/schemas/unauthorized-flow'
      required:
        - code
        - reasons
    flow-trusted:
      description: |
        Indicates the `trusted` identity verification flow was selected.
      const: trusted
    state-flow-trusted:
      description: >
        Describes the state of the resource when the Trusted flow has been
        selected.


        `state` is one of:

        - `authorizing` - the Bango Platform is checking for permission to start
        the flow

        - `creating-token` - the Bango Platform is obtaining the payment
        instrument token

        - `succeeded` - the Bango Platform has successfully obtained the payment
        instrument token (it's a property on the resource)

        - `failed` - the Bango Platform has denied the request to start the flow


        Typically partners only see `succeeded`. `authorizing` and
        `creating-token` are short-lived, and `failed` occurs when the partner
        is not authorized for this flow.
      type: string
      enum:
        - authorizing
        - creating-token
        - succeeded
        - failed
    paymentInstrumentToken-flow-trusted:
      description: >
        The payment instrument token obtained by the Bango Platform for the
        partner's end user.


        Only present in the resource when `state` is `succeeded`.
      type: string
      format: uuid
    flow-negotiated:
      description: |
        Indicates the `negotiated` identity verification flow was selected.
      const: negotiated
    state-flow-negotiated:
      description: >
        Describes the state of the resource when the Negotiated flow has been
        selected.


        `state` is one of:

        - `authorizing` - the Bango Platform is checking for permission to start
        the flow

        - `awaiting-confirmation` - the Bango Platform is awaiting confirmation
        of the end user's identity from the payment provider

        - `creating-token` - the payment provider confirmed the end user's
        identity and the Bango Platform is obtaining the payment instrument
        token

        - `succeeded` - the Bango Platform has successfully obtained the payment
        instrument token (it's a property on the resource)

        - `failed` - the Bango Platform has denied the request to start the
        flow, or the payment provider rejected the attempt to identify the end
        user


        Typically partners only see `awaiting-confirmation`,  and `succeeded`.
        `authorizing` and `creating-token` are short-lived, and `failed` occurs
        when the partner is not authorized for this flow.
      type: string
      enum:
        - authorizing
        - awaiting-confirmation
        - creating-token
        - succeeded
        - failed
    paymentInstrumentToken-flow-negotiated:
      description: >
        The payment instrument token obtained by the Bango Platform for the
        partner's end user.


        Only present in the resource when `state` is `succeeded`.
      type: string
      format: uuid
    flow-mo:
      description: |
        Indicates the `mo` identity verification flow was selected.
      const: mo
    state-flow-mo:
      description: >
        Describes the state of the resource when the MO flow has been selected.


        `state` is one of:

        - `authorizing` - the Bango Platform is checking for permission to start
        the flow

        - `awaiting-message` - the Bango Platform is waiting for the MO message
        from the payment provider

        - `awaiting-confirmation` - the Bango Platform is awaiting confirmation
        of the end user's identity from the merchant

        - `creating-token` - the payment provider confirmed the end user's
        identity and the Bango Platform is obtaining the payment instrument
        token

        - `succeeded` - the Bango Platform has successfully obtained the payment
        instrument token (it's a property on the resource)

        - `failed` - the Bango Platform has denied the request to start the
        flow, or the merchant rejected the attempt to identify the end user, or
        there was a problem with the MO message


        Typically partners only see `awaiting-message`, `awaiting-confirmation`,
        and `succeeded`. `authorizing` and `creating-token` are short-lived, and
        `failed` occurs in case of errors.
      type: string
      enum:
        - authorizing
        - awaiting-message
        - awaiting-confirmation
        - creating-token
        - succeeded
        - failed
    shortcode-flow-mo:
      description: >
        Shortcode the merchant must use to send the message to the payment
        provider.


        Sourced from billing-route-service.


        Omitted if we don't need to tell the merchant, or if the merchant did
        not create the verification session itself.
      type: string
      pattern: ^[0-9]{1,20}$
      example: '12345'
    messageBody-flow-mo:
      description: >
        The full text of the message the merchant must send from the end user's
        device to the payment provider (using the shortcode if supplied).


        Static string `bango-session-rid:` followed by the verification session
        rid. Always exactly 54 bytes.


        Omitted if the merchant did not create the verification session itself.
        Present if it did.
      type: string
      minLength: 54
      maxLength: 54
      example: bango-session-rid:68aec572-c34e-4f68-aa80-10300c4dc06b
    mo-transport:
      title: MO transport mechanism
      description: >
        How the MO message was delivered to the payment provider.


        Permitted values:

        - `sms`: MO message was delivered over SMS

        - `http-header-enrichment`: MO message was delivered over HTTP with user
        account details provided using Header Enrichment
      type: string
      enum:
        - sms
        - http-header-enrichment
    paymentInstrumentToken-flow-mo:
      description: >
        The payment instrument token obtained by the Bango Platform for the
        partner's end user.


        Only present in the resource when `state` is `succeeded`.
      type: string
      format: uuid
    partner-billing-token:
      title: Partner billing token
      description: >
        A partner billing token to be used later by the partner in payment
        transactions.


        It may be present only after being provided by the partner in a previous
        confirm session identity request.
      type: string
      minLength: 1
      maxLength: 100
    flow-mt:
      description: |
        Indicates the `mt` identity verification flow was selected.
      const: mt
    state-flow-mt:
      description: >
        Describes the state of the resource when the MT flow has been selected.


        `state` is one of:

        - `authorizing` - the Bango Platform is checking for permission to start
        the flow

        - `processing-otp` - the Bango Platform is creating, validating,
        renewing, or resetting an OTP

        - `processing-pp-otp` - the Bango Platform has asked the payment
        provider to send or verify an OTP

        - `sending-otp` - the Bango Platform has asked the payment provider to
        send the OTP to the user, and is waiting for a response

        - `awaiting-user-otp` - the Bango Platform is waiting for the merchant
        to send an action related to the OTP: verify, reset, or resent

        - `creating-token` - the merchant end user entered the OTP correctly and
        the Bango Platform is obtaining the payment instrument token

        - `succeeded` - the Bango Platform has successfully obtained the payment
        instrument token (it's a property on the resource)

        - `failed` - the Bango Platform has denied the request to start the
        flow, or the payment provider fatally denied the request to send the MT
        message to the end user, or a service error occurred


        Typically partners only see `awaiting-user-otp` and `succeeded`.
        `authorizing`, `processing-otp`, `processing-pp-otp`, `sending-otp`, and
        `creating-token` are short-lived, and `failed` occurs in case of errors.
      type: string
      enum:
        - authorizing
        - processing-otp
        - processing-pp-otp
        - sending-otp
        - awaiting-user-otp
        - creating-token
        - succeeded
        - failed
    otp-flow-mt:
      title: OTP properties
      description: >
        Properties useful to the merchant about the current OTP and retries and
        resets available. Only used for Bango-managed OTPs.
      type: object
      additionalProperties: false
      properties:
        triesUntilReset:
          description: >
            How many attempts remain for the merchant end user to type the
            current OTP before a reset occurs, if available
          type: integer
          minimum: 0
          example: 3
        resetsAvailable:
          description: >
            How many times the merchant may request to generate a new OTP within
            the session. When `triesUntilReset` and `resetsAvailable` are both
            zero, the session ends in failure.
          type: integer
          minimum: 0
          example: 5
        validUntil:
          description: >
            RFC 3339 datetime after which the current OTP expires. On expiry,
            any attempt to verify the OTP fails and a reset occurs, if available
          type: string
          format: date-time
          example: '2024-02-06T18:31:36Z'
    result-flow-mt:
      title: Action result, if any
      description: >
        The result of the most recent action.


        The result `code` indicates what happened and is always a string in
        `lower-kebab-case`.


        The result `reasons` indicates any additional explanations available. It
        might be 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_.


            Route configuration identifies which actor manages OTPs for the
            flow: either the Bango Platform or the payment provider.

            - Values marked with [B] are returned only when the Bango Platform
            manages the OTPs

            - Values marked with [PP] are returned only when the payment
            provider manages the OTPs

            - Values without a marker are returned in either case


            Possible values:

            - `create-denied`
              - Bango Platform denied the request to create the session
            - `create-failed`
              - Bango Platform encountered an error while creating the session
            - `flow-denied`
              - Bango Platform or payment provider denied the request to start a flow. Occurs if the payment provider doesn't recognize the account properties supplied
            - `flow-failed`
              - Bango Platform encountered an error while performing an internal operation
            - `token-created`
             - Bango Platform successfully created the payment instrument token
            - `otp-created-send-requested` [B]
              - Merchant started flow
              - Bango Platform generated the first OTP and asked the payment provider to send it to the end user
            - `otp-reset-send-requested` [B]
              - Merchant requested RESET, or RESEND of an expired OTP
              - Bango Platform reset the OTP, and asked the payment provider to send it to the end user
            - `otp-resend-requested` [B]
              - Merchant requested RESEND of an unexpired OTP
              - Bango Platform reset the expiry date and asked the payment provider to send the current OTP to the end user again
            - `otp-expired-send-requested` [B]
              - Merchant requested VERIFY of an expired OTP
              - Bango Platform generated a new OTP and asked the payment provider to send it to the end user
            - `otp-incorrect-send-requested` [B]
              - Merchant requested VERIFY of an unexpired OTP, the supplied OTP was incorrect, no more attempts remain for that OTP, but resets are available
              - Bango Platform generated a new OTP and asked the payment provider to send it to the end user
            - `otp-send-requested` [PP]
              - Bango Platform asked the payment provider to generate and send an OTP to the end user, or send an unexpired OTP it generated earlier
            - `otp-send-request-denied` [PP]
              - Bango Platform asked the payment provider to generate and send an OTP to the end user, or send an unexpired OTP it generated earlier, but payment provider denied the request for security reasons
            - `otp-send-request-failure` [B]
              - Any merchant action
              - Bango Platform asked the payment provider to send an OTP to the end user, and the payment provider did not accept the request
              - Merchant should RESEND
            - `otp-expired-must-resend` [B]
              - Merchant requested VERIFY of an expired OTP
              - Bango Platform generated a new OTP
              - Bango Platform is configured to wait for the merchant to request RESEND
            - `otp-expired` [PP]
              - Merchant requested VERIFY, and the payment provider reported that the OTP has expired. Merchant should request RESET
            - `otp-incorrect-must-resend` [B]
              - Merchant requested VERIFY of an unexpired OTP, the supplied OTP was incorrect, no more attempts remain for that OTP, but resets are available
              - Bango Platform generated a new OTP
              - Bango Platform is configured to wait for the merchant to request RESEND
            - `otp-incorrect`
              - Merchant requested VERIFY of an unexpired OTP, and the supplied OTP was incorrect. For a Bango-managed OTP, more attempts remain for that OTP. For a payment-provider-managed OTP, more attempts MIGHT remain
              - Merchant can request VERIFY again, or RESET, or RESEND
            - `otp-reset-not-available` [B]
              - Merchant requested RESET and more attempts are available but no resets, OR
              - Merchant requested RESEND of an expired OTP and no resets are available
            - `otp-incorrect-final-attempt`
              - Merchant requested VERIFY, the supplied OTP was incorrect, and now there are no more retries or resets available
              - Bango Platform closed the session in state `failed`
            - `session-ended` [B]
              - Merchant requested VERIFY when no retries or resets are available, OR
              - Merchant requested RESET when no retries or resets are available, OR
              - Merchant requested RESEND of an expired OTP and no retries or resets are available
            - `flow-temporary-error` [B]
              - Bango Platform encountered a temporary internal error
              - Merchant should try again
            - `pp-otp-error` [PP]
              - Bango Platform asked the payment provider to send an OTP to a merchant end user, or verify an OTP supplied by a merchant end user, and an error occurred at the payment provider
              - Merchant should try again
            - `unknown`
              - An unknown error occurred
              - Merchant should try again
          type: string
          enum:
            - create-denied
            - create-failed
            - flow-denied
            - flow-failed
            - token-created
            - otp-created-send-requested
            - otp-reset-send-requested
            - otp-resend-requested
            - otp-expired-send-requested
            - otp-incorrect-send-requested
            - otp-send-requested
            - otp-send-request-denied
            - otp-send-request-failure
            - otp-expired-must-resend
            - otp-expired
            - otp-incorrect-must-resend
            - otp-incorrect
            - otp-reset-not-available
            - otp-incorrect-final-attempt
            - session-ended
            - flow-temporary-error
            - pp-otp-error
            - unknown
          example: token-created
        reasons:
          description: >
            Any explanations available to describe the outcome of the most
            recent action. Empty if no more details are available or needed.
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/missing-parameter'
              - $ref: '#/components/schemas/invalid-parameter'
              - $ref: '#/components/schemas/incompatible-state'
              - $ref: '#/components/schemas/internal-server-error'
              - $ref: '#/components/schemas/service-unavailable'
              - $ref: '#/components/schemas/user-canceled'
              - $ref: '#/components/schemas/expired'
              - $ref: '#/components/schemas/payment-provider-failure'
              - $ref: '#/components/schemas/merchant-failure'
              - $ref: '#/components/schemas/user-invalid'
              - $ref: '#/components/schemas/user-barred'
              - $ref: '#/components/schemas/user-suspended'
              - $ref: '#/components/schemas/user-not-enabled'
              - $ref: '#/components/schemas/rejected'
              - $ref: '#/components/schemas/operation-not-supported'
              - $ref: '#/components/schemas/denied'
              - $ref: '#/components/schemas/unauthorized-flow'
      required:
        - code
        - reasons
    paymentInstrumentToken-flow-mt:
      description: >
        The payment instrument token obtained by the Bango Platform for the
        partner's end user.


        Only present in the resource when `state` is `succeeded`.
      type: string
      format: uuid
    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
          example: The request body is not valid JSON
        url:
          description: URL to more information about the error type
          type: string
          format: url
          example: https://developer.bango.com/error-codes/invalid-json
      required:
        - code
        - meta
        - message
    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
          example: A required parameter was missing from the request
        url:
          description: URL to more information about the error type
          type: string
          format: url
          example: 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
              example: 'Expected format: YYYY-MM-DD'
          required:
            - param
        message:
          description: Human-readable message describing the error
          type: string
          example: A parameter in the request was not valid
        url:
          description: URL to more information about the error type
          type: string
          format: url
          example: https://developer.bango.com/error-codes/invalid-parameter
      required:
        - code
        - meta
        - message
    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
          example: The supplied credentials are not valid
        url:
          description: URL to more information about the error type
          type: string
          format: url
          example: https://developer.bango.com/error-codes/invalid-credentials
      required:
        - code
        - meta
        - message
    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
          example: The client is not permitted to perform this operation
        url:
          description: URL to more information about the error type
          type: string
          format: url
          example: https://developer.bango.com/error-codes/permission-denied
      required:
        - code
        - meta
        - message
    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
          example: The requested resource was not found
        url:
          description: URL to more information about the error type
          type: string
          format: url
          example: https://developer.bango.com/error-codes/not-found
      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
              example: 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
          example: https://developer.bango.com/error-codes/incompatible-state
      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
          example: Request limit reached. Please try again later
        url:
          description: URL to more information about the error type
          type: string
          format: url
          example: https://developer.bango.com/error-codes/too-many-requests
      required:
        - code
        - meta
        - message
    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
          example: >-
            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
          example: https://developer.bango.com/error-codes/service-unavailable
      required:
        - code
        - meta
        - message
    user-canceled:
      title: user-canceled
      description: >
        The payment provider denied a requested action because the user
        canceled.
      type: object
      properties:
        code:
          const: user-canceled
        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
          example: https://developer.bango.com/error-codes/user-canceled
      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
          example: https://developer.bango.com/error-codes/expired
      required:
        - code
        - meta
        - message
    merchant-failure:
      title: merchant-failure
      description: >
        An error occurred with the upstream merchant, and the Bango Platform was
        unable to fulfil the request.


        This might be a transient error or a persistent error. The
        `meta.merchantCode` value indicates the type of response received by the
        Bango Platform from the merchant.
      type: object
      properties:
        code:
          const: merchant-failure
        meta:
          description: Additional information to help identify the specific error case
          type: object
          properties:
            merchantCode:
              description: >
                Code indicating the type of response received by the Bango
                Platform from the merchant.
              type: string
              enum:
                - internal-server-error
                - service-unavailable
          required:
            - merchantCode
        message:
          description: Human-readable message describing the error
          const: An error occurred at the merchant
        url:
          description: URL to more information about the error type
          type: string
          format: url
          example: https://developer.bango.com/error-codes/merchant-failure
      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
          example: 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
          example: 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
          example: 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
          example: https://developer.bango.com/error-codes/user-not-enabled
      required:
        - code
        - meta
        - message
    rejected:
      title: rejected
      description: >
        The responsible partner decided not to confirm the identity of an end
        user as part of an identity verification flow, and did not supply a
        specific error code. The `message` may contain more information.


        The identity verification flow for the session determines whether the
        responsible partner is the payment provider or the merchant.
      type: object
      properties:
        code:
          const: rejected
        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
          example: https://developer.bango.com/error-codes/rejected
      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
          example: 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
          example: https://developer.bango.com/error-codes/denied
      required:
        - code
        - meta
        - message
    unauthorized-flow:
      title: unauthorized-flow
      description: |
        The merchant is not authorized to use the requested flow.
      type: object
      properties:
        code:
          const: unauthorized-flow
        meta:
          description: Empty in this case
          type: object
        message:
          description: Human-readable message describing the error
          const: Not authorized to start requested flow
        url:
          description: URL to more information about the error type
          type: string
          format: url
          example: https://developer.bango.com/error-codes/unauthorized-flow
      required:
        - code
        - meta
        - message
  responses:
    BadRequestErrorResponse:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BadRequest'
    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'
    ConflictErrorResponse:
      description: >
        The 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.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Conflict'
    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'
    ServiceUnavailableErrorResponse:
      description: Service unavailable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ServiceUnavailable'
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic

````