Developer Documentation

Everything you need to integrate iPayBD payments into your application.

Overview

i

What is iPayBD?

iPayBD is a powerful Instant Automatic Deposit and Withdrawal Solution designed for merchants, small businesses, and platform developers. It enables seamless and automated fund transfers between your application and customer wallets through mobile banking services.

Instant Collection via bKash, Nagad, Rocket, Upay
Automated Withdrawals to customer wallets
Real-Time Validation of transaction data
JSON API with HTTP request/response
Webhook Support for instant notifications

Architecture Overview

Client Side

Secure collection of payment details using our API

Server Side

Payment processing and transaction management via API

Webhooks

Real-time notifications for payment events

Integration Process

1

Account Setup

Create an account and get your API keys

2

Integration

Implement payment flow using our APIs

3

Testing

Test integration using test API keys

4

Go Live

Switch to production keys and start accepting payments

Getting Started

Follow these steps to start accepting payments with iPayBD.

Base URL

ipaybd.net

1. Get Your API Keys

X-Authorization="pk_test_123..."
X-Authorization-Secret="sk_test_456..."

2. Check Merchant Balance

GET

Use this endpoint to retrieve the current wallet balance and available balance for your merchant account using your API keys.

GET (v1) https://ipaybd.net/api/v1/payment/balance
GET (v2) https://ipaybd.net/api/v2/payment/balance

cURL Request Example

curl -X GET "https://ipaybd.net/api/v1/payment/balance" \
  -H "X-Authorization: pk_test_123..." \
  -H "X-Authorization-Secret: sk_test_456..." \
  -H "Accept: application/json"

Request Headers

Header Required Description
X-Authorization Required Your API Public Key.
X-Authorization-Secret Required Your API Secret Key.

Response Examples

{
    "status": "success",
    "message": "Merchant balance retrieved successfully",
    "data": {
        "username": "merchant62",
        "fullname": "John Doe",
        "company_name": "Merchant Co",
        "merchant_type": "general",
        "balance": 15000.0,
        "available_balance": 14500.0,
        "currency": "BDT",
        "status": "active"
    }
}
{
    "message": "Unauthorized: Invalid API credentials."
}

Response Field Details

Field Type Description
statusstringRequest status (success).
data.usernamestringMerchant account username.
data.fullnamestringMerchant full name.
data.company_namestringRegistered business/company name.
data.merchant_typestringMerchant category (general or sub_merchant).
data.balancenumericTotal account balance in wallet.
data.available_balancenumericUsable balance available for withdrawals and operations.
data.currencystringWallet currency code (e.g. BDT).
data.statusstringAccount status: active or block.

Checkout

Checkout allows you to skip the payment method selection page by specifying deposit_method and type in your Create Payment request. The customer will be redirected directly to the transaction input page for the specified payment method.

POST /api/v1/payment/create-payment
Crucial: Actual Received Amount in Webhook
Important

If a customer transfers an amount different from what was initiated in your Create Payment request, the gateway webhook will deliver the actual received amount rather than the requested figure.

Initiated Amount: 500 BDT
Customer Sends: 300 BDT or 700 BDT
Webhook Receives: amount: 300 or 700

Always check and verify the received amount in the webhook payload before crediting your customer or fulfilling orders.

Request Parameters

Property Type Example Mandatory Definition
amount numeric 1100 yes The payment amount.
reference string (3–20) inv_smart_001 yes Your unique invoice/tracking ID. Must be unique per merchant.
currency string BDT yes Always pass BDT.
callback_url url https://example.com/callback yes A valid URL where the customer is redirected after a successful/failed payment.
webhook_url url https://example.com/webhook no Server-to-server URL that receives the final payment status. See the Webhook section.
cust_name string Jhon yes Customer name.
cust_phone string +8801711XXYYZZ no Customer phone number.
deposit_method string bkash nagad rocket upay yes MFS operator name. Must be sent together with type.
type string P2A yes Transaction type — P2A (Cash Out). Must be sent together with deposit_method.

Example Request

curl -X POST "https://ipaybd.net/api/v1/payment/create-payment" \
                    -H "X-Authorization: pk_test_123..." \
                    -H "X-Authorization-Secret: sk_test_456..." \
                    -H "Content-Type: application/json" \
                    -d '{
                        "amount": "1100",
                        "reference": "inv_smart_001",
                        "currency": "BDT",
                        "callback_url": "https://example.com/callback",
                        "webhook_url": "https://example.com/webhook",
                        "cust_name": "Jhon",
                        "deposit_method": "bkash",
                        "type": "P2A",
                    }'
$curl = curl_init();

                    curl_setopt_array($curl, array(
                        CURLOPT_URL => "https://ipaybd.net/api/v1/payment/create-payment",
                        CURLOPT_RETURNTRANSFER => true,
                        CURLOPT_HTTPHEADER => array(
                            "X-Authorization: pk_test_123...",
                            "X-Authorization-Secret: sk_test_456...",
                            "Content-Type: application/json"
                        ),
                        CURLOPT_POSTFIELDS => '{
                            "amount": "1100",
                            "reference": "inv_smart_001",
                            "currency": "BDT",
                            "callback_url": "https://example.com/callback",
                            "webhook_url": "https://example.com/webhook",
                            "cust_name": "Jhon",
                            "deposit_method": "bkash",
                            "type": "P2A",
                        }'
                    ));

                    $response = curl_exec($curl);
                    curl_close($curl);
                    echo $response;
import requests

                    url = "https://ipaybd.net/api/v1/payment/create-payment"
                    headers = {
                        "X-Authorization": "pk_test_123...",
                        "X-Authorization-Secret": "sk_test_456...",
                        "Content-Type": "application/json"
                    }
                    payload = {
                        "amount": "1100",
                        "reference": "inv_smart_001",
                        "currency": "BDT",
                        "callback_url": "https://example.com/callback",
                        "webhook_url": "https://example.com/webhook",
                        "cust_name": "Jhon",
                        "deposit_method": "bkash",
                        "type": "P2A",
                    }

                    response = requests.post(url, json=payload, headers=headers)
                    print(response.json())
const url = "https://ipaybd.net/api/v1/payment/create-payment";
                    const headers = {
                        "X-Authorization": "pk_test_123...",
                        "X-Authorization-Secret": "sk_test_456...",
                        "Content-Type": "application/json"
                    };
                    const payload = {
                        amount: "1100",
                        reference: "inv_smart_001",
                        currency: "BDT",
                        callback_url: "https://example.com/callback",
                        webhook_url: "https://example.com/webhook",
                        cust_name: "Jhon",
                        deposit_method: "bkash",
                        type: "P2A",
                    };

                    fetch(url, {
                        method: "POST",
                        headers: headers,
                        body: JSON.stringify(payload)
                    })
                    .then(response => response.json())
                    .then(data => console.log(data))
                    .catch(error => console.error(error));

Important Notes

  • Both deposit_method and type must be provided together. Sending only one will be ignored.
  • If the specified method is not available at the time of checkout, the customer will see the standard payment method selection page instead.
  • If the customer transfers an amount different from the requested amount (e.g. sending 300 or 700 BDT instead of 500 BDT), the webhook will return the actual received amount. Always verify the received amount before fulfilling the order.
  • The response format is identical to the standard Create Payment response — only the checkout behavior changes.

Response Examples

{
    "success": true,
    "message": "Payment request created successfully",
    "data": {
        "request_id": "c05a584911240b30f525041959c5c38540fdd5f34639b214b9",
        "amount": "100",
        "reference": "5w21rm54e4FD",
        "currency": "BDT",
        "issue_time": "2025-03-06 23:54:44",
        "payment_url": "https://ipaybd.net/checkout/c05a584911240b30f525041959c5c38540fdd5f34639b214b9?expires=1741319684&signature=6294408b326cf940cad20816cda5aa96c234fcabfeef49d013be6e6daeb9514e"
    }
}
{
    "success": false,
    "code": 403,
    "message": "not authorized"
}
{
    "success": false,
    "message": "Data validation error",
    "data": {
        "reference": [
            "Duplicate reference-id iuy8767jyLKgJDKgFfJ"
        ]
    }
}
{
    "success": false,
    "message": "Data validation error",
    "data": {
        "amount": [
            "The amount field is required."
        ],
        "reference": [
            "The reference field is required."
        ]
    }
}
{
    "success": false,
    "message": "Data validation error",
    "data": {
        "amount": [
            "The amount field must be a number."
        ]
    }
}
===========Payment Callback Handler===========
 Handle callback URL parameters
 Sample Success URL:
 http://127.0.0.1:5500/?payment=success&payment_method=rocket&
request_id=7dc7ae27c564e9bffcc72d3d3f10fc69b50998fe24ff0cd566&reference
=ref_usx60cisvas8886&sim_id=01893087273&trxid=DR123456&amount=50

 Sample Cancel URL:
 http://127.0.0.1:5500/?payment=Cancelled

 Status codes:
 payment = success
 payment = rejected
 payment = Cancelled
 payment = pending

 

Webhook

POST

The Payment Webhook lets you receive the final status of a payment automatically, so you don't have to poll the Track Payment Status endpoint. When a payment is completed or rejected, the system sends a POST request in JSON format to the webhook_url (and/or callback_url) you provided when creating the payment.

How It Works

1

Create Payment

Include webhook_url in your Checkout / Create Payment request.

2

Status Changes

Payment is processed and status changes to completed or rejected.

3

Receive Notification

System sends a POST request with final payment data to your webhook URL.

Sample Webhook Payload

The following JSON payload is sent as a POST request to your webhook_url:

{
    "status": "true",
    "signature": "6294408b326cf940cad20816cda5aa96c234fcabfeef49d013be6e6daeb9514e",
    "data": {
        "request_id": "c05a584911240b30f525041959c5c38540fdd5f34639b214b9",
        "amount": 50,
        "payment_method": "bkash",
        "reference": "Rvx99sS99",
        "cust_name": "Jhon",
        "cust_phone": "+8801712345678",
        "note": null,
        "reject_msg": null,
        "payment_method_trx": "01JYG4GET7",
        "status": "1",
        "status_name": "completed"
    }
}

Key Fields

  • signature — SHA-256 HMAC signature of the data object, generated using your secret key.
  • data.reference — your unique reference ID; use this to match the webhook with your order.
  • data.status_name — completed or rejected.
  • data.status — numeric code: 1/2 = completed, 3 = rejected.
  • data.payment_method_trx — MFS-side transaction ID (for completed payments).
  • data.reject_msg — rejection reason (for rejected payments).

See the full field reference and handler example in the Webhook section of the H2H Payment API — the payload format and behavior are identical.

Important Notes

  • Webhooks are only sent for completed and rejected payments. Pending payments do not trigger webhooks.
  • Your endpoint must respond with HTTP 200 within 10 seconds to acknowledge receipt.
  • Always verify the reference and amount in the webhook against your records before updating order status.
  • If the webhook is missed or fails, you can always fetch the current status via the Track Payment Status endpoint below.

Track Payment Status

Use this endpoint to track the status of a payment using the referenceId. The response will include details about the payment, such as its status, amount, and customer information.

cURL Request Example

curl -X GET "https://ipaybd.net/api/v1/payment/track-status/REF12345" \
                    -H "X-Authorization: pk_test_123..." \
                    -H "X-Authorization-Secret: sk_test_456..."

Response Examples

Below are examples of the responses you might receive when calling this endpoint:

If the payment is found, the response will include the payment details and status information.

{
    "status": "true",
    "data": {
        "request_id": "12345",
        "amount": "100.00",
        "payment_method": "credit_card",
        "reference": "REF12345",
        "cust_name": "John Doe",
        "cust_phone": "+1234567890",
        "note": "Test payment",
        "reject_msg": null,
        "payment_method_trx": "trx_67890",
        "status": "pending" // pending, rejected, completed
    }
}

Details about the possible statuses: pending, completed, rejected.

If the payment is not found or the referenceId is invalid, the response will indicate the error.

{
    "status": "false",
    "message": "Data Not found"
}

Response Field Details

Here's a breakdown of the fields in the response:

Field Type Description
statusstringIndicates whether the request was successful (true) or not (false).
dataobjectContains the payment details if the request is successful.
request_idstringThe unique ID of the payment request.
amountnumericThe amount of the payment.
payment_methodstringThe payment method used (e.g., credit_card).
referencestringThe reference ID provided during payment creation.
cust_namestringThe name of the customer.
cust_phonestringThe phone number of the customer.
notestringAdditional notes provided during payment creation.
reject_msgstringThe rejection message, if the payment was rejected.
payment_method_trxstringThe transaction ID from the payment method.
StatusstringDetails about the possible statuses (e.g., pending, Completed, Rejected).
v2 Host-to-Host

H2H Payment API

A white-label payment gateway that lets you build your own branded checkout — no redirects, full control.

White-Label Payment Gateway

H2H (Host-to-Host) Payment API is a white-label payment gateway system that allows you to build your own custom payment checkout page under your own branding. Instead of redirecting customers to a third-party checkout, you have full control over the payment UI and user experience within your own platform.

Introduction

With the H2H Payment API, merchants integrate directly via server-to-server communication with mobile financial services such as bKash, Nagad, Rocket, and Upay. You design and host your own checkout page — iPaybd handles the payment processing behind the scenes.

Payment Flow

1

Check Available Methods

Query the Available Methods API to see which payment methods are currently active in the system.

2

User Chooses a Method

The user selects a preferred payment method (e.g., bKash, Nagad, Rocket, Upay) and a deposit number from the list.

3

Send Payment Request

Submit a payment request including the method, deposit number, amount, reference ID, and callback URL.

4

System Creates Payment

The system validates the request, creates a payment record, and returns the status with callback & webhook URLs.

iPaybd provides a unique deposit number for each merchant, which can be displayed inside the merchant's custom checkout page or application — giving customers a seamless, fully branded payment experience.


Get Available Payment Methods

GET

Retrieve a list of available payment methods (MFS operators) along with their associated SIM numbers and icons. Requires authentication via X-Authorization and X-Authorization-Secret headers.

GET https://ipaybd.net/api/v2/payment/available-method

cURL Example

curl -X GET "https://ipaybd.net/api/v2/payment/available-method" \
  -H "X-Authorization: pk_test_123..." \
  -H "X-Authorization-Secret: sk_test_456..."

Request Headers

Header Required Description
X-Authorization Required Your API public key for authentication.
X-Authorization-Secret Required Your API secret key for authentication.

Success Response

Returns a list of available payment methods with their SIM numbers and icons.

[
    {
        "deposit_method": "nagad",
        "deposit_number": "018xxx33742",
        "icon": "https://ibotbd.com/payments/nagad.png",
        "type": "P2C"
    },
    {
        "deposit_method": "upay",
        "deposit_number": "0132xxx6627",
        "icon": "https://ibotbd.com/payments/upay.png",
        "type": "P2A"
    },
    {
        "deposit_method": "bkash",
        "deposit_number": "0163xxx9900",
        "icon": "https://ibotbd.com/payments/bkash.png",
        "type": "P2C"
    },
    {
        "deposit_method": "rocket",
        "deposit_number": "01xxx8164207",
        "icon": "https://ibotbd.com/payments/rocket.png",
        "type": "P2C"
    }
]

Response Fields

Field Type Description
deposit_method string Name of the payment method (e.g., bkash, nagad).
deposit_number string The SIM number associated with the payment method.
icon string URL of the icon representing the payment method.
type string Payment type — P2A (Partner to Customer) or P2A (Partner to Agent).

Create Payment

POST

Create a payment request using the v2 API. Requires authentication via X-Authorization and X-Authorization-Secret headers. The payment will be processed based on the provided amount, method, and customer details.

POST https://ipaybd.net/api/v2/payment/create-payment
Crucial: Actual Received Amount in Webhook
Important

If a customer transfers an amount different from what was initiated in your Create Payment request, the gateway webhook will deliver the actual received amount rather than the requested figure.

Initiated Amount: 500 BDT
Customer Sends: 300 BDT or 700 BDT
Webhook Receives: amount: 300 or 700

Always check and verify the received amount in the webhook payload before crediting your customer or fulfilling orders.

cURL Examples

curl -X POST "https://ipaybd.net/api/v2/payment/create-payment" \
  -H "X-Authorization: pk_test_123..." \
  -H "X-Authorization-Secret: sk_test_456..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 50,
    "reference": "Rvx99sS99",
    "currency": "BDT",
    "callback_url": "https://example.com/callback",
    "webhook_url": "https://example.com/webhook",
    "transaction_id": "01JYG4GET7",
    "from_number": "01712345678",
    "payment_method": "rocket",
    "deposit_number": "013358164207",
    "type": "P2A"
  }'
curl -X POST "https://ipaybd.net/api/v2/payment/create-payment" \
  -H "X-Authorization: pk_test_123..." \
  -H "X-Authorization-Secret: sk_test_456..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 50,
    "reference": "Rvx99sS99",
    "currency": "BDT",
    "callback_url": "https://example.com/callback",
    "webhook_url": "https://example.com/webhook",
    "payment_method": "bkash",
    "deposit_number": "013358164207",
    "type": "P2C"
  }'

Request Headers

Header Required Description
X-Authorization Required Your API public key for authentication.
X-Authorization-Secret Required Your API secret key for authentication.
Content-Type Required application/json

Request Parameters

Field Type Required Description
amount numeric Required The amount of the payment.
reference string Required A unique reference ID for the payment (3–20 characters).
currency string Required Currency code (e.g., BDT).
callback_url string Required URL to receive payment status updates.
transaction_id string P2A Only A unique transaction ID (8–10 alphanumeric characters).
from_number string P2A Only The sender's phone number.
payment_method string Required Payment method operator: bkash, nagad, rocket, or upay. Aliases: deposit_method, method.
deposit_number string Required The SIM number associated with the payment method.
type string Required Transaction type: P2A (Partner to Agent), P2C (Partner to Customer), or P2P (Partner to Partner).
webhook_url string Optional A valid URL to receive webhook notifications (POST) when the payment status changes (completed or rejected). See Webhook section.

Response Examples

{
    "status": "pending",
    "message": "Deposit is processing, check status using track or webhook_url",
    "callback": "https://example.com/callback?status=pending&reference=Rvx99ssS99&transaction_id=01JYG4GET7&payment_method=rocket"
}

Possible statuses: pending completed rejected

{
    "status": true,
    "message": "Data submitted successfully",
    "data": {
        "sim_id": "01871168733",
        "amount": 10,
        "payment_method": "api_bkash",
        "reference": "turag05",
        "currency": "BDT",
        "callback_url": "https://google.com/",
        "cust_name": null,
        "issue_time": "2025-09-17 21:22:20"
    },
    "type": "P2C",
    "URL": "https://payment.bkash.com/?paymentId=..."
}

For P2C, the response includes a URL field. Redirect the customer to this URL to complete the payment.

Response Fields

Field Type Description
status string | boolean Payment request status (pending, success, or error).
message string Human-readable message describing the result.
callback string Callback URL with appended query parameters (P2A only).
URL string Payment URL to redirect the customer (P2C only).
Payment Callback Handler

When a payment is processed, the system redirects the user to your callback_url with query parameters:

Success Callback Example

https://yoursite.com/callback?payment=success&payment_method=rocket&request_id=7dc7ae27c564...&reference=ref_usx60cisvas8886&sim_id=01893087273&trxid=DR123456&amount=50

Cancel Callback Example

https://yoursite.com/callback?payment=Cancelled

Possible Status Codes

payment = success payment = rejected payment = Cancelled payment = pending

Track Payment Status

GET

Track the status of a payment using the referenceId. Requires authentication via X-Authorization and X-Authorization-Secret headers.

Tip: The preferred way to get the final payment status is via the Webhook. Use this Track Status endpoint as a fallback — if your webhook endpoint is down, times out, or the webhook was missed, call this API with the referenceId to fetch the current status on demand.

GET https://ipaybd.net/api/v2/payment/status-track/{referenceId}

cURL Example

curl -X GET "https://ipaybd.net/api/v2/payment/status-track/REF12345" \
  -H "X-Authorization: pk_test_123..." \
  -H "X-Authorization-Secret: sk_test_456..."

Request Headers

Header Required Description
X-Authorization Required Your API public key for authentication.
X-Authorization-Secret Required Your API secret key for authentication.

Request Parameters

Field Type Required Description
referenceId string Required The unique reference ID of the payment to track (URL path parameter).

Response Examples

{
    "status": "true",
    "data": {
        "request_id": "4305381816f2515178de5b02b3b819551ca437a75f98b966d3",
        "amount": 50,
        "payment_method": "rocket",
        "reference": "Rvx99sS99",
        "cust_name": null,
        "cust_phone": null,
        "note": null,
        "reject_msg": null,
        "payment_method_trx": "01JYG4GET7",
        "status": "pending"
    }
}

The status field inside data can be: pending success rejected

{
    "status": "false",
    "message": "Data Not found"
}

Response Fields

Field Type Description
status string true if found, false if not.
data object Payment details object (only present on success).
data.request_id string Unique ID of the payment request.
data.amount numeric Payment amount.
data.payment_method string Payment method used.
data.reference string Reference ID from payment creation.
data.cust_name string | null Customer name.
data.reject_msg string | null Rejection reason (if payment was rejected).
data.payment_method_trx string Transaction ID from the payment method.
data.status string Current payment status (pending, success, rejected).

Webhook

POST

Webhooks allow you to receive real-time notifications when a payment status changes. When a payment is completed or rejected, the system will send a POST request to both your callback_url and webhook_url (if provided during payment creation).

Crucial: Actual Received Amount in Webhook
Important

If a customer transfers an amount different from what was initiated in your Create Payment request, the gateway webhook will deliver the actual received amount rather than the requested figure.

Initiated Amount: 500 BDT
Customer Sends: 300 BDT or 700 BDT
Webhook Receives: amount: 300 or 700

Always check and verify the received amount in the webhook payload before crediting your customer or fulfilling orders.

How It Works

1

Create Payment

Include webhook_url in your create-payment request.

2

Status Changes

Payment is processed and status changes to completed or rejected.

3

Receive Notification

System sends a POST request with payment data to your webhook URL.

Webhook Payload

The following JSON payload will be sent as a POST request to your callback_url and webhook_url:

{
    "status": "true",
    "signature": "6294408b326cf940cad20816cda5aa96c234fcabfeef49d013be6e6daeb9514e",
    "data": {
        "request_id": "c05a584911240b30f525041959c5c38540fdd5f34639b214b9",
        "amount": 50,
        "payment_method": "rocket",
        "reference": "Rvx99sS99",
        "cust_name": "Jhon",
        "cust_phone": "+8801712345678",
        "note": null,
        "reject_msg": null,
        "payment_method_trx": "01JYG4GET7",
        "status": "1",
        "status_name": "completed"
    }
}

Payload Fields

Field Type Description
status string Always "true" when webhook is sent.
signature string SHA-256 HMAC signature of the data object, generated using your secret key.
data.request_id string Unique payment request ID generated by the system.
data.amount numeric Actual received payment amount (delivers the actual received amount even if different from the initiated amount).
data.payment_method string Payment method used (e.g., bkash, nagad, rocket, upay).
data.reference string Your unique reference ID provided during payment creation.
data.cust_name string | null Customer name.
data.cust_phone string | null Customer phone number.
data.note string | null Additional note provided during payment creation.
data.reject_msg string | null Rejection reason (only present when payment is rejected).
data.payment_method_trx string Transaction ID from the MFS operator.
data.status string Numeric status code: 1 or 2 = completed, 3 = rejected.
data.status_name string Human-readable status: completed or rejected.

Webhook Handler Example (PHP)

<?php
// webhook.php — Your webhook endpoint

$payloadRaw = file_get_contents('php://input');
$payload = json_decode($payloadRaw, true);

// Your merchant secret key
$merchantSecretKey = 'YOUR_SECRET_KEY';

if ($payload && isset($payload['data']) && isset($payload['signature'])) {
    
    // Verify signature
    $dataJson = json_encode($payload['data']);
    $expectedSignature = hash_hmac('sha256', $dataJson, $merchantSecretKey);
    
    if (!hash_equals($expectedSignature, $payload['signature'])) {
        http_response_code(401);
        echo json_encode(['error' => 'Invalid signature']);
        exit;
    }

    $data = $payload['data'];
    $reference = $data['reference'];
    $statusName = $data['status_name']; // 'completed' or 'rejected'
    $amount = $data['amount'];
    $trxId = $data['payment_method_trx'];

    if ($statusName === 'completed') {
        // Payment successful — update your order status
        // updateOrder($reference, 'paid', $amount, $trxId);
    } elseif ($statusName === 'rejected') {
        // Payment rejected
        $reason = $data['reject_msg'];
        // updateOrder($reference, 'failed', $amount, $reason);
    }

    // Respond with 200 to acknowledge receipt
    http_response_code(200);
    echo json_encode(['received' => true]);
} else {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid payload']);
}

Important Notes

  • Webhooks are only sent for completed (status 1, 2) and rejected (status 3) payments. Pending payments do not trigger webhooks.
  • The webhook is sent as a POST request with Content-Type: application/json.
  • The system sends the webhook to both callback_url and webhook_url if both are provided. You can use either or both.
  • Your webhook endpoint must respond within 10 seconds. Requests that time out will be logged as failed.
  • Always verify the reference and amount in the webhook data against your records before updating order status.
  • Return HTTP 200 from your webhook endpoint to acknowledge receipt.