Webhook for Tylt Prime ( Pay-out)
Overview
Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a callBackUrl
in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.
Setting Up the Webhook
Implement a Callback Endpoint: Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
Insert the Callback URL: While calling the Create Pay-in or Create Pay-out instance API's , insert your endpoint URL in the
callBackUrl
field. Tylt will send updates to this URL whenever the transaction status changes.Status Updates: The life cycle of a payment instance is tracked via
eventId
. Below is the list of possibleeventId
values and their meanings:
Payout using balance in Tylt Wallet
If you are using the Tylt Wallet balance to process a payout, please use the API keys generated for the account configured for Daily Settlement (T0). While payouts are executed and settled instantly, they are routed through the Daily Settlement channel for technical and compliance purposes.
1
The instance and trade is created. Waiting for the user to accept the quote.
2
Quote accepted. The merchant wallet has been debited and we are now awaiting the user to enter their CPF number and payment details.
3
Payment to PIX ID in BRL is under process.
4
Payment completed and trade settled.
9
Trade expired as action or payment was not completed prior to the deadline or disputed payment was expired due to non payment.
Instance Information
The response related to an instance information contains two primary objects:
1. Trade Object
This object contains all the information about the customer buying or selling USDT from the counterparty. It includes fields like:
Trade lifecycle details (
eventId
, deadlines, description).Fiat and cryptocurrency details (currency name, symbol, amount, etc.).
Payment method information (e.g., PIX).
2. Transaction Object
This object contains all the information about the financial debit or credit carried out on the merchant's account. It is relevant to merchants for crediting or debiting a consumer for the transaction. The transaction
object is updated only when the eventId
is 4, representing the completion of the trade
Callback Validation: To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header
X-TLP-SIGNATURE
.Acknowledge the Callback: Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text
"ok"
in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend webhooks from their Tylt dashboard.
Validating Callbacks
Merchants should validate the HMAC signature included in the X-TLP-SIGNATURE
header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the MERCHANT_API_SECRET
as the shared key.
Example Web-hook Handling Code
const express = require('express');
const crypto = require('crypto');
const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key
// Middleware to parse incoming JSON requests
app.use(express.json());
// Callback endpoint
app.post('/callback', (req, res) => {
const data = req.body;
// Calculate HMAC signature
const tlpSignature = req.headers['x-tlp-signature'];
const calculatedHmac = crypto
.createHmac('sha256', apiSecretKey)
.update(JSON.stringify(data)) // Use raw body string for HMAC calculation
.digest('hex');
if (calculatedHmac === tlpSignature) {
// Signature is valid
if (data.accounts.transactionType === 'pay-out') {
console.log('Received pay-out callback:', data);
// Process pay-in data here
}
// Return HTTP Response 200 with content "ok"
res.status(200).send('ok');
} else {
// Invalid HMAC signature
res.status(400).send('Invalid HMAC signature');
}
});
// Start the server
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});
Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.
Example of Web-hook Responses
{
"data": {
"trade": {
"event": {
"id": 1,
"deadline": "2025-02-12T05:27:37Z",
"description": "Trade Initiated. Payment Link Generated. Quote displayed."
},
"createdAt": "2025-02-12T05:24:37Z",
"updatedAt": "2025-02-12T05:24:37Z",
"fiatCurrency": {
"name": "Brazilian Real",
"symbol": "BRL"
},
"priceDetails": {
"price": null,
"amount": null,
"paymentAmount": 500
},
"paymentMethod": {
"details": null
},
"cryptoCurrency": {
"name": "Tether",
"symbol": "USDT"
}
},
"transaction": {
"amount": null,
"status": null,
"isFinal": null,
"orderId": null,
"createdAt": null,
"isCredited": null,
"updatedAt": null,
"merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3"
},
"accounts": {
"transactionType": "pay-out",
"amountPaidInLocalCurrency": 500,
"localCurrency": "BRL",
"conversionRate": null,
"amountPaidInCryptoCurrency": null,
"cryptoCurrencySymbol": "USDT",
"MDR_Rate": 1.1,
"merchantAccountCredited": null,
"merchantAccountDebited": null
},
"user": {}
}
}
Last updated