Authentication

X-API-Key is sufficient for a normal integration. Create the key under Dashboard API Keys and send it on every request. There is no OAuth or session login for the API. An RSA public key on the Security page is optional extra protection — it is not a second API key and is not required unless you turn those options on.

Method

Include your API key on every request using the X-API-Key header:

X-API-Key: YOUR_API_KEY

Also send:

Accept: application/json
Content-Type: application/json

(Use Content-Type: application/json for request bodies on POST endpoints.)

Obtaining your API key

  1. Log in to the CardPlusPay Dashboard.
  2. Go to API Keys in the Dashboard and create or copy a key.
  3. Treat it like a password: anyone with the key can perform actions and spend balance on your account.

Security

  • Server-side only — Call the API from your backend. Never put the API key in frontend JavaScript, mobile app source, or public repositories.
  • Store securely — Use environment variables or a secrets manager (e.g. CARDPLUSPAY_API_KEY), not hardcoded strings or config files committed to version control.
  • HTTPS only — All requests must go to https://api.cardpluspay.com. Do not send the key over plain HTTP.
  • Rotation — If a key may be compromised, generate a new key in API Keys in the Dashboard and update your app; revoke or delete the old key as needed.

Advanced: optional RSA (leave off unless you need it)

Register a PEM public key (-----BEGIN PUBLIC KEY-----) only if you need extra protection. Use Dashboard Account Settings → Security → API public key (#apikey) and, separately, gift card code encryption (#giftcard). Saving a key does not turn these options on. Leave them off unless your client already implements the matching private-key work.

Request signing (challenge + signature)

When Enable request signing is on, unsigned /v1 calls return 401 until the client signs. You must send two extra headers on every /v1 request except fetching a challenge:

  • X-API-Challenge — The one-time challenge string from GET /v1/challenge.
  • X-API-Signature — Base64-encoded SHA256 with RSA signature of that challenge string (OpenSSL OPENSSL_ALGO_SHA256), signed with your private key. The server verifies it with the public key registered on #apikey.

Fetch a challenge with X-API-Key only (no signature headers):

GET https://api.cardpluspay.com/v1/challenge
X-API-Key: YOUR_API_KEY
Accept: application/json

The challenge is single-use and valid for 5 minutes (expires_in: 300). Request a new challenge for each signed call. GET /v1/challenge itself is available only after signing is enabled and a public key is stored; if signing is off, you do not call this endpoint.

Encrypting the JSON data object

When response encryption is on for the API public key, the envelope stays the same (success, message) but the data object is RSA-wrapped. Your client must decrypt data with the matching private key. This is not the same as gift card code encryption.

Gift card codes in order responses

When gift card code encryption is on (#giftcard), redeemable codes in POST /orders and GET /orders/{id} are RSA-encrypted. Direct top-up has no codes. Dashboard reveal of stored PINs is unchanged. This does not replace X-API-Key and is not extra API authentication.

Invalid or missing key

If the key is missing, invalid, or inactive, the API returns 401 Unauthorized. The response body still uses the usual envelope:

{
  "success": false,
  "message": "Unauthorized",
  "data": { ... }
}

Check that the header name is exactly X-API-Key and the value is the full key with no extra spaces or quotes.

← Concepts · Integration Guide