Home/Developers
Developer hub · public beta

Payments infrastructure for builders.

REST API. JSON in, JSON out. Idempotent by key. Real webhooks with retry. Every request signed with HMAC-SHA256, so a leaked key on its own gets an attacker nowhere. Card data never touches your server, so you stay out of PCI scope. Sandbox and production share one base URL, switched by the key you send.

curl · POST /v1/checkout-sessions
# Signature covers METHOD, PATH, QUERY, # TIMESTAMP, NONCE and a hash of the body.   curl -X POST https://api.cxpay.net/v1/checkout-sessions \   -H "X-Key-Id: ak_test_7f3c..." \   -H "X-Timestamp: $TS" \   -H "X-Nonce: $NONCE" \   -H "X-Body-Hash: $BODY_SHA256" \   -H "X-Signature: $SIG" \   -H "Idempotency-Key: $(uuidgen)" \   -d '{     "amount": 28450,     "currency": "USD"   }'   # → 200 OK # { id: "cs_...", url: "...", #  payment_intent: "pi_..." }   # Send the customer to url. Fulfil on the # payment_intent.succeeded webhook.
Resources

Everything you need to ship.

The reference, the guides and the controls, all in one developer hub.

Secure payment flow from customer to bank on a laptop
One REST API. Tokenised, 3DS-ready, settled to the local bank.
Signing helpers

No SDK to install. Copy the helper and you are done.

We do not ship client libraries, because for this API you do not need one. There is one thing a library would do for you, which is sign the request, and it is about 20 lines. Take the helper for your language, drop it in, and call the API with the HTTP client you already use.

Node.js
helper
crypto.createHmac('sha256', key)
Python
helper
hmac.new(key, msg, sha256)
PHP
helper
hash_hmac('sha256', $msg, $key, true)
Any language
stdlib
HMAC-SHA256 + base64
Signed string
order
METHOD PATH QUERY TS NONCE BODYHASH
Freshness
5 min
X-Timestamp within 300s
Replay
blocked
X-Nonce is single use
cURL
always
api.cxpay.net/v1/
Core endpoints

The API surface, at a glance.

RESTful endpoints organised by resource, on https://api.cxpay.net. Amounts are in the smallest unit of the currency, across 157 currencies including XCG. Writes take an Idempotency-Key, so a retry after a timeout cannot charge twice.

POST/v1/checkout-sessions
GET/v1/checkout-sessions/:id
POST/v1/checkout-sessions/:id/cancel
POST/v1/payment-intents
GET/v1/payment-intents/:id
POST/v1/payment-intents/:id/capture
POST/v1/payment-intents/:id/refund
POST/v1/customers
PATCH/v1/customers/:id
GET/v1/payment-methods
POST/v1/payment-methods/:id/attach
POST/v1/setup-intents
POST/v1/setup-intents/:id/confirm
GET/v1/setup-attempts
GET/v1/mandates
POST/v1/mandates/:id/revoke
POST/v1/payment-links
GET/v1/me

Shown in short. Most resources also take GET for listing, PATCH for updates, and the cancel routes their type allows. Customers and payment methods support DELETE.

Hosted checkout fires 4 events: payment_intent.succeeded, payment_intent.payment_failed, checkout_session.completed and checkout_session.expired. Each delivery carries an X-CXPay-Signature header you verify against the raw body. Make your endpoint idempotent, since a retry can arrive after you have already handled the event, and if a delivery never lands you can always read the truth from GET /v1/payment-intents/:id.

Ready to start building?

Ask your account manager for keys. They arrive as ak_test_ keys, with the reference and the signing helper, and most teams have a test payment going through the same day. You are early, and you will have us on the phone rather than a ticket queue.