Skip to main content
Every order endpoint takes its request body as a single encrypted string rather than plain JSON. You build the payload as JSON, encrypt it with your RSA public encryption key, and send the result as data:
The encryption key is not the same thing as your API key. Your api-key header authenticates the request; the RSA public encryption key encrypts the body. Both are issued during onboarding.

Which endpoints are encrypted

GET endpoints — List banks, Fetch a payment link, List refunds, List chargebacks and Ping — take no body at all.
Track an event is the one endpoint whose envelope key is capitalised: {"Data": "..."}, not {"data": "..."}.

The key format

Your public encryption key arrives as a single base64 string. Decoded, it looks like this:
Three things to notice: So the procedure is always: base64-decode the key → split on ! → take the second half → parse the XML → base64-decode Modulus and Exponent → build an RSA public key from them.

The algorithm

PKCS#1 v1.5 — not OAEP. Browser SubtleCrypto only implements RSA-OAEP for encryption, so a pure WebCrypto implementation is not possible; use a library (or do it server-side, which you should be doing anyway to keep the key off the client).

Code

Requires node-forge.
encrypt.js

The sandbox encryption helper

While you are building, sandbox exposes an endpoint that encrypts a payload for you, so you can exercise the API before your own encryption code works.
Send the plaintext JSON payload as the body, with your public key in the api-key header:
Take data from the response and send it as the data field of the real endpoint.
This endpoint does not exist in production. It is a development aid only. Ship your own encryption before going live, and never route live payloads through it.
Older integrations may reference /data/encrypt or /payment/data/encrypt. Both are superseded — use /charge/data/encrypt.

Troubleshooting

The data string could not be decrypted. Usual causes: the wrong padding (OAEP instead of PKCS#1 v1.5), a key that belongs to a different environment, encrypting the raw bytes instead of base64-encoding the ciphertext, or a payload longer than the key can encrypt in one block.
That is expected. PKCS#1 v1.5 padding includes random bytes, so encrypting the same payload twice produces different ciphertext. Both decrypt correctly.
The server. Even though the key is public, doing it server-side keeps card data off your own frontend and out of your logs, and avoids shipping an RSA implementation to the browser.