Sign in
परिचय/Webhook सूचनाएँ

Webhook Notifications

HMAC-signed webhooks के माध्यम से real-time payment और payout status updates प्राप्त करें।

जब भी कोई payment status बदलता है, 2328.io सिस्टम आपके url_callback पर एक webhook भेजता है। सफल भुगतानों के बारे में सूचित होने का यह अनुशंसित तरीका है।

Request format

  • Method: POST
  • Content-Type: application/json
  • Signature: request body में sign field

Payload

Webhook body /v1/payment/info response के समान है, साथ ही signature verification के लिए एक sign field।

सफल भुगतान

JSON
{
  "uuid": "db17d490-15b6-47b9-9015-91d1d8b119f2",
  "order_id": "ORDER-12345",
  "amount": "180.00000000",
  "currency": "RUB",
  "url": "https://go.2328.io/db17d490-15b6-47b9-9015-91d1d8b119f2",
  "expires_at": "2026-05-09T16:56:58+03:00",
  "created_at": "2026-05-09T15:56:58+03:00",
  "payer_currency": "TON",
  "payer_amount": "0.95256917",
  "network": "TON",
  "address": "UQA0RevhkCQx-EltyNgPPeG8dqtnCz7ZslOzMdNQlLxVaNBb",
  "payment_status": "paid",
  "txid": "41c2a327323480af8e705d05deb09c238a41779928832abef4bb77c862357b11",
  "payment_amount": "0.95256917",
  "merchant_amount": "0.949711462490000000",
  "amount_usd": "2.41324380",
  "exchange_rate": "0.01340691",
  "sign": "6f8c15b6e53b506d5bfa38ed3fb3b50697af73434262153c02e412541372f04d"
}

रद्द / असफल भुगतान

जब भुगतान terminal paid state में नहीं होता, तो txid, payment_amount, और merchant_amount null होते हैं:

JSON
{
  "uuid": "48edaf2d-2c49-4638-8f86-88636f661c1f",
  "order_id": "ORDER-12345",
  "amount": "2800.00000000",
  "currency": "RUB",
  "url": "https://go.2328.io/48edaf2d-2c49-4638-8f86-88636f661c1f",
  "expires_at": "2026-05-09T06:19:04+03:00",
  "created_at": "2026-05-09T05:19:04+03:00",
  "payer_currency": "ETH",
  "payer_amount": "0.01620968",
  "network": "ETH-ERC20",
  "address": "0x37c20d6d96d130Bc5B33D832e43b8e16aACe0c59",
  "payment_status": "cancel",
  "txid": null,
  "payment_amount": null,
  "merchant_amount": null,
  "amount_usd": "37.53934800",
  "exchange_rate": "0.01340691",
  "sign": "40ce68ad9691ad54e684329d75ab5adaf5b01409a2d18d3e0110b8c1be605342"
}

Field reference

FieldTypeDescription
uuidstringPayment UUID
order_idstringआपका order ID
amountdecimal (8 dp)currency में Fiat राशि
currencystringवह fiat currency जिसका merchant ने अनुरोध किया
urlstringHosted checkout URL
expires_atstring (ISO 8601)Payment session कब expire होता है
created_atstring (ISO 8601)Payment session कब बनाया गया
payer_currencystringवह crypto जिसमें payer pay कर रहा है
payer_amountdecimal (8 dp)अपेक्षित crypto राशि
networkstringBlockchain network
addressstringDeposit address
payment_statusstringइनमें से एक: pending, check, paid, underpaid_check, underpaid, overpaid, cancel, aml_lock (देखें References)
txidstring | nullBlockchain tx hash, केवल confirmed payment के बाद उपस्थित
payment_amountdecimal | nullवास्तविक भुगतान राशि, केवल payment के बाद उपस्थित
merchant_amountdecimal (18 dp) | nullFees के बाद merchant को credit की गई राशि
amount_usddecimal (8 dp)Creation के समय USD में राशि
exchange_ratedecimalउपयोग की गई Crypto / fiat विनिमय दर
signstring (hex)Payload का HMAC-SHA256 सिग्नेचर

सिग्नेचर verify करना

Webhook सिग्नेचर verify करने के लिए:

  1. Payload से sign field निकालें
  2. Object से sign field हटा दें
  3. बाकी fields को JSON के रूप में encode करें
  4. JSON को Base64 में encode करें
  5. अपनी API_KEY का उपयोग करके Base64 string से HMAC-SHA256 compute करें
  6. Constant-time comparison का उपयोग करके computed सिग्नेचर की तुलना sign value से करें
PHP
<?php
function verifyWebhookSign(array $data, string $apiKey): bool {
    $receivedSign = $data['sign'] ?? '';
    unset($data['sign']);

    $json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    $base64 = base64_encode($json);
    $calculated = hash_hmac('sha256', $base64, $apiKey);

    return hash_equals($calculated, $receivedSign);
}

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

if (!verifyWebhookSign($payload, $apiKey)) {
    http_response_code(401);
    exit;
}

switch ($payload['payment_status']) {
    case 'paid':
    case 'overpaid':
        // Credit the order — check idempotency by order_id first
        break;
    case 'underpaid_check':
    case 'underpaid':
    case 'cancel':
        break;
}

http_response_code(200);

किसी भी user को फंड credit करने से पहले हमेशा सिग्नेचर verify करें। एक unsigned या गलत-तरीके से signed webhook spoofed request हो सकता है।

Payout webhooks

जब किसी payout का status बदलता है, तो सिस्टम payout बनाते समय pass किए गए url_callback URL पर एक POST webhook भेजता है। यदि url_callback प्रदान नहीं किया गया था, तो उस payout के लिए कोई webhook नहीं भेजा जाता।

Payout webhooks को आपकी Payout API key से verify किया जाना चाहिए — सामान्य API key से नहीं। Signing algorithm payment webhooks के समान ही है (sign हटाएँ, JSON-encode, base64, HMAC-SHA256), केवल key अलग है।

Payload

JSON
{
  "uuid": "019dff1f-0dbd-7277-8d45-271e7775388f",
  "order_id": "4dfdcc84402b1185b71cbe399321533e",
  "status": "completed",
  "currency": "TRX",
  "network": "TRX-TRC20",
  "amount": "3.00",
  "merchant_amount": "3.00",
  "network_amount": "3.00",
  "amount_usd": "1.04",
  "to_address": "THauRv5tcucQRohXg8NiyGTk16DX1XQG5x",
  "memo": null,
  "txid": "9242e533703704ef3eaba840f70b4a26333e72c943377ee375fea17badb53def",
  "block_number": null,
  "error_type": null,
  "created_at": "2026-05-07T00:08:38+03:00",
  "updated_at": "2026-05-07T00:08:54+03:00",
  "from_currency": "USDT",
  "debited_amount": "1.050735",
  "debited_currency": "USDT",
  "sign": "925ad7bf3d6841864101f7cc2c7e30652e70a06cdb04dbe07a0129480000ce4a"
}

Field reference

FieldTypeDescription
uuidstringPayout UUID
order_idstringआपका idempotency / reference ID, यदि आपने प्रदान किया हो
statusstringpending, completed, failed, cancelled (देखें References)
currencystringनिकासी currency
networkstringBlockchain network
amountdecimalनिकासी राशि (currency में)
merchant_amountdecimalMerchant बैलेंस से charge की गई राशि
network_amountdecimalवास्तव में on-chain भेजी गई राशि
amount_usddecimalPayout के समय USD value
to_addressstringप्राप्तकर्ता का blockchain address
memostring | nullयदि उपयोग किया गया हो तो Memo / destination tag
txidstring | nullBlockchain transaction hash, completed पर set होता है
block_numberinteger | nullOn-chain transaction की Block height
error_typestring | nullजब status = failed का कारण (जैसे aml_risk, देखें References)
created_atstring (ISO 8601)Payout कब बनाया गया
updated_atstring (ISO 8601)Status अंतिम बार कब बदला गया
from_currencystringAuto-conversion का उपयोग होने पर वह source बैलेंस जिससे payout debit हुआ था (जैसे BTC payout के लिए USDT)
debited_amountdecimalfrom_currency बैलेंस से debit की गई राशि
debited_currencystringDebit की currency
signstring (hex)Payload का HMAC-SHA256 सिग्नेचर, Payout API key से signed

Best practices

  • Idempotency — हमेशा जाँच करें कि भुगतान पहले से process हो चुका है (या तो order_id या uuid से)। Webhooks कई बार आ सकते हैं।
  • तेज़ response — जितनी जल्दी हो सके HTTP 200 लौटाएँ। भारी काम को background queue में स्थानांतरित करें।
  • Retries — यदि सिस्टम को HTTP 200 नहीं मिलता, तो webhook 2 मिनट बाद फिर से भेजा जाता है। अधिकतम 5 retry प्रयास।
  • Async processing — Response को block होने से बचाने के लिए webhook events को asynchronously handle करें।
  • Security — Payload पर भरोसा करने से पहले हमेशा sign सिग्नेचर verify करें।

Webhooks order से बाहर आ सकते हैं। यह न मानें कि आपको प्राप्त पहला webhook ही final state है — यदि आपको निश्चितता चाहिए तो हमेशा /v1/payment/info (या /v1/payout/status/{uuid}) के माध्यम से दोबारा fetch करें।