Vizo Digital Api
Sign in

Airtel CMS · Airtel CMS Services

Inbound Webhook Callback Listener

Webhook callback specifications for balance verification, debit, and transaction posting

POST request

URL: https://uat-api.vizodigital.com/api/v1/cms/airtel/callback

Body

{
    "action": "transaction_post",
    "merchantId": "3123456789",
    "amount": "100",
    "transactionId": "DEMOTRAN123",
    "billerId": "011023",
    "billerName": "TEST",
    "utr": "DEMO0101012",
    "mobile": "9829098290",
    "tranDateTime": "07-10-2024 04:47:01",
    "commission": "0.1",
    "otherFields": "",
    "description": "DEMODEMODEMO 12132123",
    "tranStatus": "Success"
}

Include a valid Bearer token with every request

Code sample

curl --location 'https://api.vizodigital.com/api/v1/cms/airtel/callback' \
  --header 'Authorization: Bearer <YOUR_API_TOKEN>' \
  --header 'X-Timestamp: 2026-10-30T11:25:06' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --data '{
    "action": "transaction_post",
    "merchantId": "3123456789",
    "amount": "100",
    "transactionId": "DEMOTRAN123",
    "billerId": "011023",
    "billerName": "TEST",
    "utr": "DEMO0101012",
    "mobile": "9829098290",
    "tranDateTime": "07-10-2024 04:47:01",
    "commission": "0.1",
    "otherFields": "",
    "description": "DEMODEMODEMO 12132123",
    "tranStatus": "Success"
}'
<?php

$client = new \GuzzleHttp\Client();
$response = $client->post('https://api.vizodigital.com/api/v1/cms/airtel/callback', [
    'headers' => [
        'Authorization' => 'Bearer <YOUR_API_TOKEN>',
        'X-Timestamp' => '2026-10-30T11:25:06',
        'Content-Type' => 'application/json',
        'Accept' => 'application/json',
    ],
    'json' => array (
  'action' => 'transaction_post',
  'merchantId' => '3123456789',
  'amount' => '100',
  'transactionId' => 'DEMOTRAN123',
  'billerId' => '011023',
  'billerName' => 'TEST',
  'utr' => 'DEMO0101012',
  'mobile' => '9829098290',
  'tranDateTime' => '07-10-2024 04:47:01',
  'commission' => '0.1',
  'otherFields' => '',
  'description' => 'DEMODEMODEMO 12132123',
  'tranStatus' => 'Success',
),
]);

echo $response->getBody();
import requests

url = 'https://api.vizodigital.com/api/v1/cms/airtel/callback'
headers = {
    'Authorization': 'Bearer <YOUR_API_TOKEN>',
    'X-Timestamp': '2026-10-30T11:25:06',
    'Content-Type': 'application/json',
    'Accept': 'application/json'
}
payload = {
    "action": "transaction_post",
    "merchantId": "3123456789",
    "amount": "100",
    "transactionId": "DEMOTRAN123",
    "billerId": "011023",
    "billerName": "TEST",
    "utr": "DEMO0101012",
    "mobile": "9829098290",
    "tranDateTime": "07-10-2024 04:47:01",
    "commission": "0.1",
    "otherFields": "",
    "description": "DEMODEMODEMO 12132123",
    "tranStatus": "Success"
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())
const axios = require('axios');

axios.post('https://api.vizodigital.com/api/v1/cms/airtel/callback', {"action":"transaction_post","merchantId":"3123456789","amount":"100","transactionId":"DEMOTRAN123","billerId":"011023","billerName":"TEST","utr":"DEMO0101012","mobile":"9829098290","tranDateTime":"07-10-2024 04:47:01","commission":"0.1","otherFields":"","description":"DEMODEMODEMO 12132123","tranStatus":"Success"}, {
  headers: {
    'Authorization': 'Bearer <YOUR_API_TOKEN>',
    'X-Timestamp': '2026-10-30T11:25:06',
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  }
})
.then(res => console.log(res.data))
.catch(err => console.error(err));

Success Example

{
    "status": "1",
    "message": "Transaction Posting Successful"
}

Failure response

{
    "status": "error",
    "message": "Request failed. Check credentials, wallet balance, or validation errors."
}

Overview

Airtel CMS – Client Callback Responses

During the Airtel CMS transaction process, the system sends three types of callback requests to the client’s callback URL:

POST https://api.vizodigital.com/api/v1/cms/airtel/callback

⚠️ Important Callback Implementation Notes

  • HTTPS Endpoint: A valid HTTPS Callback URL is required to receive and handle the final transaction response.
  • POST Method: The callback should be capable of accepting POST responses containing transaction status and details.
  • Valid JSON Response: The client must respond in valid JSON format.
  • Status Field: The status field accepts only "0" (Fail) or "1" (Success).
  • String Format Rule: In the JSON request and response, all fields must be strings.
  • 15-Minute Posting Timing: For transaction_post (Final Callback), client callback data will be received within 15 minutes after the transaction.
  • Acknowledgment Responsibility: The client is fully responsible for any successful (status = "1") acknowledgment sent.

1. Balance Check (action: "balance_check")

Purpose: To verify whether the client/merchant has sufficient balance before initiating a transaction.

Field Type Description Example
action string Always "balance_check" "balance_check"
merchantId string 10-digit numeric Merchant ID "123456789"
amount string Transaction amount as string "100"
transactionId string Unique transaction ID "DEMOTRAN123"

Client Response:

{
  "status": "1",
  "message": "Success"
}

2. Balance Check Debit (action: "balance_check_debit")

Purpose: Debit the merchant’s account with the specified transaction amount.

Field Type Description Example
action string Always "balance_check_debit" "balance_check_debit"
merchantId string 10-digit numeric Merchant ID "123456789"
amount string Transaction amount to debit "100"
transactionId string Unique transaction ID "DEMOTRAN123"
billerId string Biller ID selected by customer "011023"
billerName string Biller name "TEST"
mobile string Customer mobile number "9829098290"

Client Response:

{
  "status": "1",
  "message": "Amount Debit Successful"
}

3. Transaction Post (Final Callback) (action: "transaction_post")

Purpose: Indicates that the final transaction posting process has been completed.

Field Type Description Example
action string Always "transaction_post" "transaction_post"
merchantId string 10-digit numeric Merchant ID "3123456789"
amount string Collected amount "100"
transactionId string Unique transaction identifier "DEMOTRAN123"
billerId string Biller ID "011023"
billerName string Biller organization name "TEST"
utr string Bank UTR reference number "DEMO0101012"
mobile string Customer mobile number "9829098290"
tranDateTime string Bank transaction date & time "07-10-2024 04:47:01"
commission string Retailer commission "0.1"
otherFields string Additional metadata ""
description string Description or status remarks "DEMODEMODEMO 12132123"
tranStatus string Final status: Success or Failed "Success"

Client Response:

{
  "status": "1",
  "message": "Transaction Posting Successful"
}

Headers

  • Authorization · string required

    An authentication token required for the request (Sanctum Bearer Token or Noble API token).

    Example: Bearer <YOUR_API_TOKEN>

  • X-Timestamp · string required

    Generated at the time of request, with skew time of 15 seconds (must be in format yyyy-MM-ddTHH:mm:ss).

    Example: 2024-10-20T21:27:09

  • Content-Type · string required

    Request content-type. Only application/json is allowed.

    Example: application/json

  • Accept · string required

    Response content-type. Must be application/json.

    Example: application/json

Body

application/json required

JSON payload for Inbound Webhook Callback Listener

Schema

{
    "type": "object",
    "required": [
        "action",
        "merchantId",
        "amount",
        "transactionId"
    ],
    "properties": {
        "action": {
            "type": "string",
            "description": "Callback action: balance_check, balance_check_debit, or transaction_post",
            "example": "transaction_post"
        },
        "merchantId": {
            "type": "string",
            "description": "10-digit numeric Merchant ID",
            "example": "3123456789"
        },
        "amount": {
            "type": "string",
            "description": "Transaction cash amount as string",
            "example": "100"
        },
        "transactionId": {
            "type": "string",
            "description": "Unique transaction identifier",
            "example": "DEMOTRAN123"
        },
        "billerId": {
            "type": "string",
            "description": "Biller ID (present in debit & post callbacks)",
            "example": "011023"
        },
        "billerName": {
            "type": "string",
            "description": "Biller organization name",
            "example": "TEST"
        },
        "utr": {
            "type": "string",
            "description": "Bank UTR reference number",
            "example": "DEMO0101012"
        },
        "mobile": {
            "type": "string",
            "description": "Depositor customer mobile number",
            "example": "9829098290"
        },
        "tranDateTime": {
            "type": "string",
            "description": "Transaction date & time string",
            "example": "07-10-2024 04:47:01"
        },
        "commission": {
            "type": "string",
            "description": "Retailer commission earned",
            "example": "0.1"
        },
        "tranStatus": {
            "type": "string",
            "description": "Final status: Success or Failed",
            "example": "Success"
        }
    }
}

Example

{
    "action": "transaction_post",
    "merchantId": "3123456789",
    "amount": "100",
    "transactionId": "DEMOTRAN123",
    "billerId": "011023",
    "billerName": "TEST",
    "utr": "DEMO0101012",
    "mobile": "9829098290",
    "tranDateTime": "07-10-2024 04:47:01",
    "commission": "0.1",
    "otherFields": "",
    "description": "DEMODEMODEMO 12132123",
    "tranStatus": "Success"
}

Responses

  • 200 · application/json default

    Webhook callback acknowledgment response.

    Example

    {
        "status": "1",
        "message": "Transaction Posting Successful"
    }
  • 200 · application/json

    Callback failure acknowledgment

    Example

    {
        "status": "0",
        "message": "Transaction Posting Failed"
    }

Errors

  • IR0001 · HTTP 400

    Invalid Request: Malformed or invalid request body. Check syntax and required fields.

    Invalid Request: Malformed or invalid request body. Check syntax and required fields.

    {
        "status": 0,
        "statusCode": "IR0001",
        "message": "Invalid Request: Malformed or invalid request body. Check syntax and required fields."
    }
  • PM0002 · HTTP 422

    Parameter Missing: Required parameter is missing.

    Parameter Missing: Required parameter is missing.

    {
        "status": 0,
        "statusCode": "PM0002",
        "message": "Parameter Missing: Required parameter is missing."
    }
  • VF0003 · HTTP 422

    Validation Failed: Input validation failed.

    Validation Failed: Input validation failed.

    {
        "status": 0,
        "statusCode": "VF0003",
        "message": "Validation Failed: Input validation failed."
    }
  • IE0004 · HTTP 404

    Invalid Api Endpoint: Endpoint not found.

    Invalid Api Endpoint: Endpoint not found.

    {
        "status": 0,
        "statusCode": "IE0004",
        "message": "Invalid Api Endpoint: Endpoint not found."
    }
  • IC0007 · HTTP 401

    Invalid Credentials: Authentication failed.

    Invalid Credentials: Authentication failed.

    {
        "status": 0,
        "statusCode": "IC0007",
        "message": "Invalid Credentials: Authentication failed."
    }
  • SE0006 · HTTP 500

    Internal Server Error: Server is down. Please try again later.

    Internal Server Error: Server is down. Please try again later.

    {
        "status": 0,
        "statusCode": "SE0006",
        "message": "Internal Server Error: Server is down. Please try again later."
    }
  • AE0021 · HTTP 400

    Invalid Header: Header validation failed.

    Invalid Header: Header validation failed.

    {
        "status": 0,
        "statusCode": "AE0021",
        "message": "Invalid Header: Header validation failed."
    }
  • AE0022 · HTTP 429

    Authentication Error: Rate limit exceeded. Please try again later.

    Authentication Error: Rate limit exceeded. Please try again later.

    {
        "status": 0,
        "statusCode": "AE0022",
        "message": "Authentication Error: Rate limit exceeded. Please try again later."
    }
  • AE0024 · HTTP 400

    Authentication Error: Invalid timestamp format (must be yyyy-MM-ddTHH:mm:ss).

    Authentication Error: Invalid timestamp format (must be yyyy-MM-ddTHH:mm:ss).

    {
        "status": 0,
        "statusCode": "AE0024",
        "message": "Authentication Error: Invalid timestamp format (must be yyyy-MM-ddTHH:mm:ss)."
    }
  • AE0026 · HTTP 401

    Authentication Error: Header Token is invalid or inactive.

    Authentication Error: Header Token is invalid or inactive.

    {
        "status": 0,
        "statusCode": "AE0026",
        "message": "Authentication Error: Header Token is invalid or inactive."
    }
  • AE0028 · HTTP 403

    Authentication Error: IP address not allowed.

    Authentication Error: IP address not allowed.

    {
        "status": 0,
        "statusCode": "AE0028",
        "message": "Authentication Error: IP address not allowed."
    }
  • AC0001 · HTTP 200

    Success: Transaction processed successfully.

    Success: Transaction processed successfully.

    {
        "status": 1,
        "statusCode": "AC0001",
        "message": "Success: Transaction processed successfully."
    }
  • AC0002 · HTTP 422

    Failed: Transaction failed downstream with Airtel Bank.

    Failed: Transaction failed downstream with Airtel Bank.

    {
        "status": 0,
        "statusCode": "AC0002",
        "message": "Failed: Transaction failed downstream with Airtel Bank."
    }
  • AC0003 · HTTP 500

    Error: System error or partner connectivity failure.

    Error: System error or partner connectivity failure.

    {
        "status": 0,
        "statusCode": "AC0003",
        "message": "Error: System error or partner connectivity failure."
    }
  • APB_000 · HTTP 200

    Success: Ideal success code in all scenarios.

    Success: Ideal success code in all scenarios.

    {
        "status": 1,
        "statusCode": "APB_000",
        "message": "Success: Ideal success code in all scenarios."
    }
  • APB_001 · HTTP 422

    Form Data not found (Biller is not configured in the system).

    Form Data not found (Biller is not configured in the system).

    {
        "status": 0,
        "statusCode": "APB_001",
        "message": "Form Data not found (Biller is not configured in the system)."
    }
  • APB_002 · HTTP 422

    Insufficient balance in account, please add funds and try again.

    Insufficient balance in account, please add funds and try again.

    {
        "status": 0,
        "statusCode": "APB_002",
        "message": "Insufficient balance in account, please add funds and try again."
    }
  • APB_004 · HTTP 422

    Amount cannot be credited as account exceeds maximum balance limit.

    Amount cannot be credited as account exceeds maximum balance limit.

    {
        "status": 0,
        "statusCode": "APB_004",
        "message": "Amount cannot be credited as account exceeds maximum balance limit."
    }
  • APB_006 · HTTP 422

    Credit freeze on account, ask beneficiary to contact bank.

    Credit freeze on account, ask beneficiary to contact bank.

    {
        "status": 0,
        "statusCode": "APB_006",
        "message": "Credit freeze on account, ask beneficiary to contact bank."
    }
  • APB_010 · HTTP 422

    Either debit or credit account is closed.

    Either debit or credit account is closed.

    {
        "status": 0,
        "statusCode": "APB_010",
        "message": "Either debit or credit account is closed."
    }
  • APB_011 · HTTP 422

    Transaction could not be processed as Credit account is blocked.

    Transaction could not be processed as Credit account is blocked.

    {
        "status": 0,
        "statusCode": "APB_011",
        "message": "Transaction could not be processed as Credit account is blocked."
    }
  • APB_042 · HTTP 422

    Permissible daily transaction amount has exceeded.

    Permissible daily transaction amount has exceeded.

    {
        "status": 0,
        "statusCode": "APB_042",
        "message": "Permissible daily transaction amount has exceeded."
    }
  • APB_043 · HTTP 202

    Transaction pending. Deposited amount will be credited against ID.

    Transaction pending. Deposited amount will be credited against ID.

    {
        "status": 1,
        "statusCode": "APB_043",
        "message": "Transaction pending. Deposited amount will be credited against ID."
    }
  • APB_111 · HTTP 422

    Default failure code: Partner Not Found or Partner status is inactive.

    Default failure code: Partner Not Found or Partner status is inactive.

    {
        "status": 0,
        "statusCode": "APB_111",
        "message": "Default failure code: Partner Not Found or Partner status is inactive."
    }
  • APB_112 · HTTP 422

    Txn failed due to duplicate request, please retry with fresh ID.

    Txn failed due to duplicate request, please retry with fresh ID.

    {
        "status": 0,
        "statusCode": "APB_112",
        "message": "Txn failed due to duplicate request, please retry with fresh ID."
    }
  • APB_121 · HTTP 422

    No such transaction exists in system, please retry.

    No such transaction exists in system, please retry.

    {
        "status": 0,
        "statusCode": "APB_121",
        "message": "No such transaction exists in system, please retry."
    }
  • APB_182 · HTTP 422

    Balance not found for corresponding COD account.

    Balance not found for corresponding COD account.

    {
        "status": 0,
        "statusCode": "APB_182",
        "message": "Balance not found for corresponding COD account."
    }
  • APB_183 · HTTP 422

    Account details not found.

    Account details not found.

    {
        "status": 0,
        "statusCode": "APB_183",
        "message": "Account details not found."
    }

Notes

🔄 Airtel CMS 4-Step Transaction Flow

  1. Start Transaction: Call /api/v1/cms/airtel/start with merchantId and transactionId to receive the official Airtel Bank Plugin redirection URL.
  2. Enter Details & Generate OTP: Retailer opens the redirection URL and enters biller, depositor mobile, and cash amount.
  3. OTP Verification & Balance Check: Retailer enters OTP; Airtel triggers balance_check and balance_check_debit webhook callbacks.
  4. Transaction Posting: Once completed, Airtel sends transaction_post callback (delivered within 15 minutes) and retailer commission is credited.

💰 Real-Time Wallet Balance, Commission & Auto-Refund

  • Zero Surcharge: No fee or surcharge is charged to the retailer or customer on cash collections.
  • Retailer Commission: The retailer earns a commission on each successfully settled transaction, credited automatically to their primary wallet.
  • Atomic Debit: Your wallet is atomically debited for the exact collection amount when Airtel issues the balance_check_debit callback.
  • Instant Auto-Refund: If the transaction fails downstream (Status Failed or provider decline), your wallet is 100% automatically refunded.

🔔 Inbound Callback Contract

  • In every callback request and response, all fields must be strings.
  • The status field accepts only "1" (Success) or "0" (Fail).
  • Always maintain a stable HTTPS callback listener and respond promptly with valid JSON.

Rate Limits

60/min