API Quick Start
Third-party applications can obtain a store's review data from Trustoo after being authorized by the store. By subscribing to webhooks, you can receive updates on review data.
1.User Authorization Information
After the merchant is required to provide Trustoo's public token and private token, it can obtain authorization from the merchant's Trustoo system. In the following text, Trustoo's public token and private token are all referred to as public token and private token.
1.1 public token Merchant's Public Token
The public token is the unique identifier of the store in the third-party application.
1.2 private token Merchant's Private Token
The private token of the user is a crucial key used to authorize third-party applications to access review information. Please keep it confidential and only provide it to trusted developers. In case of any leakage, please contact us promptly for a reset.
CAUTION
The original private token becomes immediately invalid after a reset. Please contact all authorized third-party applications to update the private token.
TIP
Merchants can view the public token and private token in the Trustoo backend of their store.
2.Trustoo Data Interaction Guide
The API address for our production environment is https://api.trustoo.io/
2.1 Information for Required Headers
HEADER NAME | DESCRIPTION | EXAMPLE |
---|---|---|
public-token | It is the unique identifier of the store in the third-party application. | GfKu22TCaj4gULtrA3/OgA== |
timestamp | This is a Unix timestamp. | 1700465771 |
sign | It is the unique identifier of the store in the third-party application. | c3f6910a4dc12969c819f47621e5adf608e2a33f4db0575988bd4fc19173a582 |
Post Reviews API Doc
This is the detailed content
curl --location --request POST 'https://api.trustoo.io/api/v1/open_api/create_shop_webhook' \
--header 'Public-token: GfKu22TCaj4gULtrA3/OgA==' \
--header 'sign: c3f6910a4dc12969c819f47621e5adf608e2a33f4db0575988bd4fc19173a582' \
--header 'timestamp: 1699934592' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \
--header 'Content-Type: application/json' \
--data-raw '{
"topic":"review/created",
"url":"127.0.0.1"
}'
2.2 Algorithm for Calculating 'sign'
The calculation rule for the signature is as follows: concatenate all data transmitted in the body with the timestamp, and sort them alphabetically. If the first letter is the same, sort them by the second letter, and so on. Concatenate these values into a string 'str' in the form key=value&key=value.
Next, append 'private_token' to 'str' to get 'newStr'. Use SHA-256 encryption on 'newStr' to obtain the final 'sign'.
CAUTION
The timestamp is only valid within 5 minutes. It needs to be regenerated if it exceeds this timeframe.
Example of Generating 'sign' in GO
func TestSignData(t *testing.T) {
data := map[string]string{
"banana": "yellow",
"apple": "red",
"grape": "purple",
"orange": "orange",
"timestamp": strconv.Itoa(int(time.Now().UTC().Unix())),
}
sign := SignData(data, "123")
fmt.Println("=========sign=======:", sign)
}
// SignData signs the data
func SignData(data map[string]string, privateToken string) string {
// 1. Retrieve and sort the keys
var keys []string
for key := range data {
keys = append(keys, key)
}
sort.Strings(keys)
// 2. Traverse the sorted keys and concatenate them into a string
var resultStr string
for _, key := range keys {
value := data[key]
resultStr += fmt.Sprintf("%s=%s&", key, value)
}
// Remove the trailing"&"
resultStr = strings.TrimSuffix(resultStr, "&")
//Add salt
resultStr = resultStr + privateToken
hashed := sha256.Sum256([]byte(resultStr))
return fmt.Sprintf("%x", hashed)
}
Example of Generating 'sign' in JAVA
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;
import java.util.TreeMap;
public class Signer {
public static String signData(Map<String, String> data, String privateToken) {
// 1. Retrieve and sort the keys
TreeMap<String, String> sortedData = new TreeMap<>(data);
// 2. Traverse the sorted keys and concatenate them into a string
StringBuilder resultStr = new StringBuilder();
for (Map.Entry<String, String> entry : sortedData.entrySet()) {
resultStr.append(String.format("%s=%s&", entry.getKey(), entry.getValue()));
}
// Remove the trailing"&"
resultStr.deleteCharAt(resultStr.length() - 1);
// Add salt
resultStr.append(privateToken);
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashed = digest.digest(resultStr.toString().getBytes());
// Convert to hexadecimal string
StringBuilder hexString = new StringBuilder();
for (byte b : hashed) {
hexString.append(String.format("%02x", b));
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
// Handle the exception; here, it simply returns an empty string
return "";
}
}
public static void main(String[] args) {
// Example usage
Map<String, String> data = new TreeMap<>();
data.put("key1", "value1");
data.put("key2", "value2");
data.put("timestamp", "your timestamp");
String privateToken = "your_private_token";
String signature = signData(data, privateToken);
System.out.println("Signature: " + signature);
}
}
PHP
This is the detailed content <?php
function signData($data, $privateToken) {
// Retrieve and sort the keys
$keys = array_keys($data);
sort($keys);
// Traverse the sorted keys and concatenate them into a string
$resultStr = '';
foreach ($keys as $key) {
$value = $data[$key];
$resultStr .= "$key=$value&";
}
// Remove the trailing "&"
$resultStr = rtrim($resultStr, '&');
// Add salt
$resultStr .= $privateToken;
// Calculate SHA-256 hash
$hashed = hash('sha256', $resultStr);
return $hashed;
}
// Example usage
$data = array(
'param1' => 'value1',
'param2' => 'value2',
'timestamp'=>'your timestamp',
// Add other parameters...
);
$privateToken = 'your_private_token';
$signature = signData($data, $privateToken);
echo $signature;
?>
node.js
This is the detailed content const crypto = require('crypto');
function signData(data, privateToken) {
// Retrieve and sort the keys
const keys = Object.keys(data).sort();
// Traverse the sorted keys and concatenate them into a string
let resultStr = '';
for (const key of keys) {
const value = data[key];
resultStr += `${key}=${value}&`;
}
// Remove the trailing "&"
resultStr = resultStr.slice(0, -1);
// Add salt
resultStr += privateToken;
// Calculate SHA-256 hash
const hashed = crypto.createHash('sha256').update(resultStr).digest('hex');
return hashed;
}
// Example usage
const data = {
"topic": 'review/created',
"url": 'value2',
"timestamp": 'your timestamp',
// Add other parameters...
};
const privateToken = 'your_private_token';
const signature = signData(data, privateToken);
console.log(signature);
C#
This is the detailed contentusing System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
class Program
{
static void Main()
{
// Example usage
Dictionary<string, string> data = new Dictionary<string, string>
{
{ "param1", "value1" },
{ "param2", "value2" },
{"timestamp","your timestamp"},
// Add other parameters...
};
string privateToken = "your_private_token";
string signature = SignData(data, privateToken);
Console.WriteLine(signature);
}
static string SignData(Dictionary<string, string> data, string privateToken)
{
// Retrieve and sort the keys
var keys = data.Keys.ToList();
keys.Sort();
// Traverse the sorted keys and concatenate them into a string
StringBuilder resultStr = new StringBuilder();
foreach (var key in keys)
{
string value = data[key];
resultStr.AppendFormat("{0}={1}&", key, value);
}
// Remove the trailing "&"
resultStr.Length--;
// Add salt
resultStr.Append(privateToken);
// Calculate SHA-256 hash
using (SHA256 sha256 = SHA256.Create())
{
byte[] hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(resultStr.ToString()));
return BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
}
}
}