Skip to main content
Every message you exchange with Gcashier Pay is protected by three overlapping security mechanisms working together. AES/ECB/PKCS7Padding encrypts the JSON payload itself so the body stays confidential in transit. RSA/ECB/PKCS1Padding wraps the ephemeral AES session key so only the intended recipient can recover it. SHA1withRSA signs the plaintext payload so neither party can tamper with the message without detection. Understanding how these three layers interact is the foundation for a correct integration.

Algorithms at a glance

ConcernAlgorithmKey size
Payload encryptionAES/ECB/PKCS7Padding128-bit session key
Session key protectionRSA/ECB/PKCS1Padding2048-bit RSA
Message signingSHA1withRSA2048-bit RSA
TransportHTTPS 1.2
Text encodingUTF-8
Content-Typeapplication/json

POST parameters

Every API call is a single HTTPS POST. The request body carries exactly four top-level fields:
ParameterTypeDescription
merchantNoStringYour unique merchant identifier, assigned during onboarding. Included in plaintext so the server can look up your public key.
jsonEncStringBase64-encoded AES ciphertext of your JSON payload.
keyEncStringHEX-encoded RSA ciphertext of the Base64 AES session key. Encrypted with the recipient’s RSA public key.
signStringHEX-encoded SHA1withRSA signature over the JSON plaintext, computed with the sender’s RSA private key.
merchantNo travels in plaintext intentionally — Gcashier Pay uses it to retrieve your RSA public key for signature verification before decrypting anything.

Request and response envelope

Before encryption, every payload shares a common JSON envelope with head and body sections.

Request structure

{
  "head": {
    "version": "1.0.0",
    "tradeType": "00",
    "tradeTime": "1551341750",
    "tradeCode": "sp1301",
    "language": "cn"
  },
  "body": {
    "...": "API-specific fields go here"
  }
}

Response structure

{
  "head": {
    "version": "1.0.0",
    "tradeType": "01",
    "tradeTime": "1551341750",
    "tradeCode": "sp1301",
    "language": "cn",
    "respCode": "S00000",
    "respDesc": "Success"
  },
  "body": {
    "...": "API-specific Response Body"
  }
}

Head field reference

FieldDirectionTypeDescription
versionBothStringAPI version. Current value: "1.0.0".
tradeTypeBothString"00" for requests; "01" for responses.
tradeTimeBothStringUnix timestamp (10-digit seconds). Echo’d back in responses.
tradeCodeBothStringIdentifies the API operation (e.g. "sp1301" for RMB payment).
languageBothStringResponse language preference. "cn" for Chinese, "en" for English.
respCodeResponse onlyStringResult code. "S00000" = success; all other values indicate an error.
respDescResponse onlyStringHuman-readable description of respCode.
Always check respCode before reading body fields in a response. A non-S00000 code means the body may be empty or contain only partial data.

Outgoing request: encryption and signing

The following steps describe exactly what you must do to build a valid outgoing request.
1

Build the JSON plaintext

Assemble your complete request object — head plus all required body fields for the target API operation. Serialize it to a UTF-8 JSON string. This is the value you sign and then encrypt.
{
  "head": {
    "version": "1.0.0",
    "tradeType": "00",
    "tradeTime": "1672531200",
    "tradeCode": "sp1301",
    "language": "en"
  },
  "body": {
    "merchantNo": "M10000001",
    "orderNo": "ORD20240101001",
    "amount": "100.00",
    "currency": "USD"
  }
}
2

Sign the plaintext with SHA1withRSA → HEX

Compute a digital signature over the JSON plaintext using your RSA private key and the SHA1withRSA algorithm. Encode the raw signature bytes as a lowercase HEX string. This becomes the sign POST parameter.
sign = HEX( SHA1withRSA_sign( jsonPlaintext, yourPrivateKey ) )
Sign the plaintext — not the encrypted ciphertext. Gcashier Pay verifies the signature after decrypting, against the recovered plaintext.
3

Generate an AES session key → Base64

Use a cryptographically secure random generator to produce a fresh 128-bit AES key for this request. Base64-encode the raw key bytes. This is your session key SK.
SK = Base64( randomBytes(16) )
A new SK must be generated for every request. Reusing session keys undermines forward secrecy.
4

Encrypt the JSON plaintext with SK → Base64

Encrypt the JSON plaintext bytes using AES/ECB/PKCS7Padding with the session key SK. Base64-encode the resulting ciphertext. This becomes the jsonEnc POST parameter.
jsonEnc = Base64( AES_ECB_PKCS7_encrypt( jsonPlaintext, SK ) )
5

Encrypt SK with Gcashier Pay's RSA public key → HEX

Encrypt the Base64-encoded session key string using Gcashier Pay’s RSA public key with RSA/ECB/PKCS1Padding. HEX-encode the resulting ciphertext. This becomes the keyEnc POST parameter.
keyEnc = HEX( RSA_PKCS1_encrypt( SK, gcashierPayPublicKey ) )
6

POST the four parameters

Submit an HTTPS POST with Content-Type: application/json to the target endpoint. The request body must contain exactly these four fields:
{
  "merchantNo": "M10000001",
  "jsonEnc":    "<Base64 AES ciphertext>",
  "keyEnc":     "<HEX RSA-encrypted session key>",
  "sign":       "<HEX SHA1withRSA signature>"
}

Incoming response: decryption and verification

When Gcashier Pay responds, you receive the same four-field envelope. Process it in this order:
1

Recover the session key from keyEnc

HEX-decode the keyEnc value to get the raw encrypted bytes, then decrypt those bytes with your own RSA private key using RSA/ECB/PKCS1Padding. The result is the Base64-encoded session key SK.
SK = RSA_PKCS1_decrypt( HEX_decode( keyEnc ), yourPrivateKey )
2

Decrypt the payload from jsonEnc

Base64-decode both jsonEnc and SK to their raw byte forms, then apply AES/ECB/PKCS7Padding decryption. The result is the UTF-8 JSON plaintext.
jsonPlaintext = AES_ECB_PKCS7_decrypt( Base64_decode( jsonEnc ), Base64_decode( SK ) )
3

Verify the signature from sign

HEX-decode the sign value to get the raw signature bytes, then verify those bytes against the recovered JSON plaintext using Gcashier Pay’s RSA public key and SHA1withRSA.
valid = SHA1withRSA_verify( jsonPlaintext, HEX_decode( sign ), gcashierPayPublicKey )
Always verify the signature before trusting any field in the decrypted response. A failed verification means the message was tampered with in transit and must be discarded.

The merchantNo field

Your merchantNo is assigned by Gcashier Pay during merchant onboarding. It appears as both a top-level POST parameter (in plaintext) and often as a field inside the encrypted body for certain API operations. The plaintext copy allows Gcashier Pay to resolve your public key before performing any cryptographic operation.

The accessToken field

Some APIs — particularly FX trading and workflows that follow merchant onboarding — require an additional accessToken field inside the head object of the encrypted payload.
{
  "head": {
    "version": "1.0.0",
    "tradeType": "00",
    "tradeTime": "1672531200",
    "tradeCode": "sp1202",
    "language": "en",
    "accessToken": "eyJhbGciOiJSUzI1NiJ9..."
  },
  "body": { "..." : "..." }
}
You obtain an accessToken after your merchant account has been approved through the onboarding API. The token proves your merchant entity has been verified and is required for operations that carry regulatory or financial risk. When an accessToken is required, the individual API reference page will say so explicitly.
Store your accessToken securely and refresh it according to its expiry. Passing an expired or invalid token returns an authentication error in respCode, not an HTTP 4xx status.