API Reference

Generating Signature

This code can be used in scenarios where secure API communication is necessary, such as in financial applications where the authenticity of transactions must be verified. By generating a hash of the request data, the program ensures that any tampering with the request payload would result in a different hash, thus providing a way to detect unauthorized changes.

Message

Generate signature

FieldTypeDescription
Secret KeystringThis when you create client from FinanOne
MethodstringGET/PUT/POST/DELETE
Relative Pathstring/api/v1/transfer/verify-otp (this is example after base HOST)
TimestampunixTIme.now().Unix() -> Must not > current 30s
Encoded Payloadstring{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}
This body do not spacing or anything else

Secret Key

Please contact the support team to get secret_key (Who owner account in FinanOne that can create your client)

Hash logical

secretkey_method_relativepath_encodedpayload_timestamp (hash256)

Hash Function

A cryptographic hash function employed by HMAC for generating the signature.

package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
)

func main() {
	secretKey := "s3r3c_k3y"
	method := "POST"
	url := "/api/v1/transfer/verify-otp"
	body := `{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}`
	timeStamp := "1724986946"
	
	// Compact JSON to remove unnecessary spaces
	jsonCompat, _ := CompactJSON([]byte(body))
	
	// Create a hash using the compacted JSON and other data
	hashData := HashSHA256(fmt.Sprintf("%s_%s_%s_%s_%s", secretKey, method, url, jsonCompat, timeStamp))
	fmt.Println(hashData)
}

func HashSHA256(hashData string) string {
	hash := sha256.New()
	hash.Write([]byte(hashData))
	hashedBytes := hash.Sum(nil)
	return hex.EncodeToString(hashedBytes)
}

func CompactJSON(input []byte) (string, error) {
	var compactedBuffer bytes.Buffer
	err := json.Compact(&compactedBuffer, input)
	if err != nil {
		return "", err
	}

	return compactedBuffer.String(), nil
}

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.io.JsonStringEncoder;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) {
        String secretKey = "s3r3c_k3y";
        String method = "POST";
        String url = "/api/v1/transfer/verify-otp";
        String body = "{\"id\":\"7fc5e181-aae3-4021-8ce0-6a53aa71990d\",\"pass_code\":\"1828288371923881984\"}";
        String timeStamp = "1724986946";
        
        // Compact JSON to remove unnecessary spaces
        String jsonCompat = compactJSON(body);
        
        // Create a hash using the compacted JSON and other data
        String hashData = hashSHA256(String.format("%s_%s_%s_%s_%s", secretKey, method, url, jsonCompat, timeStamp));
        System.out.println(hashData);
    }

    public static String hashSHA256(String hashData) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(hashData.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder(2 * bytes.length);
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }

    public static String compactJSON(String input) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Object json = objectMapper.readValue(input, Object.class);
            return objectMapper.writeValueAsString(json);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Failed to compact JSON", e);
        }
    }
}

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

const crypto = require('crypto');

const secretKey = "s3r3c_k3y";
const method = "POST";
const url = "/api/v1/transfer/verify-otp";
const body = '{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}';
const timeStamp = "1724986946";

// Compact JSON to remove unnecessary spaces
const jsonCompat = JSON.stringify(JSON.parse(body));

// Create a hash using the compacted JSON and other data
const hashData = hashSHA256(`${secretKey}_${method}_${url}_${jsonCompat}_${timeStamp}`);
console.log(hashData);

function hashSHA256(data) {
  return crypto.createHash('sha256').update(data).digest('hex');
}

import hashlib
import json

secret_key = "s3r3c_k3y"
method = "POST"
url = "/api/v1/transfer/verify-otp"
body = '{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}'
timestamp = "1724986946"

# Compact JSON to remove unnecessary spaces
json_compat = json.dumps(json.loads(body), separators=(',', ':'))

# Create a hash using the compacted JSON and other data
hash_data = hashlib.sha256(f"{secret_key}_{method}_{url}_{json_compat}_{timestamp}".encode()).hexdigest()
print(hash_data)

<?php

$secretKey = "s3r3c_k3y";
$method = "POST";
$url = "/api/v1/transfer/verify-otp";
$body = '{"id":"7fc5e181-aae3-4021-8ce0-6a53aa71990d","pass_code":"1828288371923881984"}';
$timeStamp = "1724986946";

// Compact JSON to remove unnecessary spaces
$jsonCompat = json_encode(json_decode($body));

// Create a hash using the compacted JSON and other data
$hashData = hash('sha256', "$secretKey_$method_$url_$jsonCompat_$timeStamp");
echo $hashData;
?>

using System;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

class Program
{
    static void Main()
    {
        string secretKey = "s3r3c_k3y";
        string method = "POST";
        string url = "/api/v1/transfer/verify-otp";
        string body = "{\"id\":\"7fc5e181-aae3-4021-8ce0-6a53aa71990d\",\"pass_code\":\"1828288371923881984\"}";
        string timeStamp = "1724986946";

        // Compact JSON to remove unnecessary spaces
        string jsonCompat = CompactJSON(body);

        // Create a hash using the compacted JSON and other data
        string hashData = HashSHA256($"{secretKey}_{method}_{url}_{jsonCompat}_{timeStamp}");
        Console.WriteLine(hashData);
    }

    static string HashSHA256(string data)
    {
        using (SHA256 sha256 = SHA256.Create())
        {
            byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(data));
            return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
        }
    }

    static string CompactJSON(string json)
    {
        JObject parsed = JObject.Parse(json);
        return parsed.ToString(Formatting.None);
    }
}

Generated signature in client will be attached in request header by key x-finan-signature along with client_id by key x-finan-key

📘

Obtain client Id

Please contact the support team to get client_id

Example

Content-Type: application/json
x-client-id: <client_id>
x-signature: <signature>
x-timestamp: <timestamp>