PEXX Platform APIs

Quickstart: Your first payout in 10 minutes

This guide gets you from zero to a successful test payout. By the end you will have authenticated, queried an exchange rate, created a payout, and received a webhook confirming its status.

What you need before you start

  1. A PEXX merchant account with API access enabled
  2. A clientId and apiSecret issued by Pexx
  3. An RSA keypair (you generate this, then upload the public key to Pexx)
  4. A test deposit of USDT or USDC in your merchant balance — see [funding guide / dashboard]
  5. A publicly reachable HTTPS URL for receiving webhooks (use a tunneling tool like ngrok during development)

Generate your RSA keypair

openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -in private.pem -pubout -out public.pem

Upload public.pem to PEXX via the merchant dashboard. Keep private.pem secret — it's what proves API requests come from you.

Step 1 — Get an access token

curl -X POST https://api.pexx.com/apis/v1/access-token \
  -H "Content-Type: application/json" \
  -H "X-Client-Id: YOUR_CLIENT_ID" \
  -H "X-Timestamp: 1735689600000" \
  -H "X-Nonce: 7f3d9a2c1b" \
  -H "X-Signature: BASE64_RSA_SIGNATURE" \
  -d '{"clientId":"YOUR_CLIENT_ID"}'

The signature is an RSA-SHA256 signature over a canonical string. See Authentication & Signing for the exact construction and runnable code in multiple languages.

Successful response:

{
  "code": "0000",
  "data": {
    "accessToken": "eyJhbGciOi...",
    "refreshToken": "eyJhbGciOi...",
    "expiresIn": 3600
  }
}

Cache the accessToken — you'll send it on every subsequent request.

Step 2 — Query an exchange rate

curl -X POST https://api.pexx.com/apis/v1/exchange-rate/query \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Timestamp: 1735689601000" \
  -H "X-Nonce: 8a2e1f4d9b" \
  -H "X-Signature: HMAC_SIGNATURE" \
  -d '{"targetCurrencys":["PHP"]}'

Response:

{
  "code": "0000",
  "data": {
    "exchangeRates": [
      {
        "id": "rate_abc123",
        "rateTime": "2025-04-30T10:00:00Z",
        "sourceCurrency": "USDT",
        "targetCurrency": "PHP",
        "rate": 56.42
      }
    ]
  }
}

Important: This rate is indicative. It does not lock in. The actual rate applied to your payout is the one returned in the create response in step 3. If you display this rate to your end user, either show a disclaimer or build in a small buffer.

Step 3 — Create a payout

curl -X POST https://api.pexx.com/apis/v1/fiat-payout/create \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Timestamp: 1735689602000" \
  -H "X-Nonce: 9b3f2e5d8c" \
  -H "X-Signature: HMAC_SIGNATURE" \
  -d '{
    "merchantReferenceId": "test-payout-001",
    "deductionCurrency": "USDT",
    "payoutCurrency": "PHP",
    "payoutAmount": 5000,
    "sender": {
      "firstName": "Jane",
      "lastName": "Doe",
      "country": "SG",
      "idType": "[ID_TYPE_ENUM]",
      "idValue": "[ID_VALUE]"
    },
    "beneficiary": {
      "accountName": "Juan dela Cruz",
      "accountNumber": "1234567890",
      "bankCode": "[BANK_CODE]"
    }
  }'

Response:

{
  "code": "0000",
  "data": {
    "payoutId": "po_8a7b6c5d",
    "rate": 56.40,
    "deductionAmount": 88.65,
    "totalFee": 0.50,
    "feeCurrency": "USDT",
    "merchantReferenceId": "test-payout-001"
  }
}

Persist payoutId and merchantReferenceId together. You'll match webhooks against them later.

Idempotency: Use a unique merchantReferenceId for every distinct payout intent. If you retry a failed network request with the same merchantReferenceId, [BEHAVIOR TO CONFIRM: Pexx returns the original payout / Pexx rejects as duplicate / no idempotency guarantee]. See Error Handling & Idempotency.

Step 4 — Receive the webhook

When the payout reaches a terminal state, Pexx will POST to your webhook URL:

{
  "event": "payout.updated",
  "eventId": "evt_3c2b1a",
  "timestamp": "2025-04-30T10:05:30Z",
  "data": {
    "payoutId": "po_8a7b6c5d",
    "merchantReferenceId": "test-payout-001",
    "status": "PAID",
    "completeTime": "2025-04-30T10:05:28Z"
  }
}

You must verify the signature on this request before processing it. See Webhook Integration for verification code and the full retry behavior.

Step 5 — Reconcile

After processing the webhook, query PEXX to confirm the final state. This is your source of truth for accounting.

curl -X POST https://api.pexx.com/apis/v1/fiat-payout/query \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "..." \
  -d '{"merchantReferenceIds":["test-payout-001"]}'