Webhooks allow your application to receive real-time notifications about events related to orders and transactions. This page explains how to configure, receive, and validate webhooks from the Two-Coin system.
To receive webhook notifications, you need to configure two things in your merchant settings:
Two-Coin sends webhook notifications when order statuses change. Currently, there is one webhook event type that covers all order status updates.
Event Type | Description |
---|---|
order | Fired when an order status changes (any status transition) |
The webhook payload includes the current order status, which can be one of:
Created
Order initially createdPending
Waiting for paymentProcessing
Payment being processedHold
Order on holdComplete
Successfully completedFailed
Order failedExpired
Order expiredRefunded
Order refundedAll webhook notifications are sent as HTTP POST requests with a JSON payload. The payload is wrapped in a typed structure that identifies the webhook type.
{
"type": "order_update",
"body": {
"id": "ord_123456",
"from_currency": "USD",
"to_currency": "BTC",
"redirect_url": "https://example.com/redirect",
"external_user_id": "user123",
"external_order_id": "order456",
"from_amount": 100.00,
"to_amount": 0.003,
"payment_method": "card",
"country_code": "US",
"state_code": "CA",
"wallet_address": "bc1q...",
"status": "Complete",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:05:00Z",
"ip": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"extras": {}
}
}
type
: The webhook event type (currently "order_update"
)body
: The actual webhook data, which varies by type. For order updates, contains the complete order information.For security reasons, you should always verify that webhook requests are coming from Two-Coin. Each webhook request includes signature headers that you can use for verification.
x-webhook-signature
: HMAC-SHA256 signature (hex-encoded)x-webhook-timestamp
: Unix timestamp (seconds) of webhook generationx-webhook-merchant
: Your merchant codeTo verify a webhook signature, you need to reconstruct the signed message and compare signatures:
merchant_code + timestamp + payload
// Node.js example
const crypto = require('crypto');
function verifyWebhook(req, webhookSigningKey) {
const signature = req.headers['x-webhook-signature'];
const timestamp = req.headers['x-webhook-timestamp'];
const merchantCode = req.headers['x-webhook-merchant'];
const payload = JSON.stringify(req.body);
// Build the message that was signed
const message = merchantCode + timestamp + payload;
// Generate expected signature
const expectedSignature = crypto
.createHmac('sha256', webhookSigningKey)
.update(message)
.digest('hex');
// Compare signatures securely
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}
// Processing the webhook
app.post('/webhook', (req, res) => {
if (!verifyWebhook(req, WEBHOOK_SIGNING_KEY)) {
return res.status(401).send('Invalid signature');
}
// Extract webhook type and body
const { type, body } = req.body;
switch (type) {
case 'order_update':
// Process order update
console.log('Order updated:', body.id, 'Status:', body.status);
break;
// Add more webhook types as they become available
}
res.status(200).send('OK');
});
Important Notes
In case your webhook endpoint is temporarily unavailable, Two-Coin will retry the webhook delivery with an exponential backoff. The number of retry attempts is configurable (default: 5 attempts). Failed webhooks are processed by a background task that handles delivery retries automatically.
If you encounter any issues or have questions not addressed in this documentation, please contact our support team on Telegram at https://t.me/cs_2coin (@cs_2coin).