Onerway
Get Started

Request signing

Learn the two Transfer API signing methods and their examples.

Transfer APIs provide two signing methods: SHA256withRSA and SHA256. Use the method assigned to your merchant by Onerway.

Before you start

Confirm your merchant's signing method first. The signing key type, canonical string rule, and generated signature format differ between the two methods.

SHA256withRSA

Signing steps

  1. Obtain the privateKey
  2. Use the SHA256withRSA algorithm
  3. Convert the canonical string into UTF-8
  4. Generate the signature
  5. Base64-encode the signature result

Canonical string rule

Remove all parameters whose values are empty, sort the remaining parameters by ASCII order of the parameter name, and concatenate them in the format key=value&key1=value1.... Do not append & after the last parameter.

Example private key

MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDHaM7clWWlJNS6
ZR5ZkxSFeMMFt74YGRmYPr67UHrfc4CzFtN9sctIUqZJVv05sfOgnb0rk1G7wx97
/LqxPEGs5chc+Nq9HkNf5VopMifOQ85j1Sv1U031oEGk+Oi4MTAR4ZWlLKBQPyKV
b5pCP8aIv15GTIiIwJKS17zY5mQUrXzASTDk54DCG9eN4Lgka9xzwRvaYZvmxLg7
32GxjI5TE797kA5gxY7GxZ0wxdkWkhcee6xX6WWhAcmdHPUUS0EPcnL5wcc3wP07
vO+R/jO1XoaXczb6JRh6ApR3Y5VjSFQApqwe7AIgASGf8aSkBU4K95RfZ3QsBjof
2SX/3fkf

Example request data

{
  "key": "value",
  "key2": "value2",
  "key1": "value2",
  "sign": "RcqXuiVp1JpwJedRGzTpL8M5mUsfeHL29gV9ycaJwmDoNV21AiaQ41au2qiJ8h+jKn/KBMcrJAzHGBTO3CZ0ffGxmqNz9fKhZX+X1MTntH+MhtKTyKR4ZF8kbAtezdVgPfqT69NPQGbWo57R3KP0m4W4n2ZjgkxkcG3yYtBdAgsyxDNoT8W0wH7nK7Y0zp88O8wIMe7kfBnK59J4y0Xz2EwiFX+bNkfRhf3U5WiHIU2TdRbaYsnzndmOkYkVdFAiUH7zoXnEn8ZVqiDZkK4eFG9H1LxU55dStug1hLtwxOKlu5OYFUi4iGAiq0Vlir01eDR1++KAudOdb1gcUyH2rA=="
}

Example canonical string

key=value&key1=value2&key2=value2

Example signature result

RcqXuiVp1JpwJedRGzTpL8M5mUsfeHL29gV9ycaJwmDoNV21AiaQ41au2qiJ8h+jKn/KBMcrJAzHGBTO3CZ0ffGxmqNz9fKhZX+X1MTntH+MhtKTyKR4ZF8kbAtezdVgPfqT69NPQGbWo57R3KP0m4W4n2ZjgkxkcG3yYtBdAgsyxDNoT8W0wH7nK7Y0zp88O8wIMe7kfBnK59J4y0Xz2EwiFX+bNkfRhf3U5WiHIU2TdRbaYsnzndmOkYkVdFAiUH7zoXnEn8ZVqiDZkK4eFG9H1LxU55dStug1hLtwxOKlu5OYFUi4iGAiq0Vlir01eDR1++KAudOdb1gcUyH2rA==
<dependency>
  <groupId>commons-codec</groupId>
  <artifactId>commons-codec</artifactId>
  <version>1.14</version>
</dependency>
package xxx;

import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;

public class RSASecureDemo {
    public static String signRSA(String privateKey, String toBeSignedData) {
        try {
            byte[] keyBytes = Base64.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(priKey);
            signature.update(toBeSignedData.getBytes(StandardCharsets.UTF_8));
            return Base64.encodeBase64String(signature.sign());
        } catch (Exception e) {
            throw new RuntimeException("rsa sign failed");
        }
    }

    public static void main(String[] args) {
        String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDHaM7clWWlJNS6" +
            "ZR5ZkxSFeMMFt74YGRmYPr67UHrfc4CzFtN9sctIUqZJVv05sfOgnb0rk1G7wx97" +
            "/LqxPEGs5chc+Nq9HkNf5VopMifOQ85j1Sv1U031oEGk+Oi4MTAR4ZWlLKBQPyKV" +
            "483/Axmrwea50UKLqRVH3IXzTOEJth0betqTmbefYFLETn5RXB6MOJQOdzpvvcP3" +
            "05FmtT/grqqcnaeLbosT4A==";

        String toBeSignedData = "key=value&key1=value2&key2=value2";
        String sign = signRSA(privateKey, toBeSignedData);
        System.out.println(sign);
    }
}

SHA256

Signing steps

  1. Obtain the secret key
  2. Concatenate the canonical string and the secret key as strings
  3. Convert the result into UTF-8
  4. Apply the SHA-256 digest
  5. Convert the digest into a hexadecimal string

Canonical string rule

Remove all parameters whose signing column is No and parameters whose values are empty. Sort the remaining parameters by ASCII order of the parameter name, concatenate only the parameter values, and then append the secret key.

Example secret key

3b5e10b65bff4172a5b9ca2d2ec00a6e

Example request data

{
  "merchantNo": "800135",
  "test": "dsaaass1dsag",
  "bizContent": "yesdas1dsa",
  "as": "12334567",
  "bc": "098754"
}

Example canonical string

12334567098754yesdas1dsa800135dsaaass1dsag

Example signature result

0ce84cc90742e79b3af76da6b6909dc158a2e933057562639fe6a5a8e73f5350
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.6</version>
</dependency>
package xxx;

import org.apache.commons.lang3.StringUtils;
import java.security.MessageDigest;
import java.util.TreeMap;

public class SHA256SecureDemo {
    public static void main(String[] args) throws Exception {
        TreeMap data = new TreeMap();
        data.put("merchantNo","800135");
        data.put("test","yesdas1dsa");
        data.put("bizContent","dsaaass1dsag");
        data.put("as","12334567");
        data.put("bc","098754");

        String toBeSignedData = strcatValueSign(data);
        String key = "3b5e10b65bff4172a5b9ca2d2ec00a6e";
        String sign = signSha256(key, toBeSignedData);
        System.out.println(sign);
    }

    private static String strcatValueSign(TreeMap treeMap) {
        StringBuffer buffer = new StringBuffer();
        treeMap.forEach((k, v) -> {
            if (StringUtils.isNotBlank((String) v)) {
                buffer.append(v);
            }
        });
        return buffer.toString();
    }

    public static String signSha256(String key, String toBeSignedData) {
        String str = toBeSignedData + key;
        String encodestr = "";
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(str.getBytes("UTF-8"));
            encodestr = byte2Hex(messageDigest.digest());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encodestr;
    }

    private static String byte2Hex(byte[] bytes) {
        StringBuffer stringBuffer = new StringBuffer();
        String temp = null;
        for (int i = 0; i < bytes.length; i++) {
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length() == 1) {
                stringBuffer.append("0");
            }
            stringBuffer.append(temp);
        }
        return stringBuffer.toString();
    }
}

Next Steps