Webhook - Offramp
This section explains the steps to configure callback URLs for receiving events about completed offramp transactions.
Configuring Webhook
Webhooks are configured in the merchant dashboard.
Inside the Setup section, webhooks can be added and modified under the Callback URL's section.

Generating HMAC
Signature is computed using Hash-based message authentication code (HMAC) using a secret key. The secret key is the API Secret present in your merchant dashboard.
The example implementation in Node.js is shown below:
let hmac = crypto.createHmac('sha256', apiSecret);
hmac.update(JSON.stringify(postBody));
let hash = hmac.digest('hex');
assert(hash == headers["X-Onmeta-Signature"])
Completed Order
{{configured_webhook_url}}This callback will be triggered when the crypto coins are deposited to the given receiver address. It will use the configured webhook URL to send order completed details in the POST body.
Event Type: offramp
Make sure you have firewall rules configured to allow receiving the webhook body, otherwise your firewall might block our webhook requests.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
Accept | string | Yes | application/json |
Content-Type | string | Yes | application/json |
X-Onmeta-Signature | string | Yes | HMAC signature for webhook verification |
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
fiat | number | Yes | Fiat amount |
senderWalletAddress | string | Yes | Wallet address sending the crypto |
sellTokenSymbol | string | Yes | Symbol of the sold token |
sellTokenAddress | string | Yes | Contract address of the sold token |
orderId | string | Yes | Unique order identifier |
status | string | Yes | Order status |
currency | string | Yes | Fiat currency code |
chainId | number | Yes | Blockchain network chain ID |
customer | object | Yes | Customer information object |
created_at | string | Yes | Order creation timestamp |
updated_at | string | Yes | Order update timestamp |
tenantId | string | Yes | Tenant identifier |
transactionId | string | Yes | Transaction identifier |
tokensDeducted | number | Yes | Amount of tokens deducted |
tds | number | Yes | TDS amount |
eventType | string | Yes | Event type identifier (offramp) |
metaData | object | No | Additional metadata |
Code Examples
- cURL
- Node.js
- Python
curl --location -g --request POST '{{configured_webhook_url}}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'X-Onmeta-Signature: string' \
--data-raw '{
"fiat": 100,
"senderWalletAddress": "0x12E217bf293b242r1r1414fcw42g1",
"sellTokenSymbol": "MATIC",
"sellTokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"orderId": "63c51a9e598f1f0fabbe8fbc",
"status": "completed",
"currency": "inr",
"source": "",
"chainId": 80001,
"customer": {
"id": "63c514c142e2ae343ed283ed",
"name": "",
"email": "test@onmeta.com",
"phone": {
"countrycode": "",
"number": ""
},
"created_at": "2023-01-16T12:00:00.000Z"
},
"created_at": "2023-01-16T12:00:00.000Z",
"updated_at": "2023-01-16T12:30:00.000Z",
"tenantId": "122345677",
"transactionId": "S11FWKNM931",
"tokensDeducted": 1.22,
"tds": 1,
"eventType": "offramp"
}'
const crypto = require('crypto');
// Verify webhook signature
function verifyWebhookSignature(postBody, signature, apiSecret) {
let hmac = crypto.createHmac('sha256', apiSecret);
hmac.update(JSON.stringify(postBody));
let hash = hmac.digest('hex');
return hash === signature;
}
// Example webhook handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-onmeta-signature'];
const isValid = verifyWebhookSignature(req.body, signature, apiSecret);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process webhook
console.log('Webhook received:', req.body);
res.status(200).json({ success: true });
});
import hmac
import hashlib
import json
def verify_webhook_signature(post_body, signature, api_secret):
message = json.dumps(post_body, separators=(',', ':'))
hash_object = hmac.new(
api_secret.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
)
computed_hash = hash_object.hexdigest()
return computed_hash == signature
# Example webhook handler
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-Onmeta-Signature')
is_valid = verify_webhook_signature(request.json, signature, api_secret)
if not is_valid:
return {'error': 'Invalid signature'}, 401
# Process webhook
print('Webhook received:', request.json)
return {'success': True}, 200
Response Sample
{
"fiat": 100,
"senderWalletAddress": "0x12E217bf293b242r1r1414fcw42g1",
"sellTokenSymbol": "MATIC",
"sellTokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"orderId": "63c51a9e598f1f0fabbe8fbc",
"status": "completed",
"currency": "inr",
"source": "",
"chainId": 80001,
"customer": {
"id": "63c514c142e2ae343ed283ed",
"name": "",
"email": "test@onmeta.com",
"phone": {
"countrycode": "",
"number": ""
},
"created_at": "2023-01-16T12:00:00.000Z"
},
"created_at": "2023-01-16T12:00:00.000Z",
"updated_at": "2023-01-16T12:30:00.000Z",
"tenantId": "122345677",
"transactionId": "S11FWKNM931",
"tokensDeducted": 1.22,
"tds": 1,
"eventType": "offramp"
}
Offramp Webhook Events
Onmeta offramp flow allows you to receive real-time notifications through webhook events when certain events occur.
| # | Event Name | Description |
|---|---|---|
| 1 | pending | This event is triggered when a user has initialised the order but crypto transfer is pending. |
| 2 | orderReceived | This event is triggered when a user transfers crypto and the tokens are received by Onmeta. |
| 3 | InProgress(optional) | This event is triggered when the order is in-progress on the blockchain while swapping tokens (in case of non-base tokens). |
| 4 | CryptoReceived | When we successfully validate the crypto received from user we send this event. |
| 5 | PayoutSuccess | This event is triggered when the fiat amount is successfully deposited in the users bank account. |
| 6 | refunded | This event is triggered when refund is successfully completed in case of amount/token mismatch. |
Example Webhook Request
{
"fiat": 100,
"senderWalletAddress": "0xf12dcsdadefed2eeb4d0475de270447a92a481635caf4a",
"sellTokenSymbol": "MATIC",
"sellTokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"chainId": 137,
"orderId": "641c311afdsaddfwcd2768aa5e",
"status": "PayoutSuccess",
"currency": "inr",
"created_at": "2023-03-23T10:59:38.494Z",
"updated_at": "0001-01-01T00:00:00Z",
"source": "",
"customer": {
"id": "63b52390dsaddefsfefwfw25d377ae",
"email": "documentation@onmeta.in",
"phone": {},
"created_at": "2023-01-04T06:58:24.968Z"
},
"tenantId": "",
"transactionId": "TRAREFXXXXXXXXX",
"tokensDeducted": 1051823.63,
"tds": 1,
"eventType": "offramp",
"metaData": {
"submeta1": "metadata"
}
}