iPeakoin API Notifications
This document list and describes the events and data models used in iPeakoin Notifications.
WebHook
iPeakoin uses Webhooks to notify a single callback URL provided by the client in a specified format. iPeakoin will send different payloads according to the scenarios described further below, and the trigger event can be understood in terms of the Template field in the payload body.
The client should return the specified return code. If no corresponding return code is received after sending the callback URL, the iPeakoin system will consider the push unsuccessful. The return fields are as follows:
Field | Type | Description |
---|---|---|
id | string | id of the notification pushed to the customer |
received | boolean | Receiving identifier |
The iPeakoin system delays the push for 30s, 60s, 120s, and 240s in sequence, with a maximum of five pushes.
Common Considerations
All current and future implementations of notification messages have the following attributes:
Name | Type | Description | Sample |
---|---|---|---|
id | UUID | notification identifier | 32b0216b-66d9-498b-a4bc-17612d9cb6cd |
businessType | string | The businessType of notification | AssetsDeposit |
sign | string | signature | 055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd |
Account Notification
AccountRegistered
When you create a subaccount, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "AccountRegistered",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a Account Object.
KYC
When you create a subaccount through KYC, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "KYC",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a Account Object.
Quantum Card Notification
CreateCard
Create a quantum card, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "CreateCard",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a Card Object.
FrozenCard
Frozen quantum card, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "FrozenCard",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a Card Object.
UnfrozenCard
Unfrozen quantum card, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "UnfrozenCard",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a Card Object.
DeleteCard
Delete quantum card, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "DeleteCard",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a Card Object.
CardTransaction
When the quantum card generates a transaction, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "CardTransaction",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a CardTransaction Object.
FrozenAmount
Frozen the quantum card amount, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "FrozenAmount",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a CardTransaction Object.
UnfrozenAmount
Unfrozen the quantum card amount, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "UnfrozenAmount",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a CardTransaction Object.
BudgetTransaction
When a budget generates a transaction, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "UnfrozenAmount",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a BudgetTransaction Object.
Global Account Notification
CreateGlobalAccount
Open global accounts in compliance, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "CreateGlobalAccount",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a BankAccount Object.
GlobalAccountTransaction
When a global account generates a transaction, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "CreateGlobalAccount",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a GlobalAccountTransaction Object.
Crypto Asset Notification
AssetsDeposit
Once you process a successful deposit, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "AssetsDeposit",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a Deposit Object.
AssetsWithdrawal
Once you process a successful withdrawal, you should see a notification message on your local server shell that looks like the following.
{
"id": "6a94b9c7-40d6-4007-a5d0-a96d714a1108",
"businessType": "AssetsWithdrawal",
"data": { ... },
"sign": "055144f3c59f2412d5575daee1ecc473b028378d3c3e359970fc96b33314e5bd"
}
The data
payload will be a Withdrawal Object.
Signature
Each request initiated by iPeakoin contains a sign parameter that can be used to verify the authenticity of the request from iPeakoin. For each request, the data of the data parameter is fetched and processed through the HMAC-SHA256 hash function.
- Set of parameters to be signed
const params = {
"id": "ee74c872-8173-4b67-81b1-5746e7d5ab88",
"accountId": null,
"holderId": "d2bd6ab3-3c28-4ac7-a7c4-b7eed5eee367",
"currency": "USD",
"settlementCurrency": null,
"counterparty": "SAILINGWOOD;;US;1800948598;;091000019",
"transactionAmount": 11,
"fee": 0,
"businessType": "Inbound",
"status": "Closed",
"transactionTime": "2021-11-22T07:34:10.997Z",
"transactionId": "124d3804-defa-4033-9f30-1d8b0468e506",
"clientTransactionId": null,
"createTime": "2021-11-22T07:34:10.997Z",
"appendFee": 0,
};
- The parameter set key to be signed is sorted in ascending order according to "ASCII code of the first character of the string" (if the ASCII code value is the same in the sorting process, the next digit is incremented in sequence for comparison).
const keys = Object.keys(params);
keys.sort();
- Concatenates a string, and empty values are filled with empty strings
accountId=&appendFee=0&businessType=Inbound&clientTransactionId=&counterparty=SAILINGWOOD;;US;1800948598;;091000019&createTime=2021-11-22T07:34:10.997Z¤cy=USD&fee=0&holderId=d2bd6ab3-3c28-4ac7-a7c4-b7eed5eee367&id=ee74c872-8173-4b67-81b1-5746e7d5ab88&settlementCurrency=&status=Closed&transactionAmount=11&transactionId=124d3804-defa-4033-9f30-1d8b0468e506&transactionTime=2021-11-22T07:34:10.997Z
- CLIENT_SECRET is used to perform hmac-sha256 signature on the concatenated string, and the hexadecimal encoding is used to obtain signature.
const hmac = crypto.createHmac('sha256', '25d55ad283aa400af464c76d713c07ad');
const sign = hmac.update('Concatenates a string').digest('hex');
Example Code
const crypto = require('crypto');
const params = {
"id": "ee74c872-8173-4b67-81b1-5746e7d5ab88",
"accountId": null,
"holderId": "d2bd6ab3-3c28-4ac7-a7c4-b7eed5eee367",
"currency": "USD",
"settlementCurrency": null,
"counterparty": "SAILINGWOOD;;US;1800948598;;091000019",
"transactionAmount": 11,
"fee": 0,
"businessType": "Inbound",
"status": "Closed",
"transactionTime": "2021-11-22T07:34:10.997Z",
"transactionId": "124d3804-defa-4033-9f30-1d8b0468e506",
"clientTransactionId": null,
"createTime": "2021-11-22T07:34:10.997Z",
"appendFee": 0,
};
const keys = Object.keys(params);
keys.sort();
const result = [];
for (const key of keys) {
let val = params[key];
if (val == null) {
val = '';
}
result.push(`${key}=${val}`);
}
const str = result.join('&');
const hmac = crypto.createHmac('sha256', '25d55ad283aa400af464c76d713c07ad');
const sign = hmac.update(str).digest('hex');
console.log(sign);
// => 8287d5539c03918c9de51176162c2bf7065d5a8756b014e3293be1920c20d102
package com.qbitnetwork.demo;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
public class Signature {
public static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
Formatter formatter = new Formatter(sb);
for (byte b : bytes) {
formatter.format("%02x", b);
}
return sb.toString();//完成16进制编码
}
public static byte[] sign(String str, String secret) throws NoSuchAlgorithmException, InvalidKeyException {
Key sk = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
Mac mac = Mac.getInstance(sk.getAlgorithm());
mac.init(sk);
return mac.doFinal(str.getBytes());//完成hmac-sha256签名
}
public static String joinStr(Map<String, Object> data) {
String[] keys = data.keySet().toArray(new String[0]);
Arrays.sort(keys);
StringBuilder sb = new StringBuilder();
for (String key : keys) {
Object val = data.get(key);
if (val == null) {
val = "";
}
sb.append(key).append("=").append(val).append("&");
}
String str = sb.toString();
return str.substring(0, str.length() - 1);
}
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
Map<String, Object> data = new HashMap<>();
data.put("id", "ee74c872-8173-4b67-81b1-5746e7d5ab88");
data.put("accountId", null);
data.put("holderId", "d2bd6ab3-3c28-4ac7-a7c4-b7eed5eee367");
data.put("currency", "USD");
data.put("settlementCurrency", null);
data.put("counterparty", "SAILINGWOOD;;US;1800948598;;091000019");
data.put("transactionAmount", 11);
data.put("fee", 0);
data.put("businessType", "Inbound");
data.put("status", "Closed");
data.put("transactionTime", "2021-11-22T07:34:10.997Z");
data.put("transactionId", "124d3804-defa-4033-9f30-1d8b0468e506");
data.put("clientTransactionId", null);
data.put("createTime", "2021-11-22T07:34:10.997Z");
data.put("appendFee", 0);
String sgn = bytesToHex(sign(joinStr(data), "25d55ad283aa400af464c76d713c07ad"));
System.out.println(sgn);
// => 8287d5539c03918c9de51176162c2bf7065d5a8756b014e3293be1920c20d102
}
}
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"sort"
"strings"
)
func getKeys(m map[string]interface{}) []string {
j := 0
keys := make([]string, len(m))
for k := range m {
keys[j] = k
j++
}
return keys
}
func joinStr(params map[string]interface{}) string {
keys := getKeys(params)
sort.Strings(keys)
var result []string
for _, key := range keys {
val := params[key]
if val == nil {
val = ""
}
result = append(result, fmt.Sprintf("%s=%s", key, fmt.Sprintf("%v", val)))
}
return strings.Join(result, "&")
}
func sign(message string, secret string) string {
key := []byte(secret)
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
return hex.EncodeToString(h.Sum(nil))
}
func main() {
params := map[string]interface{} {
"id": "ee74c872-8173-4b67-81b1-5746e7d5ab88",
"accountId": nil,
"holderId": "d2bd6ab3-3c28-4ac7-a7c4-b7eed5eee367",
"currency": "USD",
"settlementCurrency": nil,
"counterparty": "SAILINGWOOD;;US;1800948598;;091000019",
"transactionAmount": 11,
"fee": 0,
"businessType": "Inbound",
"status": "Closed",
"transactionTime": "2021-11-22T07:34:10.997Z",
"transactionId": "124d3804-defa-4033-9f30-1d8b0468e506",
"clientTransactionId": nil,
"createTime": "2021-11-22T07:34:10.997Z",
"appendFee": 0,
}
fmt.Println(sign(joinStr(params), "25d55ad283aa400af464c76d713c07ad"))
// => 8287d5539c03918c9de51176162c2bf7065d5a8756b014e3293be1920c20d102
}
import hashlib
import hmac
def sign(message, secret):
encryption = hmac.new(bytes(secret, encoding='UTF-8'), bytes(message, encoding='UTF-8'), hashlib.sha256)
return encryption.hexdigest()
def join_str(origin):
keys = list(origin.keys())
keys.sort()
content = []
for key in keys:
val = origin[key]
if val is None:
val = ''
content.append(key + '=' + str(val))
return '&'.join(content)
if __name__ == '__main__':
data = {
"id": "ee74c872-8173-4b67-81b1-5746e7d5ab88",
"accountId": None,
"holderId": "d2bd6ab3-3c28-4ac7-a7c4-b7eed5eee367",
"currency": "USD",
"settlementCurrency": None,
"counterparty": "SAILINGWOOD;;US;1800948598;;091000019",
"transactionAmount": 11,
"fee": 0,
"businessType": "Inbound",
"status": "Closed",
"transactionTime": "2021-11-22T07:34:10.997Z",
"transactionId": "124d3804-defa-4033-9f30-1d8b0468e506",
"clientTransactionId": None,
"createTime": "2021-11-22T07:34:10.997Z",
"appendFee": 0,
}
sig = sign(join_str(data), '25d55ad283aa400af464c76d713c07ad')
print(sig)
# => 8287d5539c03918c9de51176162c2bf7065d5a8756b014e3293be1920c20d102
Updated 8 days ago