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

# Verify OTP

> Completes step 2 of the OTP-verified collection flow, currently required for Cote D'Ivoire Orange payins. Submit the OTP the customer received by SMS along with the `payment_token` returned from the initial [Unified Collections](/api-reference/collections/unified-collections) request. See the [OTP-Verified Payins guide](/collecting-payments/methods#5-otp-verified-payins-c%C3%B4te-divoire-orange) for the full two-step flow.

<Note>
  This is step 2 of the OTP-verified collection flow. Step 1 is the standard [Unified Collections](/api-reference/collections/unified-collections) request, which returns a `payment_token` instead of a terminal status when OTP verification is required. See the [OTP-Verified Payins guide](/collecting-payments/methods#5-otp-verified-payins-c%C3%B4te-divoire-orange) for the full walkthrough.
</Note>


## OpenAPI

````yaml post /api/v4/niobi-unified-process-transaction
openapi: 3.0.0
info:
  title: Niobi API
  description: >-
    REST API for collecting payments, sending payouts, and managing
    multi-currency wallets across Africa and global corridors. All requests
    require IP whitelisting and a unique per-request HMAC SHA-256 signature.
  version: 4.0.0
servers:
  - url: https://sandbox.users.niobi.co
    description: Sandbox, Development and Testing
security: []
tags:
  - name: Niobi
    description: API Endpoints of Niobi
paths:
  /api/v4/niobi-unified-process-transaction:
    post:
      tags:
        - payment
      summary: Verify OTP
      description: >-
        Completes step 2 of the OTP-verified collection flow, currently required
        for Cote D'Ivoire Orange payins. Submit the OTP the customer received by
        SMS along with the `payment_token` returned from the initial [Unified
        Collections](/api-reference/collections/unified-collections) request.
        See the [OTP-Verified Payins
        guide](/collecting-payments/methods#5-otp-verified-payins-c%C3%B4te-divoire-orange)
        for the full two-step flow.
      operationId: VerifyOtp
      requestBody:
        description: >-
          Signed request envelope carrying the OTP and payment token from step
          1.
        required: true
        content:
          application/json:
            schema:
              required:
                - client_id
                - sender
                - timestamp
                - salt
                - signature
                - params
              properties:
                client_id:
                  description: >-
                    Your Client ID from the Niobi Dashboard under Workspace >
                    Integrations.
                  type: string
                sender:
                  description: >-
                    The exact title of your integration as registered in the
                    Dashboard. Case-sensitive.
                  type: string
                timestamp:
                  description: >-
                    Unix timestamp in seconds at the time of signing. Must match
                    the value used to generate the signature.
                  type: integer
                salt:
                  description: >-
                    A unique random string you generate per request. Must be the
                    same value used when generating the signature.
                  type: string
                signature:
                  description: >-
                    SHA-256 signature computed from this payload. Generate via
                    the [Signature
                    endpoint](/api-reference/authentication/generate-signature)
                    or your own backend.
                  type: string
                params:
                  required:
                    - otp
                    - payment_token
                  properties:
                    otp:
                      description: >-
                        The one-time password the customer received by SMS.
                        Valid for 2 minutes in production. Use `000000` in
                        sandbox to simulate successful verification.
                      type: string
                      example: '1234'
                    payment_token:
                      description: >-
                        The token returned in the `data.payment_token` field of
                        the initiating Unified Collections response (e.g.
                        `NIO-S0000001`).
                      type: string
                      example: NIO-S0000001
                  type: object
              type: object
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Transaction completed successfully.
                  data:
                    type: object
                    properties:
                      status:
                        type: string
                        example: success
                        description: Final transaction status.
                      payment_step:
                        type: integer
                        example: 2
                        description: >-
                          Terminal step indicator, matches the value sent to
                          your callback_url.
                      third_party_reference_1:
                        type: string
                        example: ORDER-991
                        description: >-
                          The merchant reference from the original request, if
                          provided.
                type: object
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
                    example: false
                  message:
                    type: string
                    example: Invalid or expired OTP, or payment_token not found.
                type: object
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
                    example: false
                  message:
                    type: string
                    example: >-
                      Entity integration record not found or Client id not
                      matched or Request was not verified.
                type: object

````