Credentials & Keys
Before integrating, you need four credentials in hand. This page explains what each one is, where to get it, how to generate your merchant key pair, and how the IP allowlist works.
The 4 credentials you need
Integration requires four values (obtained from the platform / viewable in the merchant portal — keep them safe and never share them):
| Name | Description | Purpose |
|---|---|---|
APP-ID | Merchant ID | Request header identifier |
TOKEN (or the secret used to obtain a token) | API token | Authentication |
Server public key public_t | Platform public key, base64(PEM) | Encrypt outbound requests / verify inbound signatures |
Merchant private key private_u | Your private key, base64(PEM) | Sign outbound requests / decrypt inbound data |
Key format = base64(PEM)
That is, the standard PEM text (the entire -----BEGIN ... KEY----- block) Base64-encoded one more time. Each language SDK first Base64-decodes it back to PEM, then loads it. The private key is PKCS#8 (BEGIN PRIVATE KEY); the public key is SPKI (BEGIN PUBLIC KEY). Keys are RSA-2048.
Note that TOKEN is not a static credential: exchange your APP-ID + secret for it via getToken and reuse it for its lifetime. The values you actually need to keep long-term are secret, public_t, and private_u.
Getting them from the merchant portal
| Credential | How to obtain |
|---|---|
APP-ID | Your merchant id, shown in the merchant list / merchant details in the portal |
secret | Shown on the "API Credentials" page in the merchant portal |
Server public key public_t | Shown on the "API Credentials" page in the merchant portal |
Merchant private key private_u | Generated by you (see the next section) — the platform never issues or stores it |
The portal displays raw PEM; the SDK expects base64(PEM)
The public key shown on the "API Credentials" page is raw PEM (the entire -----BEGIN PUBLIC KEY----- block), while the SDK constructor expects that whole PEM block Base64-encoded once more. The portal provides two copy buttons (copy raw PEM / copy base64(PEM)) — when wiring up the SDK, use the base64(PEM) one; do not paste the raw PEM directly.
After generating your key pair, submit the public key to the platform via "Upload Merchant Public Key" in the merchant portal (Google 2FA verification is required on submission). The private key stays on your own server.
Business endpoints are unavailable until your public key is uploaded
If the platform has no public key configured for you, business endpoints return publicKeyNotExist (PUBLIC U not configured). Complete the public key upload before starting integration testing.
Generating your merchant key pair (openssl)
bash
# 1. Generate an RSA-2048 private key (PKCS#8 format, BEGIN PRIVATE KEY)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_u.pem
# 2. Derive the public key from the private key (SPKI format, BEGIN PUBLIC KEY)
openssl pkey -in private_u.pem -pubout -out public_u.pem
# 3. Convert to the base64(PEM) the SDK expects (-w0 disables line wrapping)
base64 -w0 private_u.pem > private_u.b64
base64 -w0 public_u.pem > public_u.b64- Submit the contents of
public_u.pemto the platform via "Upload Merchant Public Key" in the portal. - Use the contents of
private_u.b64as the merchant private key parameter in the SDK constructor. - Lock down permissions on
private_u.pem/private_u.b64(e.g.chmod 600) and keep them only on your server.
IP allowlist
The platform maintains a source-IP allowlist per merchant ID. If a business request comes from an IP not on the allowlist, the response is the plain-text string Oops (not JSON, and no error code).
- When you get
Oops, first confirm your server's actual egress IP, then contact the platform to verify the allowlist. - With multiple egress paths / NAT / load balancers / serverless functions, your egress IP may not be a single address. You must allowlist every possible egress IP, otherwise you'll see the puzzling symptom of intermittent
Oopsresponses.
Implementation detail: the allowlist check runs first
The server-side middleware checks in this order: request body size → merchant exists → IP allowlist → token → public key → signature/decryption. In other words, if the allowlist check fails, the request never reaches token or signature validation — so if you're certain your credentials and SDK are correct but still get Oops, the problem is definitely the source IP.
For more troubleshooting of error symptoms, see Error Codes and the Troubleshooting Guide.
Security notes
Your private key belongs to you alone — the platform never holds it
You generate private_u yourself; the platform never issues it, never stores it, and will never ask you for it. Anyone requesting your merchant private key (or the key file, or its base64 string) in the name of "official staff", "customer support", or "technical support" is always a scammer. Keep the private key on your server only — never put it in frontend code, logs, or third-party services.
Key rotation takes effect immediately — do it during off-peak hours
Once you submit a new public key via "Upload Merchant Public Key", the platform immediately verifies signatures against the new key, and the old private key stops working at once — any request signed/decrypted with the old key will fail. Therefore:
- Schedule the rotation for an off-peak window;
- Have the new private key ready on your server in advance, and switch to it immediately after uploading the new public key;
- Right after switching, call selfcheck to exercise the full request/response path, and only resume business traffic once it passes.
Next steps
- Understand the full encryption, signing, and anti-replay specification: Protocol Specification
- Exchange your secret for a token: getToken
- How each language SDK loads the two base64(PEM) keys: Using the SDKs