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

# Get Started with the Gcashier Pay API

> Learn how to generate your RSA key pair, exchange credentials, download the demo SDK, and send your first encrypted Gcashier Pay API request.

This guide takes you from a blank slate to a verified API response in six steps. You will generate a 2048-bit RSA key pair, exchange public keys with Gcashier Pay, download the demo SDK, build an encrypted request envelope, and confirm that the test environment returns a successful response. Plan for about 30 minutes the first time through.

<Steps>
  <Step title="Get your credentials from Gcashier Pay">
    Before you can call any endpoint, Gcashier Pay needs to onboard your merchant account. Contact the Gcashier Pay team to begin the process. Once your account is provisioned you will receive two things:

    * **`merchantNo`** — your unique merchant identifier, included as a top-level POST parameter in every request.
    * **Gcashier Pay's RSA public key** — used to encrypt the AES session key you generate for each request.

    Keep both values secure. Your `merchantNo` is not a secret on its own, but Gcashier Pay's public key must come directly from Gcashier Pay — never from a third-party source.
  </Step>

  <Step title="Generate your 2048-bit RSA key pair">
    You need a 2048-bit RSA key pair. You will share your **public key** with Gcashier Pay and keep your **private key** secret on your own infrastructure. Gcashier Pay uses your public key to verify the `sign` field on every inbound request.

    <CodeGroup>
      ```bash macOS / Linux (OpenSSL) theme={null}
      # Step 1: Generate the raw 2048-bit private key
      mkdir -p tmp
      openssl genrsa -out tmp/tmp_rsa_private_key_2048.pem 2048

      # Step 2: Convert to PKCS#8 format (required by the API)
      openssl pkcs8 -topk8 \
        -in tmp/tmp_rsa_private_key_2048.pem \
        -out rsa_private_key_2048.pem \
        -nocrypt

      # Step 3: Extract the public key
      openssl rsa \
        -in tmp/tmp_rsa_private_key_2048.pem \
        -out rsa_public_key_2048.pem \
        -pubout
      ```

      ```bat Windows (genRsakey tool) theme={null}
      REM Download the Windows key generation tool:
      REM https://developer.gcashier.com/files/genRsakey.rar
      REM
      REM Extract the archive, then double-click genRsakey.bat.
      REM The tool writes rsa_private_key_2048.pem and
      REM rsa_public_key_2048.pem to the same directory.
      ```
    </CodeGroup>

    <Warning>
      Never commit your private key (`rsa_private_key_2048.pem`) to source control or transmit it over any channel. If your private key is compromised, regenerate the key pair immediately and re-exchange the new public key with Gcashier Pay.
    </Warning>

    After running the commands, your working directory contains:

    | File                       | Purpose                                        |
    | -------------------------- | ---------------------------------------------- |
    | `rsa_private_key_2048.pem` | Your private key — keep this secret            |
    | `rsa_public_key_2048.pem`  | Your public key — share this with Gcashier Pay |
  </Step>

  <Step title="Exchange public keys with Gcashier Pay">
    Send the contents of `rsa_public_key_2048.pem` to Gcashier Pay through the onboarding channel they provide. In return, Gcashier Pay gives you their RSA public key for the test environment.

    Store both keys so your integration code can load them at runtime:

    * **Your private key** → used to sign outgoing request payloads.
    * **Gcashier Pay's public key** → used to encrypt the AES session key and to verify response signatures.

    <Note>
      Public keys are environment-specific. The test environment key pair and the production key pair are different. Do not mix them up — using a production key against the sandbox (or vice versa) will cause decryption failures.
    </Note>
  </Step>

  <Step title="Download the demo SDK">
    Gcashier Pay provides a demo SDK that includes working encryption utilities, request builders, and sample calls for common API operations.

    <Card title="Download Demo SDK" icon="download" href="https://developer.gcashier.com/files/java_sdk.zip">
      `java sdk.zip` — includes Java source, encryption helpers, and example API calls.
    </Card>

    Extract the archive and open it in your IDE. The key files to review are:

    * **`RsaUtils`** — RSA sign / verify / encrypt / decrypt helpers.
    * **`AesUtils`** — AES/ECB/PKCS7Padding encrypt / decrypt helpers.
    * **`ApiClient`** — assembles the four POST parameters and executes the HTTPS call.
    * **`examples/`** — ready-to-run samples for merchant access, FX, remittance, and payout APIs.

    Load your key material into the SDK's configuration before running any sample.
  </Step>

  <Step title="Build and encrypt your first request">
    The following example walks through the full encryption flow for a minimal request. Adapt it to your language of choice using the algorithm names as a guide.

    <CodeGroup>
      ```java Java (pseudocode) theme={null}
      import java.util.Base64;

      // 1. Build the JSON plaintext
      String jsonPlaintext = """
          {
            "head": {
              "version": "1.0.0",
              "tradeType": "00",
              "tradeTime": "1551341750",
              "tradeCode": "sp1301",
              "language": "cn"
            },
            "body": {
              "merchantNo": "YOUR_MERCHANT_NO"
            }
          }
          """;

      // 2. Sign with your RSA private key → HEX string
      String sign = RsaUtils.sign(
          jsonPlaintext,               // data to sign
          yourRsaPrivateKey,           // PKCS#8 private key
          "SHA1withRSA"                // algorithm
      ); // returns HEX-encoded signature

      // 3. Generate a random AES session key
      KeyGenerator kg = KeyGenerator.getInstance("AES");
      kg.init(128);
      SecretKey sk = kg.generateKey();
      String skBase64 = Base64.getEncoder().encodeToString(sk.getEncoded());

      // 4. Encrypt JSON plaintext with SK → Base64
      String jsonEnc = AesUtils.encrypt(
          jsonPlaintext,   // plaintext
          skBase64,        // session key (Base64)
          "AES/ECB/PKCS5Padding"
      ); // returns Base64-encoded ciphertext

      // 5. Encrypt SK with Gcashier Pay's RSA public key → HEX
      String keyEnc = RsaUtils.encryptToHex(
          skBase64,                    // the Base64 session key
          gcashierPayRsaPublicKey,     // Gcashier Pay's public key
          "RSA/ECB/PKCS1Padding"
      ); // returns HEX-encoded encrypted session key

      // 6. POST the four parameters
      Map<String, String> body = Map.of(
          "merchantNo", "YOUR_MERCHANT_NO",
          "jsonEnc",    jsonEnc,
          "keyEnc",     keyEnc,
          "sign",       sign
      );
      HttpResponse response = httpClient.post(
          "https://{baseUrl}/api/YOUR_ENDPOINT",
          body
      );
      ```

      ```python Python (pseudocode) theme={null}
      import json, secrets, hashlib
      from Crypto.PublicKey import RSA
      from Crypto.Cipher import AES, PKCS1_v1_5
      from Crypto.Signature import pkcs1_15
      from Crypto.Hash import SHA1
      import base64, binascii

      # 1. Build JSON plaintext
      payload = {
          "head": {
              "version": "1.0.0",
              "tradeType": "00",
              "tradeTime": "1551341750",
              "tradeCode": "sp1301",
              "language": "cn"
          },
          "body": {"merchantNo": "YOUR_MERCHANT_NO"}
      }
      json_plaintext = json.dumps(payload, separators=(',', ':'))

      # 2. Sign with SHA1withRSA → HEX
      private_key = RSA.import_key(open("rsa_private_key_2048.pem").read())
      h = SHA1.new(json_plaintext.encode("utf-8"))
      signature = pkcs1_15.new(private_key).sign(h)
      sign = binascii.hexlify(signature).decode()

      # 3. Generate a random 128-bit AES session key
      sk_bytes = secrets.token_bytes(16)
      sk_b64   = base64.b64encode(sk_bytes).decode()

      # 4. AES/ECB/PKCS7 encrypt → Base64
      cipher_aes = AES.new(sk_bytes, AES.MODE_ECB)
      padded     = pad(json_plaintext.encode("utf-8"), AES.block_size)
      json_enc   = base64.b64encode(cipher_aes.encrypt(padded)).decode()

      # 5. Encrypt session key with Gcashier Pay's RSA public key → HEX
      gcashier_pub = RSA.import_key(open("gcashier_public_key.pem").read())
      cipher_rsa   = PKCS1_v1_5.new(gcashier_pub)
      key_enc      = binascii.hexlify(cipher_rsa.encrypt(sk_b64.encode())).decode()

      # 6. POST
      import requests
      resp = requests.post(
          "https://{baseUrl}/api/YOUR_ENDPOINT",
          json={
              "merchantNo": "YOUR_MERCHANT_NO",
              "jsonEnc":    json_enc,
              "keyEnc":     key_enc,
              "sign":       sign
          }
      )
      ```
    </CodeGroup>

    <Tip>
      The AES session key only needs to be 128 bits for compatibility with the API. Use a cryptographically secure random generator — never derive the session key from a predictable value.
    </Tip>
  </Step>

  <Step title="Verify the test environment response">
    A successful response arrives as the same four-field envelope (`merchantNo`, `jsonEnc`, `keyEnc`, `sign`). Decrypt and verify it by reversing the flow:

    1. HEX-decode `keyEnc`, then decrypt with **your RSA private key** using `RSA/ECB/PKCS1Padding` → recover the Base64 session key `SK`.
    2. Base64-decode `jsonEnc` and `SK`, then AES-decrypt → JSON plaintext.
    3. HEX-decode `sign`, then verify against the JSON plaintext using **Gcashier Pay's public key** with `SHA1withRSA`.

    Parse the decrypted JSON. A successful response looks like this:

    ```json theme={null}
    {
      "head": {
        "version": "1.0.0",
        "tradeType": "01",
        "tradeTime": "1551341750",
        "tradeCode": "sp1301",
        "language": "cn",
        "respCode": "S00000",
        "respDesc": "Success"
      },
      "body": {}
    }
    ```

    `respCode: "S00000"` confirms the test environment received, decrypted, and processed your request successfully. Any other `respCode` value indicates an error — check the `respDesc` field for a human-readable description and review your encryption steps.

    <Note>
      The `{baseUrl}` placeholder in all endpoint URLs is replaced with the actual hostname Gcashier Pay provides for each environment. See the [Environments](/environments) page for test and production base URL details.
    </Note>
  </Step>
</Steps>

## What's next

Now that you have a working encrypted request, explore the authentication reference for a deep dive into the full signing and encryption specification, or jump straight to the Environments page to understand the differences between sandbox and production.

<CardGroup cols={2}>
  <Card title="Authentication" icon="lock" href="/authentication">
    Full specification for the dual-key encryption scheme, POST parameters, and head fields.
  </Card>

  <Card title="Environments" icon="server" href="/environments">
    How sandbox and production environments differ, and how mock testing rules work.
  </Card>
</CardGroup>
