Skip to content

全局说明

本章节介绍 RivaaPay 接口的全局交互规范,包括请求方式、签名算法以及签名工具代码示例。


1. 请求方式

交互类型请求方法Content-Type备注
订单创建、查询POSTapplication/json; charset=utf-8商户向平台发起的请求
异步通知回调POSTapplication/json; charset=utf-8平台向商户发送的通知

2. 请求头 (Request Headers)

在请求所有接口时,必须在 HTTP Header 中携带以下参数以作身份校验:

参数名是否必填类型说明
merchantNostring商户号,由平台统一分配提供。
signstring请求体 JSON 字符串的 RSA-SHA256 签名值(Base64 编码)。

3. 签名算法说明

  1. 构造参数: 按照具体接口的参数定义,构造请求体对象。
  2. 格式化 JSON: 将请求体参数格式化为标准的 JSON 字符串(注意保持字段结构一致)。
  3. 加签与验签:
    • 商户发送请求: 商户使用自己的 RSA 私钥 对 JSON 请求体进行签名,并将签名结果放入 Header 的 sign 字段中。平台会使用商户提供的 RSA 公钥 进行验签。
    • 平台回调通知: 平台发送通知时,会使用平台的私钥签名。商户收到后,需要使用 平台公钥 进行验签。

平台测试公钥

IMPORTANT

以下为测试环境的平台公钥,用于验证平台回调的签名(正式环境公钥,在商户后台-账号信息查看):

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

4. Java 签名工具示例

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);

    /**
     * 验证签名
     *
     * @param param     原始 JSON 字符串
     * @param sign      Base64 签名值
     * @param publicKey RSA公钥字符串 (Base64)
     * @return 验签是否通过
     */
    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("Sign校验错误 :", e);
        }
        return false;
    }

    /**
     * 生成签名
     *
     * @param param      待加签的 JSON 字符串
     * @param privateKey RSA私钥字符串 (Base64)
     * @return 签名后的 Base64 字符串
     */
    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("Sign签名错误 :", e);
        }
        return null;
    }
}

5. 请求发送示例 (Java)

java
Map<String, Object> map = new HashMap<>();
map.put("timestamp", String.valueOf(System.currentTimeMillis()));
map.put("merchantOrderNo", "ORDER_123456789");
// ... 填充其他业务参数

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

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

6. 商户 RSA 密钥生成示例 (Java)

6.1 在线生成工具

a.公私钥生成工具链接(选择1024位,2048位,4096位/格式PKCS#8):https://www.bejson.com/enc/rsa/#18

b.用这个链接去除一下换行再上传:http://www.wuqianling.top/software/notepad/compress.html

1.使用密钥生成工具,生成密钥对,长度必须是1024bit,2048bit,4096bit,格式必须是 PKCS#8

2.将生成密钥对中的公钥,去除换行后复制,上传到商户后台。不要 -----BEGIN *** KEY-----,-----END *** KEY-----。

3.公钥上传完成后,请妥善保管私钥。

4.如对接过程,加密等问题,可以发送请求参数至群里,并艾特我们客服或者技术人员

5.对于回调签名,请使用平台公钥,进行解密验证,切勿使用商户公钥(您自行生成的公钥)

6.2 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();

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

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