Skip to content

Global Specification

This section describes the global communication standards of the RivaaPay API, including request methods, signature algorithms, and signature utility code examples.


1. Request Method

Transaction TypeHTTP MethodContent-TypeNote
Order Creation & QueryPOSTapplication/json; charset=utf-8Request from Merchant to Platform
Async Notification CallbackPOSTapplication/json; charset=utf-8Notification from Platform to Merchant

2. Request Headers

For all API requests, the following parameters must be included in the HTTP Header for identity verification:

ParameterRequiredTypeDescription
merchantNoYesstringThe merchant number, assigned and provided by the platform.
signYesstringThe RSA-SHA256 signature value (Base64 encoded) of the request body JSON string.

3. Signature Algorithm

  1. Construct Parameters: Construct the request body object according to the parameters specified in the API documentation.
  2. Format JSON: Serialize the request body object into a standard JSON string (ensure field structures remain consistent).
  3. Sign & Verify:
    • Merchant Request: The merchant signs the JSON request body using their own RSA Private Key and places the Base64 signature result into the sign header. The platform verifies it using the RSA Public Key provided by the merchant.
    • Platform Notification: When the platform sends callbacks, it signs with the platform's private key. The merchant must verify this signature using the Platform Public Key.

Platform Public Key for Testing

IMPORTANT

Below is the platform public key for the test environment to verify notifications. The production public key will be issued by the platform after the integration is completed:

text
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0kr9IpgDckceWl1g8IRAMV6hALHspEb+SzIsrcc2+Q9WSot/c9YbRZzd+yuzkazMv4HAHeW7oLkG1lcxFYxgPM2x0GbhWqy1Yk5iiARS0h3E2mbuDy7neaL9DzZ411Xwq/pcoEAaklJtwwkXwlIcJGVHUFAebX6Yc6BitcfSvjZe7ilyVX0LA2aTxRGoF490gWo3R7TEXK/Lmdh/rC6FldyexdlAoc1DYbCBFZJQXxJReBbvNj+jJi1BsrsrbrKXBHd9M7/vzBwrHGDa09Y4Yw1wVPm+ZRFFs8hC3bVlZWrpOrR9o9S9kSH47YmnHDPve8fK9/ySEHp6JZ0QxJOnd6DQ0uGdAWswWlIZ4Jjg2qJxC6PHmoRYeWjyc9BuekUtDv9Yiyi9SBfGJQJStjC9PksKsMtUCGaoszPMLhMDGCX9mvYKuxK+vHDK3csWu2iRtX9TIulk/ojNsoZkSKV9tnsmiPFKb9vD79k2RiRyKYVlwpLe9Gyq/joN32i6qIyuN7h5iyms+mxya3DiGNNGdrYwaRGK+nwyJtuZJ9LI8GvWjcq5hVDeAgYnUs16N/ujCbWzHpvzDpmZxgJHXxHPk9TAFzrbTUJQ4p6TBpY87NHb2ozJcOFkFzoYEmqMhivM7vn4gqmd/r1z7PNfjNpJK2dv7pjUQ28S9FEZnsnnJecCAwEAAQ==

4. Java Signature Tool Example

java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class SignUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(SignUtil.class);

    /**
     * Verify signature
     *
     * @param param     Original JSON string
     * @param sign      Base64 signature value
     * @param publicKey RSA public key string (Base64)
     * @return Whether verification passed
     */
    public static boolean checkSign(String param, String sign, String publicKey) {
        try {
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initVerify(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey))));
            signature.update(param.getBytes());
            return signature.verify(Base64.getDecoder().decode(sign));
        } catch (Exception e) {
            LOGGER.error("Signature verification error: ", e);
        }
        return false;
    }

    /**
     * Generate signature
     *
     * @param param      JSON string to sign
     * @param privateKey RSA private key string (Base64)
     * @return Base64 signature string
     */
    public static String sign(String param, String privateKey) {
        try {
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey))));
            signature.update(param.getBytes());
            byte[] bytes = signature.sign();
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            LOGGER.error("Signature generation error: ", e);
        }
        return null;
    }
}

5. Request Sending Example (Java)

java
Map<String, Object> map = new HashMap<>();
map.put("timestamp", String.valueOf(System.currentTimeMillis()));
map.put("merchantOrderNo", "ORDER_123456789");
// ... Populate other parameters

String body = gson.toJson(map);
String sign = SignUtil.sign(body, merchantPrivateKey);

HttpResponse<String> stringHttpResponse = Unirest.post("https://api.xxx.com/payin/create")
        .header("Content-Type", "application/json; charset=utf-8")
        .header("merchantNo", "M1639466186292")
        .header("sign", sign)
        .body(body)
        .asString();

6. Merchant RSA Key Pair Generation (Java)

java
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;

public class KeyPairGen {
    public static void main(String[] args) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(4096);
        KeyPair keyPair = keyPairGenerator.genKeyPair();

        // Public Key
        PublicKey publicKey = keyPair.getPublic();
        String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKey.getEncoded());
        System.out.println("----- Public Key (Provide to Platform) -----");
        System.out.println(publicKeyBase64);

        // Private Key
        PrivateKey privateKey = keyPair.getPrivate();
        String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKey.getEncoded());
        System.out.println("----- Private Key (Keep Secret) -----");
        System.out.println(privateKeyBase64);
    }
}