> ## 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 transaction that requires OTP verification for SMALL_PPI or FULL_KYC_PPI sub-wallets. Use this endpoint after the [Debit Wallet API](/api-reference/prepaid-payment-instruments/wallet-management/debit-wallet) returns status_code: OTP_GENERATED. Pass the debit_id from that response along with the OTP received by the customer through the channels configured in auth.data.notification_modes. On successful verification, the API returns status: SUCCESS and status_code: SUCCESS, and the debit transaction is completed. Each debit_id supports a maximum of three OTP verification attempts.


<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 `status_code: OTP_GENERATED` for `SMALL_PPI` or `FULL_KYC_PPI` sub-wallets. The request accepts two fields: `debit_id` and `otp`.
</Note>

Refer to [Status and status-code reference](/api-reference/prepaid-payment-instruments/wallet-management/debit-status-descriptions#status-statuscode-mapping) for a comprehensive list of `status` and `status_code` combinations.

<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: Users
    description: Operations related to PPI users.
  - name: User KYC
    description: Operations related to user KYC verification.
  - name: Wallets
    description: Operations related to PPI wallets.
  - name: Beneficiaries
    description: Operations related to user beneficiaries.
  - name: Transfers
    description: Operations related to transfers.
paths:
  /ppi/wallet/debit/verify:
    post:
      tags:
        - Wallets
      summary: Verify Debit Wallet
      description: >
        Completes a debit transaction that requires OTP verification for
        SMALL_PPI or FULL_KYC_PPI sub-wallets. Use this endpoint after the
        [Debit Wallet
        API](/api-reference/prepaid-payment-instruments/wallet-management/debit-wallet)
        returns status_code: OTP_GENERATED. Pass the debit_id from that response
        along with the OTP received by the customer through the channels
        configured in auth.data.notification_modes. On successful verification,
        the API returns status: SUCCESS and status_code: SUCCESS, and the debit
        transaction is completed. Each debit_id supports a maximum of three OTP
        verification attempts.
      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:
      $ref: '#/components/schemas/WalletDebitResponse'
    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
    WalletDebitResponse:
      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'
        applied_gift_codes:
          type: array
          description: >-
            List of gift codes used in the transaction are applicable for GIFT
            type wallets.
          items:
            $ref: '#/components/schemas/AppliedGiftCode'
        status:
          type: string
          description: >
            Status of the debit transaction. Refer to [Debit status and
            status-code
            mapping](/api-reference/prepaid-payment-instruments/wallet-management/debit-status-descriptions#status-statuscode-mapping)
            for all valid combinations.


            - For `GIFT_PPI` and `CLOSED_LOOP_PPI` sub-wallets, `status` is
            `SUCCESS` when the debit completes in a single call.

            - For `SMALL_PPI` and `FULL_KYC_PPI` sub-wallets, the Debit Wallet
            API returns `status: PENDING` and `status_code: OTP_GENERATED` until
            you verify the OTP using the [Verify Debit
            Wallet](/api-reference/prepaid-payment-instruments/wallet-management/verify-debit-wallet)
            API, after which `status` and `status_code` become `SUCCESS`.
          enum:
            - PENDING
            - SUCCESS
            - FAILED
            - REJECTED
            - REVERSED
          example: SUCCESS
        status_code:
          type: string
          description: >
            Status code for detailed tracking of debit progress. Refer to [Debit
            status and status-code
            mapping](/api-reference/prepaid-payment-instruments/wallet-management/debit-status-descriptions#status-statuscode-mapping)
            for all valid combinations.
          enum:
            - PENDING
            - OTP_GENERATED
            - OTP_GENERATION_FAILED
            - LAST_OTP_ATTEMPT_FAILED
            - OTP_VERIFICATION_FAILED
            - OTP_EXPIRED
            - OTP_VERIFICATION_ATTEMPT_EXHAUSTED
            - SUCCESS
            - FAILED
            - REJECTED
            - REVERSED
          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. Returns null
            while the debit is awaiting OTP verification or is still in
            progress.
          example: '2025-07-28T10:30:00Z'
        notes:
          type: object
          description: |
            Optional key-value metadata for the debit transaction.
          properties:
            example_key:
              type: string
              example: example_value
        auth:
          description: >
            Present only when you sent `auth` in the Debit Wallet request body
            for an OTP flow (`SMALL_PPI` or `FULL_KYC_PPI`). Echoes the same
            `mode` and `data` you supplied. Omitted for single-step debits (such
            as `GIFT_PPI` or `CLOSED_LOOP_PPI`).
          allOf:
            - $ref: '#/components/schemas/WalletOtpVerificationAuth'
    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
    AppliedGiftCode:
      type: object
      properties:
        code:
          type: string
          description: Unique identifier for the gift code.
          example: GIFT-2025-XYZ133
        amount_debited:
          type: number
          format: double
          description: Amount debited from the gift code.
          example: 100
        value:
          type: number
          format: double
          description: Total Value of the gift code.
          example: 100
        expiry:
          type: string
          format: date-time
          description: Expiry date of the gift code.
          example: '2026-07-28T10:30:00Z'
    WalletOtpVerificationAuth:
      type: object
      description: >
        OTP verification payload. When `mode` is `OTP_VERIFICATION`, Cashfree
        sends an OTP using `data.notification_modes`.
      required:
        - mode
        - data
      properties:
        mode:
          type: string
          description: >-
            Authentication mode applied to this request. Only `OTP_VERIFICATION`
            is supported.
          enum:
            - OTP_VERIFICATION
          example: OTP_VERIFICATION
        data:
          type: object
          description: >-
            Configuration for the selected `mode`. Required when `mode` is
            `OTP_VERIFICATION`.
          required:
            - notification_modes
          properties:
            notification_modes:
              type: array
              description: >
                Channels used to deliver the OTP to the end user. Specify at
                least one value. For example, use `SMS` and `WHATSAPP` to send
                the OTP over both channels.
              minItems: 1
              items:
                type: string
                description: Delivery channel for the OTP.
                enum:
                  - SMS
                  - WHATSAPP
              example:
                - SMS
                - WHATSAPP
  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
        status_code: 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).

````