Making your first API request

Once your merchant account is onboarded, your first step is to list which currencies are available for your cashier to set up the Payment Gateway.

1

Create your API key

Merchants must provide Pay.io with a public key during onboarding.

Requirements:

  • At least 2048 bits

  • PEM format

You can use the following code sample to generate the public key and private key.

Example in Python
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

# Generate 2048-bit private key
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)

# Serialize keys to PEM
pem_private = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.TraditionalOpenSSL,
    encryption_algorithm=serialization.NoEncryption()
)

pem_public = private_key.public_key().public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
2

Create merchant signature and nonce

Every API request must be signed. To set up the signature:

  1. Generate a nonce. Nonce is a secure random string, at least 16 characters long.

    # Example in Python def generate_nonce(): return str(uuid.uuid4())

  2. Build canonical string using the rules:

    1. The request’s signature is calculated over this exact concatenation (no delimiters):

      METHOD + PATH + NONCE + QUERY + BODY

  3. Sign with your merchant’s private key using RSA-SHA256.

  4. Base64-encode the signature.

  5. Send it in the X-API-Signature header

Example Python
def generate_auth_headers(method, path, query_string, body, api_signing_secret):
    # 1. Generate unique nonce (UUID4 string)
    nonce = str(uuid.uuid4())

    # 2. Build the canonical signing data
    signing_data = method + path + nonce + query_string + (body or "")

    # 3. Create the HMAC-SHA256 signature
    signature = hmac.new(
        key=api_signing_secret.encode("utf-8"),
        msg=signing_data.encode("utf-8"),
        digestmod=hashlib.sha256
    ).hexdigest()

    # 4. Return headers
    return {
        "X-API-Nonce": nonce,
        "X-API-Signature": signature
    }

# Example usage
headers = generate_auth_headers(
    method="POST",
    path="/v1/payments",
    query_string="order_id=123",
    body='{"amount":100,"currency":"USD"}',
    api_signing_secret="my_secret_key"
)
3

Prepare the full content of the request with your information.

You'll be calling the Merchant Console API Get a list of available currencies endpoint.

Request

curl --location 'https://pgw.stage.pay.io/v1/merchant/currencies' \
--header 'Content-Type: application/json' \
--header 'X-API-Key: YOUR_API_KEY' \
--header 'X-API-Nonce: YOUR_UUID_NONCE' \
--header 'X-API-Signature: SIGNATURE'

Response (example)

{
  "currencies": [
    {
      "id": "1270e0a2-593b-5272-8c0e-90ba5552d921",
      "name": "SOL",
      "currency_code": "SOL",
      "symbol": "◎",
      "network": "Solana",
      "currency_icon": "https://cdn.hub88.io/hub-wallet/SOL-ic.svg"
    },
    {
      "id": "990cd2f7-b169-5665-b0e1-05cc46ae4209",
      "name": "USDC",
      "currency_code": "USDC",
      "symbol": "$",
      "network": "Base Chain"
    }
  ]
}

Always include a request body in POST, PUT, or PATCH requests.


Next steps for Pay.io APIs

Once you have your supported currencies, you can:

See the Authorisation for details on how to sign and authenticate your requests.

Last updated