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

# Verify Debit Wallet

> Completes a debit that requires OTP verification for `SMALL_PPI` or `FULL_KYC_PPI` sub-wallets. Call this endpoint after [Debit Wallet](/api-reference/prepaid-payment-instruments/wallet-management/debit-wallet) returns `OTP_GENERATED`. Submit the `debit_id` from that response and the OTP the end user received on the channels you configured in `auth.data.notification_modes`. On success, the debit status becomes `SUCCESS` and funds are debited. A maximum of three verification attempts is allowed per `debit_id`.


<Note>
  Use this API to complete a debit transaction that requires OTP verification. Call this API after the [Debit Wallet API](/api-reference/prepaid-payment-instruments/wallet-management/debit-wallet) returns a status of `OTP_GENERATED` for `SMALL_PPI` or `FULL_KYC_PPI` sub-wallets. The request accepts two fields: `debit_id` and `otp`.
</Note>

<Warning>
  A maximum of three verification attempts is allowed per `debit_id`. Further attempts return an error.
</Warning>


## OpenAPI

````yaml /openapi/ppi/ppi.yaml post /ppi/wallet/debit/verify
openapi: 3.0.3
info:
  title: PPI Wallet API
  description: >-
    API for managing PPI (Prepaid Payment Instrument) wallets and sub-wallets,
    including credit and debit operations.
  version: 1.0.0
  contact:
    name: PPI Service Team
    email: support@cashfree.com
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
servers:
  - url: https://api.cashfree.com
    description: Production server.
  - url: https://sandbox.cashfree.com
    description: Sandbox server.
security:
  - XClientID: []
    XClientSecret: []
tags:
  - name: Wallet Management
    description: Operations related to PPI wallet management.
  - name: User Management
    description: Operations related to user management within the PPI system.
  - name: Beneficiary Management
    description: Operations related to beneficiary management for users.
  - name: KYC Management
    description: Operations related to KYC (Know Your Customer) management.
  - name: Transfers
    description: Operations related to transfer.
paths:
  /ppi/wallet/debit/verify:
    post:
      tags:
        - Wallet Management
      summary: Verify Debit Wallet
      description: >
        Completes a debit that requires OTP verification for `SMALL_PPI` or
        `FULL_KYC_PPI` sub-wallets. Call this endpoint after [Debit
        Wallet](/api-reference/prepaid-payment-instruments/wallet-management/debit-wallet)
        returns `OTP_GENERATED`. Submit the `debit_id` from that response and
        the OTP the end user received on the channels you configured in
        `auth.data.notification_modes`. On success, the debit status becomes
        `SUCCESS` and funds are debited. A maximum of three verification
        attempts is allowed per `debit_id`.
      operationId: verifyWalletDebitOtp
      parameters:
        - $ref: '#/components/parameters/global_x_api_version'
      requestBody:
        $ref: '#/components/requestBodies/VerifyWalletDebitOtpRequest'
      responses:
        '200':
          description: Success response for verifying a wallet debit OTP.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletDebitVerifyOtpResponse'
              examples:
                debit_verify_success_response:
                  $ref: '#/components/examples/debit_verify_success_response'
        '400':
          description: >-
            Bad request - Invalid OTP, expired OTP, validation failure, or
            attempts exhausted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StructuredErrorResponse'
              examples:
                otp_invalid:
                  $ref: '#/components/examples/debit_otp_invalid'
                otp_expired:
                  $ref: '#/components/examples/debit_otp_expired'
                otp_verification_exhausted:
                  $ref: '#/components/examples/debit_otp_verification_exhausted'
                debit_id_missing:
                  summary: Debit ID missing
                  value:
                    code: debit_id_missing
                    type: validation_error
                    message: debit_id is missing in the request
        '401':
          $ref: '#/components/responses/Response401'
        '403':
          $ref: '#/components/responses/Response403'
        '404':
          description: Not found - Debit not found or not awaiting OTP verification.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StructuredErrorResponse'
              examples:
                debitNotFound:
                  summary: Debit not found
                  value:
                    code: debit_id_not_found
                    type: validation_error
                    message: No debit found with the provided debit_id
        '409':
          description: Conflict - Debit already processed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StructuredErrorResponse'
              examples:
                duplicateDebit:
                  summary: Duplicate debit ID
                  value:
                    code: debit_id_already_exists
                    type: invalid_request_error
                    message: >-
                      Transaction with the same debit_id has already been
                      processed
        '422':
          description: Unprocessable Entity - Business rule validation failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StructuredErrorResponse'
              examples:
                dailyMaxDebitCountLimitExceeded:
                  summary: Daily debit count limit exceeded
                  value:
                    code: daily_max_debit_count_limit_exceeded
                    type: validation_error
                    message: daily debit count cannot exceed 3 for Gift ppi
                monthlyMaxDebitCountLimitExceeded:
                  summary: Monthly debit count limit exceeded
                  value:
                    code: monthly_max_debit_count_limit_exceeded
                    type: validation_error
                    message: monthly debit count cannot exceed 20 for Gift ppi
                yearlyMaxDebitCountLimitExceeded:
                  summary: Yearly debit count limit exceeded
                  value:
                    code: yearly_max_debit_count_limit_exceeded
                    type: validation_error
                    message: yearly debit count cannot exceed 100 for Gift ppi
                dailyMaxDebitAmountLimitExceeded:
                  summary: Daily total debit amount limit exceeded
                  value:
                    code: daily_max_debit_amount_limit_exceeded
                    type: validation_error
                    message: >-
                      daily total debit amount cannot exceed ₹10,000.00 for
                      Small ppi
                monthlyMaxDebitAmountLimitExceeded:
                  summary: Monthly total debit amount limit exceeded
                  value:
                    code: monthly_max_debit_amount_limit_exceeded
                    type: validation_error
                    message: >-
                      monthly total debit amount cannot exceed ₹10,000.00 for
                      Small ppi
                yearlyMaxDebitAmountLimitExceeded:
                  summary: Yearly total debit amount limit exceeded
                  value:
                    code: yearly_max_debit_amount_limit_exceeded
                    type: validation_error
                    message: >-
                      yearly total debit amount cannot exceed ₹1,20,000.00 for
                      Small ppi
                maxPerDebitLimitExceeded:
                  summary: Per debit amount limit exceeded
                  value:
                    code: max_per_debit_limit_exceeded
                    type: validation_error
                    message: per debit amount cannot exceed ₹10,000.00 for Gift ppi
        '429':
          $ref: '#/components/responses/Response429'
        '500':
          $ref: '#/components/responses/Response500'
components:
  parameters:
    global_x_api_version:
      description: API version to be used. Format is in YYYY-MM-DD.
      name: x-api-version
      in: header
      required: true
      schema:
        type: string
        default: '2025-11-01'
        example: '2025-11-01'
      example: '2025-11-01'
  requestBodies:
    VerifyWalletDebitOtpRequest:
      description: Request parameters to verify the OTP for a wallet debit request.
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalletDebitVerifyRequest'
          examples:
            verifyDebitOtp:
              summary: Verify debit OTP
              value:
                debit_id: DEBIT420984
                otp: '222113'
  schemas:
    WalletDebitVerifyOtpResponse:
      type: object
      properties:
        debit_id:
          type: string
          description: >-
            Unique identifier for the debit transaction, as provided by you
            during the debit request.
          example: DEBIT420984
        user_id:
          type: string
          description: >-
            Unique identifier for the user, as provided by you during PPI user
            creation.
          example: USER827364
        cf_debit_id:
          type: string
          description: Unique identifier for the debit transaction, generated by Cashfree.
          example: '8901234567890123456'
        wallet_id:
          type: string
          description: Primary wallet ID from which the amount was debited.
          example: WALLET936721
        sub_wallet:
          $ref: '#/components/schemas/SubWallet'
        status:
          type: string
          description: >-
            Status of the debit transaction after successful OTP verification
            (such as `SUCCESS`).
          example: SUCCESS
        amount:
          type: number
          format: double
          description: Amount that was debited.
          example: 600
        remarks:
          type: string
          description: Remarks for the debit transaction.
          example: Purchase of electronics item
        initiated_at:
          type: string
          format: date-time
          description: Timestamp when the debit transaction was initiated.
          example: '2025-07-28T10:30:00Z'
        processed_at:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when the debit transaction was processed.
          example: '2025-07-28T10:30:00Z'
        notes:
          $ref: '#/components/schemas/Notes'
    StructuredErrorResponse:
      type: object
      properties:
        type:
          type: string
          description: A broad category of the error.
          example: internal_error
        code:
          type: string
          description: A machine-readable error code specific to the issue.
          example: internal_server_error
        message:
          type: string
          description: >-
            A message providing more details about the error, dynamic based on
            the specific issue.
          example: Internal server error
    WalletDebitVerifyRequest:
      type: object
      required:
        - debit_id
        - otp
      properties:
        debit_id:
          type: string
          description: >
            Unique identifier for the debit transaction, as supplied when you
            created the debit via Debit Wallet (`debit_id` in that request).
          example: DEBIT420984
          minLength: 1
          maxLength: 50
        otp:
          type: string
          description: >
            One-time password received by the end user on the notification
            channels configured in `auth.data.notification_modes` on the
            original Debit Wallet request.
          example: '222113'
          minLength: 4
          maxLength: 10
    SubWallet:
      type: object
      properties:
        cf_sub_wallet_id:
          type: string
          description: >-
            Unique identifier for the sub-wallet provided in response while
            creating the wallet.
          example: '5432109876543210987'
        name:
          type: string
          description: Name for the sub-wallet.
          example: Gift Wallet
        type:
          type: string
          description: Type of the sub-wallet.
          example: GIFT_PPI
        status:
          type: string
          description: Status of the sub-wallet.
          example: ACTIVE
        balance:
          type: number
          format: double
          description: Current balance of the sub-wallet.
          example: 1500.75
        available_balance:
          type: number
          format: double
          description: Available balance in the sub-wallet.
          example: 1500.75
        funds_on_hold:
          type: number
          format: double
          description: Funds on hold in the sub-wallet.
          example: 0
    Notes:
      type: object
      description: >-
        Optional key-value pairs for any extra information. Keys and values must
        be strings.
      properties:
        example_key:
          type: string
          description: value of the note
          example: example_value
  examples:
    debit_verify_success_response:
      summary: OTP verified; debit completed
      value:
        debit_id: DEBIT420984
        user_id: USER827364
        cf_debit_id: '8901234567890123456'
        wallet_id: WALLET936721
        sub_wallet:
          cf_sub_wallet_id: '54252453468535350359'
          name: Small PPI Wallet
          type: SMALL_PPI
          status: ACTIVE
          balance: 9500.86
          available_balance: 1500.75
          funds_on_hold: 0
        status: SUCCESS
        amount: 600
        remarks: Purchase of electronics item
        initiated_at: '2025-07-28T10:30:00Z'
        processed_at: '2025-07-28T10:30:05Z'
        notes:
          example_key: example_value
    debit_otp_invalid:
      summary: Incorrect debit OTP
      value:
        code: otp_invalid
        type: validation_error
        message: The provided OTP is incorrect
    debit_otp_expired:
      summary: Expired debit OTP
      value:
        code: otp_expired
        type: validation_error
        message: The provided OTP has expired
    debit_otp_verification_exhausted:
      summary: Debit OTP verification attempts exhausted
      value:
        code: otp_verification_attempt_exhausted
        type: validation_error
        message: Maximum OTP verification attempts exceeded
  responses:
    Response401:
      description: Unauthorised - Invalid or missing authentication.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/StructuredErrorResponse'
          examples:
            invalidCredentials:
              summary: Invalid client credentials
              value:
                code: authentication_failed
                type: authentication_error
                message: Invalid client ID and client secret combination
    Response403:
      description: Forbidden - Access denied.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/StructuredErrorResponse'
          examples:
            ipNotWhitelisted:
              summary: IP not whitelisted
              value:
                code: ip_not_whitelisted
                type: authentication_error
                message: Authentication error (IP not whitelisted)
    Response429:
      description: Too Many Requests - Rate limit exceeded.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/StructuredErrorResponse'
          examples:
            internalError:
              summary: Internal server error
              value:
                code: too_many_requests_per_operation
                type: rate_limit_error
                message: Rate limit exceeded. Please try again after some time
    Response500:
      description: Internal server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/StructuredErrorResponse'
          examples:
            internalError:
              summary: Internal server error
              value:
                code: internal_server_error
                type: internal_error
                message: An internal error occurred while processing the request
  securitySchemes:
    XClientID:
      type: apiKey
      in: header
      name: x-client-id
      description: >-
        Your unique client identifier issued by Cashfree. You can find this in
        your [Merchant
        Dashboard](https://merchant.cashfree.com/merchants/landing?env=prod).
    XClientSecret:
      type: apiKey
      in: header
      name: x-client-secret
      description: >-
        The secret key associated with your client ID. Use this to authenticate
        your API requests. You can find this in your [Merchant
        Dashboard](https://merchant.cashfree.com/merchants/landing?env=prod).

````