{"removeAttribution":false,"l10n":{"translations":{"default_locale":{"translation":{}}},"defaultLocale":"default_locale","locales":[{"code":"default_locale","name":"default_locale"}]},"apiProducts":{},"logo":{"srcSet":"/assets/chicksx-main-logo.8285ae9712c313c5205b59054e125928865e1311b642f92372820ef20f5507f4.9c1bb791.svg light, /assets/cx-logo-dark.6bb2c3a4ea4bda3cad6b7841fd66b3ed8af6ac243c2ae87e1e7603770b3ac3cb.9c1bb791.svg dark","altText":"ChicksX","link":"https://docs.chicksx.com/apis","favicon":"/assets/favicon-dark.5f6c9682d6c432167af77030cea8b02326b3da8a52d85f743dc5fa2c6c9f6a10.9c1bb791.svg"},"navbar":{"items":[{"type":"link","fsPath":"apis/index.yaml","metadata":{"type":"openapi","title":"ChicksX Payments API","description":"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.\n\n# Getting Started\n\n### Prerequisites\n\nBefore you can integrate with the ChicksX Payments API, you need to obtain your merchant credentials:\n\n- **x-api-key**: Your unique API key for authentication\n- **x-client-id**: Your merchant client identifier\n\n**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.\n\n\n### Security Notice\n\n🔒 **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.\n\n# SDK Integration Flow\n\nTo integrate the ChicksX SDK into your application, follow these steps:\n\n### Step 1: Obtain Merchant Credentials\n\nReview your onboarding message in the Discord integration thread to gather:\n- `x-api-key`\n- `x-client-id`\n\n### Step 2: Create a Public Access Token (Server-Side)\n\nFrom your **backend server**, make a request to create a public access token:\n\n```bash\nPOST https://develop-api.chicksx.com/v1/public_token/create\nHeaders:\n  x-api-key: your-api-key\n  x-client-id: your-client-id\n```\n\nThis returns a public access token that can be safely used in your client-side application.\n\n### Step 3: Embed the SDK Script (Client-Side)\n\nIn your frontend application, add the ChicksX SDK script tag with the required parameters:\n\n```html\n<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>\n```\n\nThen configure and initialize the SDK:\n\n```javascript\nwindow.chicksX.configure({\n  clientId: 'your-client-id',\n  env: 'dev',\n  baseCurrency: 'cad',\n  targetCurrency: 'usdt',\n  baseAmount: 100,\n  paymentMethod: 'interac',\n  walletAddress: '0xYourWalletAddressOptional'\n});\nwindow.chicksX.init({ authenticationToken: 'your-public-token' });\n```\n\nNote: `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:\n\n```javascript\ndocument.getElementById('payButton').addEventListener('click', function () {\n  window.chicksX.init({ authenticationToken: 'your-public-token' });\n});\n```\n\n### Step 4: SDK Configuration Parameters\n\n**Required Parameters:**\n- `clientId` - Your merchant client identifier\n- `env` - Environment (`dev`, `staging`, or `prod`)\n- `authenticationToken` - The public token obtained from Step 2\n\n**Optional Parameters:**\n- `baseCurrency` - Source currency code or currency reference (default: based on merchant config)\n- `targetCurrency` - Target cryptocurrency code or currency reference (default: based on merchant config)\n- `baseAmount` - Amount in base currency\n- `targetAmount` - Amount in target currency\n- `paymentMethod` - Payment method identifier (e.g., `interac`, `paypal`)\n- `walletAddress` - Cryptocurrency wallet address\n\n# Webhooks\n\nChicksX sends webhook notifications to your server when important events occur, such as order creation and fulfillment.\n\n## Setting Up Webhooks\n\nFor us to configure webhooks, refer to the **Discord integration thread** and provide:\n- Your webhook endpoint URL (must be HTTPS)\n- The environments you want to receive webhooks for (dev, staging, prod)\n\n## Webhook Events\n\n- **OrderCreated** - A new order has been created\n- **OrderFulfillment** - An order has been fulfilled/completed\n\n## Webhook Headers\n\nEvery webhook request includes security headers for signature verification:\n\n- **X-Webhook-Id** *(string, UUID)* - Unique identifier for this webhook delivery\n- **X-Webhook-Timestamp** *(string)* - Unix timestamp (seconds) when the webhook was sent\n- **X-Webhook-Signature** *(string, hex)* - HMAC-SHA256 signature for verification\n\n## Webhook Payload Structure\n\n```json\n{\n  \"eventType\": \"OrderFulfillment\",\n  \"sessionId\": \"your-session-id\",\n  \"details\": {\n    \"orderId\": 1092114,\n    \"status\": \"completed\",\n    \"paymentMethod\": \"Interac E-Transfer\",\n    \"fulfilled\": true,\n    \"totalPrice\": 100.01,\n    \"totalPriceCurrency\": \"USD\",\n    \"exchangeDetails\": {\n      \"baseCurrency\": \"CAD\",\n      \"amountReceived\": 139.99,\n      \"targetCurrency\": \"BTC\",\n      \"amountToSend\": 0.00112180,\n      \"operationType\": \"S\"\n    }\n  }\n}\n```\n\n**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.\n\n## Signature Verification\n\nTo 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.\n\n### Step-by-Step Verification Process\n\n**Step 1: Extract the headers from the incoming request**\n\n```text\nX-Webhook-Id: a08d4ad3-0d83-4e41-ae85-1d03c7931615\nX-Webhook-Timestamp: 1769451142\nX-Webhook-Signature: e1945ff2e1d526c04072e37845b1181c2aaa787087bba7937824c4d7a22658cb\n```\n\n**Step 2: Extract values from the JSON payload**\n\n```json\n{\n  \"eventType\": \"OrderFulfillment\",\n  \"details\": {\n    \"orderId\": 1092114\n  }\n}\n```\n\n**Step 3: Construct the signed data string**\n\nConcatenate the values with periods (`.`) in this exact order:\n\n```text\n{webhookId}.{timestamp}.{eventType}.{orderId}\n```\n\nUsing our example values:\n\n```text\na08d4ad3-0d83-4e41-ae85-1d03c7931615.1769451142.OrderFulfillment.1092114\n```\n\n**Step 4: Compute the HMAC-SHA256 hash**\n\nUsing your webhook secret key (provided by ChicksX), compute the HMAC-SHA256 hash of the signed data string:\n\n```text\nHMAC-SHA256(secret, signedData)\n```\n\n**Step 5: Convert to lowercase hexadecimal**\n\nConvert the resulting hash bytes to a lowercase hexadecimal string.\n\n**Step 6: Compare the signatures**\n\nCompare your computed signature with the `X-Webhook-Signature` header value. If they match, the webhook is authentic.\n\n### Complete Example\n\nGiven:\n- **Webhook Secret**: `my-webhook-secret`\n- **X-Webhook-Id**: `a08d4ad3-0d83-4e41-ae85-1d03c7931615`\n- **X-Webhook-Timestamp**: `1769451142`\n- **eventType**: `OrderFulfillment`\n- **orderId**: `1092114`\n\n**Signed data string:**\n\n```text\na08d4ad3-0d83-4e41-ae85-1d03c7931615.1769451142.OrderFulfillment.1092114\n```\n\n**Computed signature:**\n\n```text\nHMAC-SHA256(\"my-webhook-secret\", \"a08d4ad3-0d83-4e41-ae85-1d03c7931615.1769451142.OrderFulfillment.1092114\")\n= e1945ff2e1d526c04072e37845b1181c2aaa787087bba7937824c4d7a22658cb\n```\n\n### Verification Example (Node.js)\n\n```javascript\nconst crypto = require('crypto');\n\nfunction verifyWebhookSignature(secret, webhookId, timestamp, eventType, orderId, receivedSignature) {\n  // Step 3: Construct signed data\n  const signedData = `${webhookId}.${timestamp}.${eventType}.${orderId}`;\n  \n  // Step 4 & 5: Compute HMAC-SHA256 and convert to hex\n  const computedSignature = crypto\n    .createHmac('sha256', secret)\n    .update(signedData)\n    .digest('hex');\n  \n  // Step 6: Compare signatures (use timing-safe comparison)\n  return crypto.timingSafeEqual(\n    Buffer.from(computedSignature),\n    Buffer.from(receivedSignature.toLowerCase())\n  );\n}\n\n// Usage in Express.js\napp.post('/webhook/chicksx', express.json(), (req, res) => {\n  // Step 1: Extract headers\n  const webhookId = req.headers['x-webhook-id'];\n  const timestamp = req.headers['x-webhook-timestamp'];\n  const signature = req.headers['x-webhook-signature'];\n  \n  // Step 2: Extract payload values\n  const { eventType, details } = req.body;\n  \n  // Verify signature\n  const isValid = verifyWebhookSignature(\n    process.env.WEBHOOK_SECRET,\n    webhookId,\n    timestamp,\n    eventType,\n    details.orderId,\n    signature\n  );\n  \n  if (!isValid) {\n    return res.status(401).send('Invalid signature');\n  }\n  \n  // Process the webhook...\n  res.status(200).send('OK');\n});\n```\n\n### Verification Example (C#)\n\n```csharp\nusing System.Security.Cryptography;\nusing System.Text;\n\npublic static bool VerifyWebhookSignature(\n    string secret,\n    string webhookId, \n    string timestamp,\n    string eventType,\n    long orderId,\n    string receivedSignature)\n{\n    // Step 3: Construct signed data\n    var signedData = $\"{webhookId}.{timestamp}.{eventType}.{orderId}\";\n    \n    // Step 4: Compute HMAC-SHA256\n    using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));\n    var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(signedData));\n    \n    // Step 5: Convert to lowercase hex\n    var computedSignature = Convert.ToHexString(hash).ToLowerInvariant();\n    \n    // Step 6: Compare signatures\n    return computedSignature == receivedSignature.ToLowerInvariant();\n}\n```\n\n### Verification Example (Python)\n\n```python\nimport hmac\nimport hashlib\n\ndef verify_webhook_signature(secret, webhook_id, timestamp, event_type, order_id, received_signature):\n    # Step 3: Construct signed data\n    signed_data = f\"{webhook_id}.{timestamp}.{event_type}.{order_id}\"\n    \n    # Step 4 & 5: Compute HMAC-SHA256 and convert to hex\n    computed_signature = hmac.new(\n        secret.encode('utf-8'),\n        signed_data.encode('utf-8'),\n        hashlib.sha256\n    ).hexdigest()\n    \n    # Step 6: Compare signatures (constant-time comparison)\n    return hmac.compare_digest(computed_signature, received_signature.lower())\n```\n\n## Security Best Practices\n\n1. **Always verify signatures** - Never process webhooks without signature verification in production.\n2. **Use constant-time comparison** - Prevent timing attacks by using secure comparison functions.\n3. **Check timestamp freshness** - Reject webhooks older than 5 minutes to prevent replay attacks.\n4. **Use HTTPS only** - Ensure your webhook endpoint uses TLS/SSL.\n5. **Return 200 quickly** - Process webhooks asynchronously; acknowledge receipt immediately.\n6. **Store your secret securely** - Use environment variables or a secrets manager (Azure Key Vault, AWS Secrets Manager).\n\n# Test Data\n\n## Card Payments\n\nUse the following test cards when paying with Debit/Credit. All listed cards support 3D Secure authentication, which is required for card payments.\n\n> **Sandbox only.** Do not enter real card details in the sandbox environment.\n\n| Network | Card Number | Scenario | 3DS Status |\n|:---|:---|:---|:---|\n| Visa | 4005519200000004 | Frictionless | Authenticated |\n| Visa | 4124939999999990 | Frictionless | Authenticated |\n| Visa | 4917300800000000 | Frictionless | Authenticated |\n| Mastercard | 5555341244441115 | Frictionless | Authenticated |\n| Mastercard | 5406004444444443 | Frictionless | Authenticated |\n| Mastercard | 5407721000353481 | Frictionless | Authenticated |\n| Amex | 370000000000002 | Frictionless | Authenticated |\n| Amex | 378282246310005 | Frictionless | Authenticated |\n\n### Widget Fields\n\nWhenn widget prompts for card details, fill in the following:\n\n| Field | Value |\n|:---|:---|\n| Card Number | Any card number from the table above |\n| MM/YY | Any future expiry date (e.g. `12/26`) |\n| CVV | Any value (e.g. `123`) |\n| Address | Any address |\n| Frequency | One time |\n"},"label":"API Reference","link":"/apis","linePosition":"top","routeSlug":"/apis"},{"type":"link","link":"https://chicksx.com/","label":"Back to ChicksX","linePosition":"top"}]},"footer":{"copyrightText":"© 2025 ChicksX Inc. All rights reserved.","items":[{"type":"link","link":"https://chicksx.com/terms-of-service","label":"Terms of Service","linePosition":"top"},{"type":"link","link":"https://chicksx.com/privacy-policy","label":"Privacy Policy","linePosition":"top"},{"type":"link","link":"https://chicksx.com/cookies","label":"Cookies Policy","linePosition":"top"}]},"links":[{"href":"https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"}],"markdown":{"toc":{"depth":2,"header":"On this page"},"frontMatterKeysToResolve":["image","links"],"partialsFolders":["**/_partials/**"],"lastUpdatedBlock":{"format":"timeago"},"editPage":{}},"mcp":{"hide":false,"docs":{"hide":false,"name":"MCP server","ignore":[]}},"banner":[],"breadcrumbs":{"prefixItems":[]},"userMenu":{"hide":true},"auth":{"idpsInfo":[]},"search":{},"entitiesCatalog":{},"searchFeatures":{"advanced":{"enabled":false},"ai":{"enabled":false}},"analytics":{"ga":{"trackingId":"","exclude":[],"trackers":{}}}}