# Introduction

This document provides an overview of Actyve API. By integrating traditional payment methods with distributed ledger technology, Actyve provides a seamless way for businesses to send and receive payments globally. Its borderless, fast, and secure features make it accessible to a wide range of users.

# SDK Download

Java SDK Download (opens new window)

# APP Access Process

# Get App ID and App Secret

Please contact Actyve Dev Team to get your unique app_id and app_secret for making calls to the API

Note:

app_id is the unique identification of the web app

app_secret is the key of the web app

Actyve Public Key is for notification validation

# Public Key

Public key is used to verify the API requests. Please contact Actyve Dev Team to provide your public key information.

# IP WhiteList

Please contact Actyve Dev Team to provide the IP address for whitelist. To help your integration operate securely, we must verify that it’s communicating through one of our listed IP addresses.

If your integration also receives webhooks from us, make sure these events originate from a whitelisted IP address.

# API Call Description

# Host

  1. Sandbox: https://sandbox-api.actyve.io

  2. Production: https://api.actyve.io

# Http Method

GET/POST

# Common Header


# Sign

Signature is the verification of the body of the messages during the interaction between the Actyve and the merchant. Signature usually occurs in post http request. There is also a webhook message used by Actyve to notify merchants of data changes.

Actyve uses the RSA private key to decrypt, and the RSA public key to sign.Therefore, during the API interaction, there are merchant RSA public and private keys and Actyve RSA public and private keys.

The signing rules are as follows:

  1. The merchant sends a request to Actyve, the merchant uses its own RSA private key to sign, and Actyve uses the merchant's RSA public key to verify the signature;
  2. Actyve sends a notification to the merchant, Actyve uses its own RSA private key to sign, and the merchant uses the Actyve RSA public key to verify the signature;
  3. Signing is to encrypt the http request body, app_id,timestamp,For specific rules, see the following signature example;
  4. Whether it is the public and private keys of the merchant or the platform, the generation method is to use the PKCS8 padding method and 2048 length Tool (opens new window);
  5. sign out and base64 as the signed string;
  6. Put the encrypted string in the header Sign.

# JAVA Sample code

package com.by.developer.sdk.aop;

import org.apache.commons.codec.binary.Base64;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class SignTest {

    /**
     * 参数签名(${appId}${timestamp}${requestBody})
     * @param content
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String sign(String content,String privateKey) throws Exception {
        Signature signature = Signature.getInstance("SHA256WithRSA");
        PrivateKey prk = getPrivateKeyFromPKCS8("RSA",privateKey);
        signature.initSign(prk);
        byte[] bytes = content.getBytes("UTF-8");
        signature.update(bytes);
        byte[] signed = signature.sign();
        return Base64.encodeBase64String(signed);
    }

    public static boolean signCheck(String content,String sign, String publicKey) {
        try {
            PublicKey pubKey = getPublicKeyFromX509("RSA", publicKey);
            java.security.Signature signature = java.security.Signature.getInstance("SHA256WithRSA");
            signature.initVerify(pubKey);
            signature.update(content.getBytes("UTF-8"));
            return signature.verify(Base64.decodeBase64(sign.getBytes()));
        } catch (Exception e) {
            return false;
        }
    }

    private static PrivateKey getPrivateKeyFromPKCS8(String algorithm, String privateKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        byte[] encodedKey = privateKey.getBytes();
        encodedKey = Base64.decodeBase64(encodedKey);
        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }

    private static PublicKey getPublicKeyFromX509(String algorithm, String publicKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        byte[] encodedKey = publicKey.getBytes();
        encodedKey = Base64.decodeBase64(encodedKey);
        return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }

    public static void main(String[] args) throws Exception {
        //partner app id
        String appId = "1569641270953589504";
        //request time
        Long timestamp = 1666332361000L;
        //partner rsa private key
        String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALxGyg3/boLT2I8dQnC3Njc2XIDJgZM/G4wqsDDUVoy/PQ2THA39sKHiLsTg71zVbQZ4+UYWm1aTlms7KuBuOmvmdIzKuI04NbSuDeAbAtnraizhELSOpVQFNom2tIGHw4/46VuF3bE0rgFjKGqrRI9xOVEcDGZlP4h9JatQEgytAgMBAAECgYADZ1dX9Awy+A+NlAFm4BQrcXFy1xt7GIGUHaSUCe3N7sxY45uB+F+vyVh6aJm74QlCaJvmQv62Lg5t1HOQ2pcHD6/r7G0lykjYJ3JEAmF3KKm/FgPqX9MGqZCBNHp3oQaHMf8WwRfjxr/EBT1QfdItCGjiENJ4bjSJo9qzEPtjSQJBAMx/r6clsTUdpeskw60UMJG17Af5Fc/SNCsq8hdmCqva0QtT1l/vprmwEH1hKXlA9au9cIESp0ceABH86jE9Vu8CQQDrsTt/S6iiWAiJKA8eYWSEcPyQXoB+tveg4ZoKUwG+fT5t9tXOuPZGmC7CWsAATfO88/ySGqNyIlFgSDvTM3YjAkB+c9JdLCyI6L1pSwGIq/xgjbrXL0oyiQvjSZoLp/ifTh6Hv57HEfzpw5pevU8VAHspaGoCFlPD4SQv+1GhgwmXAkAd6grBJ1sp7751mg4BLx9Q5/5GXJg2fQaE9t1UPiDUipTn5BJTAIrRfvNAW8BOyZYL/3OpH5RrIgvuCnz9W2S9AkB19MQtKSc3Ba36Jo3C0kvTdeSDBR4o+ah+bzhwg/Hj8EKYp4IoyW8mx32WXtSLGp8OjupPlZ65PUkzy838Eo8v";
        //partner rsa private key
        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8RsoN/26C09iPHUJwtzY3NlyAyYGTPxuMKrAw1FaMvz0NkxwN/bCh4i7E4O9c1W0GePlGFptWk5ZrOyrgbjpr5nSMyriNODW0rg3gGwLZ62os4RC0jqVUBTaJtrSBh8OP+Olbhd2xNK4BYyhqq0SPcTlRHAxmZT+IfSWrUBIMrQIDAQAB";
        // post request json body,read from request stream
        String requestBody = "{\"grant_type\":\"client_credentials\",\"app_id\":\"1569641270953589505\",\"app_secret\":\"bc2ead7739f447c49032b4aef7818c47\"}";

        //generate rule
        String signContent = appId + timestamp + requestBody;
        String sign = sign(signContent,privateKey);
        System.out.println(sign);
        System.out.println(signCheck(signContent,sign,publicKey));
    }
}



# Errors

If a request fails, we will respond with error details. If the response is not received, it may mean that the network has timed out, and please try again

#

Response code Description
B_XXXX Bad request - Missing parameters, incorrect shape, or failed on another validation test
B_Common_AuthError Unauthorized - Please verify that the authentication token is provided and valid
B_Common_NotFound Not found - The requested endpoint does not exist
S_XXXX The request is interrupted, which may be an unknown exception, or it may trigger some of our business rules and cause the process to be interrupted. Please contact Actyve Dev Team.

# Error Codes

Response code Description
S_Common_SystemError which may be an unknown exception, causing the process to be interrupted. Please contact Actyve Dev Team
B_Common_ParamError A provided argument has an incorrect type or failed a validation test
B_Outbound_RateExpiredError Exchange rate expired

# Failed Sample Response

{
  "code": "S_Common_DivError",
  "message": "app_id is invalid"
}

# Success Sample Response

{
  "code": "SUCCESS",
  "message": null,
  "data": {}
}