Skip to content

前期准备

请求方式:全部为 POSTContent-Type: application/json

请求头

Header必填说明
api-key商户 API Key,用于识别商户主账号
Content-Typeapplication/json

账号与密钥

仅主账号可调用(子账号不可用)。商户须先在后台上传 RSA 公钥,并持有:

  • api-key:请求头鉴权
  • apiSecretKey(签名密钥):参与 MD5 签名
  • RSA 私钥:对 MD5 结果加密,得到 sign

RSA 密钥对生成

接入前需自行生成一对 RSA 密钥,并按下列方式使用:

  1. 生成 2048 位 RSA 密钥对(PKCS#8 私钥 + X.509/SPKI 公钥)
  2. 输出为 单行纯 Base64:无 -----BEGIN/END----- 头尾,无换行、无空格
  3. 公钥 上传至商户后台(用于服务端验签)
  4. 私钥 仅由商户侧保管,用于请求签名;切勿泄露或提交到后台
  5. 公私钥必须成对使用;更换密钥后需同步更新后台公钥
  6. 私钥请商户自行保管,切勿透漏给任何人。我司不会以任何形式任何理由向贵方索要RSA的私钥。
  7. 私钥如果泄露,需要立马自行生成对应的RSA加密密钥对,并到商户后台中上传[公钥]

示例RSA加密对

以下提供一个rsa加密对,可用于测试

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAytFhze7xM54M35t5sxDknH63bXNqz3Oe1jgfL43U1MLi/xD+Owu6uENGV41ZwofMDcB0j2R9KgpNV08PhYB0+LkRoGnF5WpVlWbcFEXdpYHthDvB5gIBXOvl1GFkoLNvdoDMSI5MNqwyxR/AzopuZUTUXE294apRDmTa9nCw/PjKuWBroaAmNhAPRx66yQxQSKFly377qfYZp7p2UF+EcJkZuO0IelEn+VVmbAlqiwjYSvxqBk/LEcE7PSUJ/42poJ47XTvft1U4iQuWzjiCuAYCCmAwLeARuZB0SphCgEhBLPdaOJVxxJ7Bfjbktm4mIpkDjDQ5yiCmSIYmiohqoQIDAQAB
text
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDK0WHN7vEzngzfm3mzEOScfrdtc2rPc57WOB8vjdTUwuL/EP47C7q4Q0ZXjVnCh8wNwHSPZH0qCk1XTw+FgHT4uRGgacXlalWVZtwURd2lge2EO8HmAgFc6+XUYWSgs292gMxIjkw2rDLFH8DOim5lRNRcTb3hqlEOZNr2cLD8+Mq5YGuhoCY2EA9HHrrJDFBIoWXLfvup9hmnunZQX4RwmRm47Qh6USf5VWZsCWqLCNhK/GoGT8sRwTs9JQn/jamgnjtdO9+3VTiJC5bOOIK4BgIKYDAt4BG5kHRKmEKASEEs91o4lXHEnsF+NuS2biYimQOMNDnKIKZIhiaKiGqhAgMBAAECggEABGtZ4MHmhwTwN89+cDg3m4h8MqgQk1f0FavSE+Qov3i2R5ebKw4kN8V1QQVSL8m7yL9NOOZIHwpLvXGyS1rhXZ2yfmjcnlVF+3IS/MT5lZSQWGSxEsP/m6rDGqDDR5hGVxYrEWAKpYi0t+BzaAq6mWW9tPvPjc0rTEuGvQbHSAFRuDGnXchNiwx4onMHk5F2i/2mGvghciu1iE/sbkHkxCoRWihwBLzQpcCbcvwuAY4I1AohW6w8zFKmRO1EkMbJTXByjwpL3QEEWuvYWlEx3W1n8BohM07FtmKN4fFaBeFueHlLeT42WEA1Pf2Ysp+CbBAEtsk/iX3AD0yJzYR3QQKBgQD5/8QTZ9W7Od2C+s1lIsdgTU0A5upBQa203mwsv52MRilB6iW05I54pNrZUhETFZrvCXaf/ytjW39DX+PaQKj091JQ2SQ9b3NRaFsS/o+dR6F/yYzfRCJfFQcUF8wLyPnwXG0ZylzREufba14H4rmwRWiwIPND6n8EzESKYt9swQKBgQDPr7COtlFe3ziA/CCoo3d8tDtRj6wTf/Uh18L1VrqU4VeZhDrOEPsc/CemBRn746Y7wCvpCvwkbk7QbbFo1aLzYDSpe7LErKQkb+giTiLG4rYWrg39JQQsqYq744qxICE0wmXE105XtIi4wv7VZ23jVVNeMXmEe6TIAJgn2b4V4QKBgE+13S7SzLMFoDtC/HpivG9YNlUzSz3DUz94K8WY0wMG2+DIZ31l4odVCPKB2C/dk6jju48ILS1g3xL8YAoW08hHk1dz5Lox7vLl8yP7Ro8/Z573BJOrhcoLSlZ9v/GCAy9ASQkQHMgM3yB2+2RIRiyN9PMzjlz5R8af2rrFC7gBAoGADY6UYdx4106O66yJnTh+dj91l89fFi7GG51v9n/g0hMbmsPM6uKk4bF8DRRMK+siUMgslZvH9cDVmDlw2T0I1AY1qdKPStNSK6a6anLbRkxKQpS+CQY/jYLLsZQa25ETWdROvFipnoQEYLsp01hbDfnl5UIpgoJnsT6IsCFAjUECgYA0cx0bfV5D8EOAZ4QgPD2hm30wpoe30dP76yenyknPp5G1IdmXl+MmNcOzn5RG5JiZTtlYKUmiq9sWtRPf48dttJzmfhcYoJ2MONnDN7myaDgIt9hK0OzZxOPaJYw1myl+085He91MfbXMiOjPIKkN6tsM2JRKD2xyr+LiyFNL4Q==

RSA密钥对生成方法
java
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.Base64;

public class RsaKeyGen {
    public static void main(String[] args) throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048);
        KeyPair keyPair = generator.generateKeyPair();

        // Base64.getEncoder() 本身即为无换行、无空格
        String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
        String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());

        System.out.println(publicKey);
        System.out.println(privateKey);
    }
}
ts
// Node.js:npx ts-node rsa-keygen.ts
import { generateKeyPairSync } from 'crypto'

const { publicKey, privateKey } = generateKeyPairSync('rsa', {
  modulusLength: 2048,
  publicKeyEncoding: { type: 'spki', format: 'der' },
  privateKeyEncoding: { type: 'pkcs8', format: 'der' },
})

// Buffer.toString('base64') 为无换行、无空格的纯 Base64
console.log(publicKey.toString('base64'))
console.log(privateKey.toString('base64'))
sh
# 输出:公钥、私钥均为无头尾、无换行的纯 Base64
# 私钥强制为 PKCS#8(Java / Hutool 可直接加载)

# 1. 生成密钥(先出 PEM,再统一转 DER,避免 PKCS#1)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem

# 2. 私钥:强制转 PKCS#8 DER → 纯 Base64
openssl pkcs8 -topk8 -nocrypt -in private.pem -outform DER -out private.der
PRIVATE_KEY=$(base64 -w 0 private.der)

# 3. 公钥:X.509/SPKI DER → 纯 Base64
openssl pkey -in private.pem -pubout -outform DER -out public.der
PUBLIC_KEY=$(base64 -w 0 public.der)

# 4. 校验私钥必须是 PKCS#8(应以 MIIEv 开头;若是 MIIEow / MIIEpA 则是 PKCS#1,不能给 Java 用)
echo "公钥:"
echo "$PUBLIC_KEY"
echo
echo "私钥:"
echo "$PRIVATE_KEY"
echo
case "$PRIVATE_KEY" in
  MIIEv*) echo "格式校验:PKCS#8 OK,可用于 Hutool / Java" ;;
  *) echo "格式校验:失败!私钥不是 PKCS#8,请勿使用" ; exit 1 ;;
esac

echo "$PUBLIC_KEY" > public.b64
echo "$PRIVATE_KEY" > private.b64
rm -f private.pem public.der private.der

调用注意

  1. 主账号api-key 可用。
  2. 每次请求必须重新计算 timestampsign
  3. 签名参与字段为请求体中所有非空字段(不含 sign),空字符串字段不参与签名。
  4. orderNo 建议使用商户侧全局唯一编号,避免重复提交。
  5. 出款地址、反查 URL 需按后台「出款配置」加白后才能使用。
  6. 充值/出款结果也可通过配置的 notifyUrl 异步通知(以实际业务回调为准)。