Callbacks
Basics
The callback sends a POST request with data in the request body(data types). A 200 status is expected in response as confirmation of successful callback processing. There is also a time processing limit for the callback, currently set to 2 seconds. If a 200 status is not received within this time, the callback will be marked as unsuccessful and resent.
Additionally, there is an interval for retrying callback delivery in case of a previous unsuccessful attempt, with a total of 12 attempts. The first attempt is made after 2 seconds, followed by subsequent attempts at intervals of 4 seconds, 8 seconds, and so on, with each attempt occurring after a period of 2 raised to the power of the attempt number.
For example, if it's the 10th attempt, it will occur after 1024 seconds (approximately 17 minutes).
Each callback in the request contains a header: "kun-signature," which holds the signature of the callback body. The callback signature is generated using the private key issued along with the API key being used.
How to authenticate a callback is described in this section.
Callback types
In this section, the typification of all possible callbacks in the system is presented.
Withdraw
Callback about the status of a money withdrawal from the system.
{
event: 'Withdraw';
data: {
id: string;
type: 'Withdraw';
companyId: string;
paymentCode: string;
asset: string;
amount: string; // amount with fee
fee: string | null;
processedAmount: string | null; // amount without fee
status: 'Processed' | 'PartiallyProcessed' | 'Canceled';
address: string | null;
memo: string | null;
txId: string | null;
callbackId?: string | null;
createdAt: Date;
updatedAt: Date;
};
}
Invoice deposit
Callback about the status of a deposit for an invoice. Only available when choosing transactional callbacks for an invoice (described in the section about invoices).
{
event: 'InvoiceDeposit';
data: {
id: string;
type: 'InvoiceDeposit';
companyId: string;
paymentCode: string;
asset: string;
amount: string; // amount without fee
fee: string | null;
processedAmount: string | null; // amount with fee
status: 'Processed' | 'PartiallyProcessed' | 'Canceled';
address: string | null;
memo: string | null;
txId: string | null;
invoiceExternalOrderId?: string | null;
invoiceId: string;
callbackId?: string | null;
createdAt: Date;
updatedAt: Date;
};
}
Invoice
Callback about the status of an invoice.
{
event: 'Invoice';
data: {
id: string;
companyId: string;
invoiceAssetCode: string;
invoiceAmount: string;
paymentAssetCode: string | null;
paymentAmount: string | null;
paymentFee: string | null;
paymentMethod?: {
code: string;
network: string | null;
};
payment: {
paidAmount: string;
paidFee: string;
leftAmount: string;
paidAmountInInvoiceAsset: string;
leftAmountInInvoiceAsset: string;
};
transactions: {
id: string;
type: 'InvoiceDeposit';
companyId: string;
paymentCode: string;
asset: string;
amount: string; // amount without fee
fee: string | null;
processedAmount: string | null; // amount with fee
status: 'Processed' | 'PartiallyProcessed' | 'Canceled';
address: string | null;
memo: string | null;
txId: string | null;
invoiceExternalOrderId?: string | null;
invoiceId: string;
callbackId?: string | null;
createdAt: Date;
updatedAt: Date;
}[];
address: string | null;
memo: string | null;
status: 'PAID' | 'PARTIALLY_PAID' | 'SUSPENDED' | 'ARRESTED' | 'TIMEOUT';;
isPaymentAfterTimeout: boolean; // if payment send to blockchain after expire time
externalOrderId: string | null;
productDescription: string | null;
productCategory: string | null;
isCreatedByApi: boolean;
completedAt: Date | null;
expireAt: Date | null;
createdAt: Date;
updatedAt: Date;
};
Payout
Callback about the status of Payout.
{
event: 'Payout';
data: {
id: string;
externalId: string |null;
title: string |null;
description: string |null;
status: 'Processing' | 'Processed' | 'Failed';
completedAt: string |null;
launchedAt: string |null;
createdAt: string;
updatedAt: string;
};
}
Payout Withdraw
Callback about the status of PayoutWithdraw.
{
event: 'PayoutWithdraw';
data: {
id: string;
address: string;
asset: string;
paymentCode: string;
companyId: string;
type: 'PayoutWithdraw';
status: 'Processed';
fee: string;
amount: string;
processedAmount: string;
callbackId: string | null;
createdAt: string;
updatedAt: string;
PayoutContractor: {
name: string;
};
Payout: {
id: string;
externalId: string | null;
};
};
}
Security (signature)
To verify the authenticity of a callback, you need to generate a signature and compare it with the one received in the callback(header: "kun-signature). To generate the signature, convert the callback body to JSON, then generate an HMAC SHA384 hash using the private key provided for the API key. Ensure the hash is converted to a hex string.
Example of signature generation:
const crypto = require('crypto');
// Assuming callbackBody is the JSON representation of the callback body
const callbackBody = {
// Your callback body properties here
};
// Assuming privateKey is the private key provided for the API key
const privateKey = 'your_private_key';
// Convert the callback body to JSON
const jsonCallbackBody = JSON.stringify(callbackBody);
// Generate HMAC SHA384
const signature = crypto
.createHmac('sha384', privateKey)
.update(jsonCallbackBody)
.digest('hex');
console.log('Generated Signature:', signature);
Make sure to replace 'your_private_key' with the actual private key provided for your API key.
Updated 7 months ago