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:
- merchant-api-key: Your unique API key for authentication
- merchant-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 merchant-api-key and merchant-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:
merchant-api-keymerchant-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:
merchant-api-key: your-api-key
merchant-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?merchantId=your-merchant-id&env=dev&accessToken=your-public-token&baseCurrency=cad&targetCurrency=usdt&baseAmount=100&paymentMethod=interac"></script>Then configure and initialize the SDK:
window.chicksX.configure({
merchantId: 'your-merchant-id',
env: 'dev',
accessToken: 'your-public-token',
baseCurrency: 'cad',
targetCurrency: 'usdt',
baseAmount: 100,
paymentMethod: 'interac',
walletAddress: '0xYourWalletAddressOptional'
});
window.chicksX.init();Note: window.chicksX.init() 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();
});Required Parameters:
merchantId- Your merchant identifierenv- Environment (dev,staging, orprod)accessToken- The public token obtained from Step 2
Optional Parameters:
baseCurrency- Source currency code (default: based on merchant config)targetCurrency- Target cryptocurrency code (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-or-null",
"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. If no sessionId was provided, this field will be null.
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).
- Mock serverhttps://chicksx-payments-api.redocly.app/_mock/apis/openapi/payment-methods
- Development serverhttps://develop-api.chicksx.com/v1/payment-methods
- Staging serverhttps://staging-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://chicksx-payments-api.redocly.app/_mock/apis/openapi/payment-methods?operationType=S&countryCode=US&includeDeliveryMethods=true' \
-H 'Authorization: eyJhbGciOiJSUzI1NiIsImtpZCI6InNkay1rZXktMjAyNS0wMyJ9...' \
-H 'merchant-api-key: YOUR_API_KEY_HERE' \
-H 'merchant-client-id: string'{ "success": true, "code": "ok", "data": [ { … }, { … }, { … } ] }
- Mock serverhttps://chicksx-payments-api.redocly.app/_mock/apis/openapi/exchange/currencies
- Development serverhttps://develop-api.chicksx.com/v1/exchange/currencies
- Staging serverhttps://staging-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://chicksx-payments-api.redocly.app/_mock/apis/openapi/exchange/currencies?operationType=S&countryCode=US' \
-H 'Authorization: eyJhbGciOiJSUzI1NiIsImtpZCI6InNkay1rZXktMjAyNS0wMyJ9...' \
-H 'merchant-api-key: YOUR_API_KEY_HERE' \
-H 'merchant-client-id: string'{ "success": true, "code": "ok", "data": { "receiveCurrencies": [ … ], "spendCurrencies": [ … ] } }