Endpoints for SDK authentication and token management
ChicksX Payments API (1.0.0)
REST API that provides an interface to ChicksX cryptocurrency exchange ecosystem. This API enables merchants to offer their users cryptocurrency purchases, sales, and swaps through a simple integration.
Before you can integrate with the ChicksX Payments API, you need to obtain your merchant credentials:
- x-api-key: Your unique API key for authentication
- x-client-id: Your merchant client identifier
Important: If you don't have these credentials yet, please refer to your integration Discord thread and technology point of contact. As a last resort, contact our support team directly at support@chicksx.com.
🔒 All endpoints requiring x-api-key and x-client-id headers MUST be called from your backend server only. These credentials should never be exposed in client-side applications (web browsers, mobile apps, etc.) as they provide full access to your merchant account.
Review your onboarding message in the Discord integration thread to gather:
x-api-keyx-client-id
From your backend server, make a request to create a public access token:
POST https://develop-api.chicksx.com/v1/public_token/create
Headers:
x-api-key: your-api-key
x-client-id: your-client-idThis returns a public access token that can be safely used in your client-side application.
In your frontend application, add the ChicksX SDK script tag with the required parameters:
<script src="https://develop-api.chicksx.com/v1/sdk/chicksx.js?clientId=your-client-id&env=dev&baseCurrency=cad&targetCurrency=usdt&baseAmount=100&paymentMethod=interac"></script>Then configure and initialize the SDK:
window.chicksX.configure({
clientId: 'your-client-id',
env: 'dev',
baseCurrency: 'cad',
targetCurrency: 'usdt',
baseAmount: 100,
paymentMethod: 'interac',
walletAddress: '0xYourWalletAddressOptional'
});
window.chicksX.init({ authenticationToken: 'your-public-token' });Note: window.chicksX.init({ authenticationToken: 'your-public-token' }) opens the payment popup/modal. You typically want to call it in response to a user action (e.g., a button click) to avoid unexpected popups:
document.getElementById('payButton').addEventListener('click', function () {
window.chicksX.init({ authenticationToken: 'your-public-token' });
});Required Parameters:
clientId- Your merchant client identifierenv- Environment (dev,staging, orprod)authenticationToken- The public token obtained from Step 2
Optional Parameters:
baseCurrency- Source currency code or currency reference (default: based on merchant config)targetCurrency- Target cryptocurrency code or currency reference (default: based on merchant config)baseAmount- Amount in base currencytargetAmount- Amount in target currencypaymentMethod- Payment method identifier (e.g.,interac,paypal)walletAddress- Cryptocurrency wallet address
ChicksX sends webhook notifications to your server when important events occur, such as order creation and fulfillment.
For us to configure webhooks, refer to the Discord integration thread and provide:
- Your webhook endpoint URL (must be HTTPS)
- The environments you want to receive webhooks for (dev, staging, prod)
- OrderCreated - A new order has been created
- OrderFulfillment - An order has been fulfilled/completed
Every webhook request includes security headers for signature verification:
- X-Webhook-Id (string, UUID) - Unique identifier for this webhook delivery
- X-Webhook-Timestamp (string) - Unix timestamp (seconds) when the webhook was sent
- X-Webhook-Signature (string, hex) - HMAC-SHA256 signature for verification
{
"eventType": "OrderFulfillment",
"sessionId": "your-session-id",
"details": {
"orderId": 1092114,
"status": "completed",
"paymentMethod": "Interac E-Transfer",
"fulfilled": true,
"totalPrice": 100.01,
"totalPriceCurrency": "USD",
"exchangeDetails": {
"baseCurrency": "CAD",
"amountReceived": 139.99,
"targetCurrency": "BTC",
"amountToSend": 0.00112180,
"operationType": "S"
}
}
}Note: The sessionId field contains the session identifier you provided when creating the access token. This value correlates the webhook event back to the specific session (and order) initiated from your platform.
To verify webhook authenticity, you must compute an HMAC-SHA256 signature and compare it with the X-Webhook-Signature header. This ensures the webhook originated from ChicksX and hasn't been tampered with.
Step 1: Extract the headers from the incoming request
X-Webhook-Id: a08d4ad3-0d83-4e41-ae85-1d03c7931615
X-Webhook-Timestamp: 1769451142
X-Webhook-Signature: e1945ff2e1d526c04072e37845b1181c2aaa787087bba7937824c4d7a22658cbStep 2: Extract values from the JSON payload
{
"eventType": "OrderFulfillment",
"details": {
"orderId": 1092114
}
}Step 3: Construct the signed data string
Concatenate the values with periods (.) in this exact order:
{webhookId}.{timestamp}.{eventType}.{orderId}Using our example values:
a08d4ad3-0d83-4e41-ae85-1d03c7931615.1769451142.OrderFulfillment.1092114Step 4: Compute the HMAC-SHA256 hash
Using your webhook secret key (provided by ChicksX), compute the HMAC-SHA256 hash of the signed data string:
HMAC-SHA256(secret, signedData)Step 5: Convert to lowercase hexadecimal
Convert the resulting hash bytes to a lowercase hexadecimal string.
Step 6: Compare the signatures
Compare your computed signature with the X-Webhook-Signature header value. If they match, the webhook is authentic.
Given:
- Webhook Secret:
my-webhook-secret - X-Webhook-Id:
a08d4ad3-0d83-4e41-ae85-1d03c7931615 - X-Webhook-Timestamp:
1769451142 - eventType:
OrderFulfillment - orderId:
1092114
Signed data string:
a08d4ad3-0d83-4e41-ae85-1d03c7931615.1769451142.OrderFulfillment.1092114Computed signature:
HMAC-SHA256("my-webhook-secret", "a08d4ad3-0d83-4e41-ae85-1d03c7931615.1769451142.OrderFulfillment.1092114")
= e1945ff2e1d526c04072e37845b1181c2aaa787087bba7937824c4d7a22658cbconst crypto = require('crypto');
function verifyWebhookSignature(secret, webhookId, timestamp, eventType, orderId, receivedSignature) {
// Step 3: Construct signed data
const signedData = `${webhookId}.${timestamp}.${eventType}.${orderId}`;
// Step 4 & 5: Compute HMAC-SHA256 and convert to hex
const computedSignature = crypto
.createHmac('sha256', secret)
.update(signedData)
.digest('hex');
// Step 6: Compare signatures (use timing-safe comparison)
return crypto.timingSafeEqual(
Buffer.from(computedSignature),
Buffer.from(receivedSignature.toLowerCase())
);
}
// Usage in Express.js
app.post('/webhook/chicksx', express.json(), (req, res) => {
// Step 1: Extract headers
const webhookId = req.headers['x-webhook-id'];
const timestamp = req.headers['x-webhook-timestamp'];
const signature = req.headers['x-webhook-signature'];
// Step 2: Extract payload values
const { eventType, details } = req.body;
// Verify signature
const isValid = verifyWebhookSignature(
process.env.WEBHOOK_SECRET,
webhookId,
timestamp,
eventType,
details.orderId,
signature
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process the webhook...
res.status(200).send('OK');
});using System.Security.Cryptography;
using System.Text;
public static bool VerifyWebhookSignature(
string secret,
string webhookId,
string timestamp,
string eventType,
long orderId,
string receivedSignature)
{
// Step 3: Construct signed data
var signedData = $"{webhookId}.{timestamp}.{eventType}.{orderId}";
// Step 4: Compute HMAC-SHA256
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(signedData));
// Step 5: Convert to lowercase hex
var computedSignature = Convert.ToHexString(hash).ToLowerInvariant();
// Step 6: Compare signatures
return computedSignature == receivedSignature.ToLowerInvariant();
}import hmac
import hashlib
def verify_webhook_signature(secret, webhook_id, timestamp, event_type, order_id, received_signature):
# Step 3: Construct signed data
signed_data = f"{webhook_id}.{timestamp}.{event_type}.{order_id}"
# Step 4 & 5: Compute HMAC-SHA256 and convert to hex
computed_signature = hmac.new(
secret.encode('utf-8'),
signed_data.encode('utf-8'),
hashlib.sha256
).hexdigest()
# Step 6: Compare signatures (constant-time comparison)
return hmac.compare_digest(computed_signature, received_signature.lower())- Always verify signatures - Never process webhooks without signature verification in production.
- Use constant-time comparison - Prevent timing attacks by using secure comparison functions.
- Check timestamp freshness - Reject webhooks older than 5 minutes to prevent replay attacks.
- Use HTTPS only - Ensure your webhook endpoint uses TLS/SSL.
- Return 200 quickly - Process webhooks asynchronously; acknowledge receipt immediately.
- Store your secret securely - Use environment variables or a secrets manager (Azure Key Vault, AWS Secrets Manager).
Use the following test cards when paying with Debit/Credit. All listed cards support 3D Secure authentication, which is required for card payments.
Sandbox only. Do not enter real card details in the sandbox environment.
| Network | Card Number | Scenario | 3DS Status |
|---|---|---|---|
| Visa | 4005519200000004 | Frictionless | Authenticated |
| Visa | 4124939999999990 | Frictionless | Authenticated |
| Visa | 4917300800000000 | Frictionless | Authenticated |
| Mastercard | 5555341244441115 | Frictionless | Authenticated |
| Mastercard | 5406004444444443 | Frictionless | Authenticated |
| Mastercard | 5407721000353481 | Frictionless | Authenticated |
| Amex | 370000000000002 | Frictionless | Authenticated |
| Amex | 378282246310005 | Frictionless | Authenticated |
Request
Creates a public access token for SDK authentication. This endpoint must be called from your secure backend server using your merchant credentials.
The returned access token can be safely used in client-side applications to authenticate with the ChicksX SDK.
Session and order correlation: A sessionId is required and ties each public token to exactly one order. Once an order has been placed, the session expires and cannot be reused. If a user attempts to place another order within the same session, they will see a message indicating the session has expired and must restart the checkout process from your platform.
Security: Never expose your x-api-key or x-client-id in client-side code.
Your merchant API key (must be kept secure, never expose in client-side code)
Array of permission scopes for the token
Unique session identifier that correlates this public token to a single order. Each session must map to exactly one order — once an order has been placed, the session expires and cannot be reused. If a user attempts to start another order within the same session, they will be prompted to restart the process from your platform.
- Mock serverhttps://docs.chicksx.com/_mock/apis/public_token/create
- Development serverhttps://develop-api.chicksx.com/v1/public_token/create
- Production serverhttps://api.chicksx.com/v1/public_token/create
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X POST \
https://docs.chicksx.com/_mock/apis/public_token/create \
-H 'Content-Type: application/json' \
-H 'x-api-key: your-api-key' \
-H 'x-client-id: your-client-id' \
-d '{
"scope": [
"wallet.read",
"merchant.read"
],
"sessionId": "user-session-abc123"
}'{ "code": "OK", "data": { "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjaGlja3N4LWFwaSIsInN1YiI6Im1lcmNoYW50LWRlbW8iLCJhdWQiOiJjaGlja3N4LXNkayIsImV4cCI6MTY5NjUzNDgwMCwiaWF0IjoxNjk2NTMxMjAwLCJqdGkiOiJmNDdhYzEwYi01OGNjLTQzNzItYTU2Ny0wZTAyYjJjM2Q0NzkiLCJlbnZpcm9ubWVudCI6InNhbmRib3giLCJzY29wZSI6WyJ3YWxsZXQucmVhZCIsIm1lcmNoYW50LnJlYWQiXX0.signature", "tokenType": "Bearer", "expiresIn": 3600, "expiresAt": 1696534800, "scope": [ … ], "jti": "f47ac10b-58cc-4372-a567-0e02b2c3d479" } }
Operation type (e.g. S = Sell, B = Buy, FF = Fiat to Fiat, CC = Crypto to Crypto)
- Mock serverhttps://docs.chicksx.com/_mock/apis/payment-methods
- Development serverhttps://develop-api.chicksx.com/v1/payment-methods
- Production serverhttps://api.chicksx.com/v1/payment-methods
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X GET \
'https://docs.chicksx.com/_mock/apis/payment-methods?operationType=S&countryCode=US&includeDeliveryMethods=true' \
-H 'x-api-key: your-api-key' \
-H 'x-client-id: your-client-id'{ "success": true, "code": "ok", "data": [ { … }, { … }, { … } ] }
Operation type (e.g. S = Sell, B = Buy, FF = Fiat to Fiat, CC = Crypto to Crypto)
- Mock serverhttps://docs.chicksx.com/_mock/apis/exchange/currencies
- Development serverhttps://develop-api.chicksx.com/v1/exchange/currencies
- Production serverhttps://api.chicksx.com/v1/exchange/currencies
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X GET \
'https://docs.chicksx.com/_mock/apis/exchange/currencies?operationType=S&countryCode=US' \
-H 'x-api-key: your-api-key' \
-H 'x-client-id: your-client-id'{ "success": true, "code": "ok", "data": { "receiveCurrencies": [ … ], "spendCurrencies": [ … ] } }
Your merchant API key (must be kept secure, never expose in client-side code)
Type of operation (e.g. S = Sell, B = Buy, FF = Fiat to Fiat, CC = Crypto to Crypto)
- Mock serverhttps://docs.chicksx.com/_mock/apis/exchange/quotes
- Development serverhttps://develop-api.chicksx.com/v1/exchange/quotes
- Production serverhttps://api.chicksx.com/v1/exchange/quotes
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X POST \
https://docs.chicksx.com/_mock/apis/exchange/quotes \
-H 'Content-Type: application/json' \
-H 'x-api-key: your-api-key' \
-H 'x-client-id: your-client-id' \
-d '{
"operationType": "B",
"baseCurrencyId": 22,
"baseAmount": 100,
"targetCurrencyId": 1,
"paymentMethodId": 7
}'{ "success": true, "code": "ok", "data": { "spend": { … }, "transactionFee": { … }, "receive": { … }, "delivery": { … }, "paymentMethod": { … }, "receivePaymentMethod": { … }, "rate": 0.74 } }