About the Sign

Introduction

The secret key used to generate a signature for API request input parameters should be securely maintained by the merchant.

To generate a signature string:

  1. Collect all required parameters that need to be verified into an array.
  2. Sort the array alphabetically by parameter names (keys) in ascending ASCII order. It's important to note that only the parameter keys are sorted, not their values.
  3. Exclude the sign parameter itself from the array before generating the signature.

Example

Example request parameters

{
    "appId": "TEST000001",
    "sign": "TEST000001",
    "merchantOrderNo": "11126",
    "userId": "[email protected]",
    "orderAmount": "1000",
    "payCurrency": "USD",
    "paymentTokens": "USDT,ETH",
    "paymentExchange": "16f021b0-f220-4bbb-aa3b-82d423301957,9226e5c2-ebc3-4fdd-94f6-ed52cdce1420"
}

Prepare the string concatenation for sign, convert the format to parameter_name=parameter_value, link with '&', and finally append the key (secret). The result is as follows:

appId=TEST000001&merchantOrderNo=11126&orderAmount=1000&payCurrency=USD&paymentExchange=16f021b0-f220-4bbb-aa3b-82d423301957,9226e5c2-ebc3-4fdd-94f6-ed52cdce1420&paymentTokens=USDT,ETH&[email protected]&key=**************0b5nCak

Continuing from the prepared string for signing, perform the SHA-512 algorithm to generate the final signature.And change it into capital letters. The signature result is as follows:

 3962E8FF2ABD24B806D744C6630B95A05855A2AB86944CCF52009D6E2582787EB0F34CFF323843DDA55B148D770390598AF335DDBECC61D702AA1A87EE93D

Java signature generation code example

import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;

public class Sha512Signer {
    
    public static String sha512Sign(Map<String, String> dataMap, String secretKey) throws NoSuchAlgorithmException {

        List<String> keys = new ArrayList<>(dataMap.keySet());
        Collections.sort(keys);


        StringBuilder queryString = new StringBuilder();
        for (String key : keys) {
            queryString.append(key).append("=").append(dataMap.get(key)).append("&");
        }


        queryString.append("key=").append(secretKey);
        String stringToSign = queryString.toString();
        System.out.println("String to sign: " + stringToSign);

        MessageDigest md = MessageDigest.getInstance("SHA-512");
        byte[] hash = md.digest(stringToSign.getBytes());
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            hexString.append(String.format("%02x", b));
        }

        return hexString.toString().toUpperCase();
    }

    public static void main(String[] args) throws Exception {

        String url = "https://crypto-payment.alchemytech.cc/XXXXX";
        String appId = "XXXXX";
        String secret = "XXXXX";


        Map<String, String> reqData = new HashMap<>();
        reqData.put("merchantOrderNo", "XXXXX");
        reqData.put("appId", appId);


        String sign = sha512Sign(reqData, secret);
        reqData.put("sign", sign);


        StringBuilder jsonData = new StringBuilder("{");
        for (Map.Entry<String, String> entry : reqData.entrySet()) {
            jsonData.append("\"").append(entry.getKey()).append("\":\"").append(entry.getValue()).append("\",");
        }
        jsonData.deleteCharAt(jsonData.length() - 1); 
        jsonData.append("}");


        sendPostRequest(url, jsonData.toString());
    }


    private static void sendPostRequest(String url, String jsonData) throws IOException {
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        

        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);
        

        try (OutputStream os = con.getOutputStream()) {
            byte[] input = jsonData.getBytes("utf-8");
            os.write(input, 0, input.length);	
        }


        int responseCode = con.getResponseCode();
        System.out.println("Response Code: " + responseCode);
        
        try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
            String inputLine;
            StringBuilder response = new StringBuilder();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }

            System.out.println("Response: " + response.toString());
        }
    }
}
import requests
import hashlib


def sha512_sign(data_dict, secret_key):
    sorted_items = sorted(data_dict.items())
    query_string = '&'.join(f"{str(k)}={str(v)}" for k, v in sorted_items)
    string_to_sign = query_string + f"&key={secret_key}"
    print(string_to_sign)
    sha512_hash = hashlib.sha512(string_to_sign.encode('utf-8')).hexdigest().upper()
    return sha512_hash

urls = "https://crypto-payment.alchemytech.cc/XXXXX"
appId = "XXXXX"
secret = "XXXXX"
req_data = {
    "merchantOrderNo":"XXXXX",
    "appId":appId,
}

sign = sha512_sign(req_data, secret)
req_data["sign"] = sign

print(requests.post(urls, json=req_data).text)
package main

import (
	"bytes"
	"crypto/sha512"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"net/http"
	"sort"
	"strings"
)

func sha512Sign(dataMap map[string]string, secretKey string) string {
	keys := make([]string, 0, len(dataMap))
	for key := range dataMap {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	var queryStrings []string
	for _, key := range keys {
		queryStrings = append(queryStrings, fmt.Sprintf("%s=%s", key, dataMap[key]))
	}
	queryString := strings.Join(queryStrings, "&")


	stringToSign := queryString + "&key=" + secretKey
	fmt.Println("String to sign:", stringToSign)


	hash := sha512.New()
	hash.Write([]byte(stringToSign))
	signature := hex.EncodeToString(hash.Sum(nil))
	return strings.ToUpper(signature)
}

func main() {
	url := "https://crypto-payment.alchemytech.cc/XXXXX"
	appId := "XXXXX"
	secret := "XXXXX"


	reqData := map[string]string{
		"merchantOrderNo": "XXXXX",
		"appId":           appId,
	}


	sign := sha512Sign(reqData, secret)
	reqData["sign"] = sign

	jsonData := "{"
	for key, value := range reqData {
		jsonData += fmt.Sprintf("\"%s\":\"%s\",", key, value)
	}
	jsonData = jsonData[:len(jsonData)-1] + "}"

	resp, err := http.Post(url, "application/json", bytes.NewBuffer([]byte(jsonData)))
	if err != nil {
		fmt.Println("Error sending request:", err)
		return
	}
	defer resp.Body.Close()


	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}

	fmt.Println("Response:", string(body))
}