> ## Documentation Index
> Fetch the complete documentation index at: https://doc2.payloco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Signing Tool

* Last Updated: 2022-07-05 13:50:33

## Overview

* The open platform uses a public/private key mechanism for application management. Merchants can configure a **public key / public key certificate** for their application under Key Management in the open platform to prevent data tampering and ensure the security of interactions between merchant applications and the platform.

## Terminology

1. **Public Key**: The application public key (`public_key`), generated by the developer using a key generation tool.
2. **Private Key**: The application private key (`private_key`), generated by the developer using a key generation tool.
3. **Platform Public Key**: Generated by the open platform after the developer uploads their application public key. Used by developers to verify signatures on asynchronous or synchronous messages from the platform.

## Signature Algorithm

| Signature Algorithm | Standard Algorithm | Description                                |
| :------------------ | :----------------- | :----------------------------------------- |
| RSA                 | SHA256WithRSA      | RSA key length must be at least 2048 bits. |

## Features

* If you are unfamiliar with the API call method, please review the API Call Conventions documentation first.

* Every API call must include a signature. The server validates the signature against the request parameters. Requests with invalid signatures will be rejected. The main purposes are:

  * Verify the integrity of each request's parameters on both the service provider and platform sides.

  * Verify the identity of the requester on both the service provider and platform sides.

## Signature Calculation

### Java — Sign Reference Code

```java theme={null}
    // Generate private key
    /**
     * Get private key
     *
     * @param privateKey private key string
     * @return PrivateKey
     */
    public static PrivateKey getPrivateKey(String privateKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * Sign
     *
     * @param data       data to sign
     * @param privateKey private key
     * @return signature
     */
    public static String sign(String data, PrivateKey privateKey) throws Exception {
        byte[] keyBytes = privateKey.getEncoded();
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey key = keyFactory.generatePrivate(keySpec);
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(key);
        signature.update(data.getBytes("UTF-8"));
        return new String(Base64.encodeBase64(signature.sign()));
    }
```

### Java — Verify Signature Reference Code

```java theme={null}
    /**
     * Get public key
     *
     * @param publicKey public key string
     * @return PublicKey
     */
    public static PublicKey getPublicKey(String publicKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
        return keyFactory.generatePublic(keySpec);
    }
```

```java theme={null}
    /**
     * Verify signature
     *
     * @param srcData   original string
     * @param publicKey public key
     * @param sign      signature
     * @return whether verification passed
     */
    public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
        byte[] keyBytes = publicKey.getEncoded();
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey key = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(key);
        signature.update(srcData.getBytes("UTF-8"));
        return signature.verify(Base64.decodeBase64(sign.getBytes()));
    }
```

If you are using another language, refer to the code above to implement it yourself.

### Signature Algorithm:

```text theme={null}
1. Fields included in the signature: the entire JSON request body participates in signing.
2. Signature algorithm: SHA256withRSA.
```

#### Note:

<Warning>
  When computing the SHA256withRSA signature, the byte stream must be encoded in UTF-8. Otherwise, signature calculation for parameters containing non-ASCII characters (e.g. Chinese) may be incorrect.
</Warning>

### Request Example:

```http request theme={null}
POST /v2/payments/open/api/pay HTTP/1.1
Host: gate.payloco.com
signature: M+CSWJPVOxHHyT2K85VzGifLx7UrF2LYA/V9ATFQFa75WvCwZ3T0mcBIcptn/s+T/i/X2FElVSpL0S7WMiNU70Lg+DeNtgic+4BfwVGoMhX5Mq0pkrriruArZHI58/5bs1S98SFvjciiBpZnN3xziuwHWRoW6yO3anp1/XKTbVc=
Content-Type: application/json;charset=utf-8

{
  "version": "2.0.0",
  "keyVersion": "1",
  "charset": "UTF-8",
  "transType": "PAY",
  "accessType": "s2s",
  "signType": "RSA",
  "memberId": "851220000002",
  "requestTime": "2026-06-16T20:53:26.6223951+08:00",
  "appId": "11111111",
  "merchantId": "851220000002",
  "data": {
    "captureMode": "merchantId",
    "merchantOrderId": "1781614406638",
    "integrate": "Direct",
    "subject": "Test",
    "totalAmount": 10.24,
    "currency": "HKD",
    "country": "HK",
    "userId": "1781614406639",
    "expireTime": "10000",
    "paymentDetail": {
      "paymentMethodType": "WALLET",
      "targetOrg": "ALIPAYHK"
    },
    "goodsDetails": [
      {
        "goodsName": "Test Item",
        "goodsId": "1781614406642"
      }
    ],
    "terminalType": "APP",
    "osType": "IOS",
    "frontCallbackUrl": "https://www.google.com",
    "notifyUrl": "https://www.google.com"
  }
}
```
