API reference
All routes are served by the Worker at https://ares-crypto-pay.ajittadil7526.workers.dev unless noted. The frontend never talks to the Worker directly for intent creation — that flow goes through Ares Core.
Public routes (browser-callable, no auth)
GET /config?chain=bsc|eth|ethSepolia
Returns which assets are currently enabled on the contract. Used by the checkout page to decide which buttons to render.
$ curl https://ares-crypto-pay.ajittadil7526.workers.dev/config?chain=bsc
{
"chain": "bsc",
"chainId": 56,
"contractAddress": "0x171b0E75613954a82780973546dA87f3aD9FCB06",
"mode": 2,
"assets": ["native", "usdt", "usdc"]
}
mode is the on-chain paymentMode: 0 = native only, 1 = token only, 2 = both.
GET /intents/:id
Polled by the checkout page. Returns the current status of an intent.
$ curl https://ares-crypto-pay.ajittadil7526.workers.dev/intents/0xabc...64hex
{
"status": "settled",
"txHash": "0x...",
"expiresAt": 1765000000
}
Status is one of pending, settled, expired, failed. Expired intents are lazily flipped on read.
Server-to-server (Ares Core → Worker, X-Internal-Secret required)
POST /intents
Create a payment intent. Called by Ares Core; the page itself never holds the secret.
POST /intents
Content-Type: application/json
X-Internal-Secret: <INTERNAL_API_SECRET>
{
"orderId": "ares-order-12345",
"chain": "bsc",
"asset": "native",
"fiatAmount": "1.00"
}
Response:
{
"intentId": "0x...",
"contractAddress": "0x171b0E75613954a82780973546dA87f3aD9FCB06",
"chainId": 56,
"token": "0x0000000000000000000000000000000000000000",
"decimals": 18,
"amount": "1000000000000000",
"asset": "native",
"expiresAt": 1765000900
}
Errors:
400 bad json— body didn't parse400 missing fields— orderId/chain/asset/fiatAmount missing or non-positive400 bad chain— chain is not bsc, eth, or ethSepolia400 pricing failed— Alchemy price feed returned an error401 unauthorized— bad or missingX-Internal-Secret409 native payments disabled/409 token payments disabled— the contract'spaymentModedoesn't allow the requested asset class502 createIntent tx failed— the on-chain transaction reverted (e.g. intent creator hot key out of gas)
Operator endpoints
For ops/dashboard use. Also require X-Internal-Secret.
GET /api/dashboard
Returns per-chain contract balances (native + ERC-20), owner, pending owner, payment mode, and the 25 most recent intents.
GET /api/calldata/sweep?chain=bsc&token=usdt
Builds the calldata for a sweep operation and a deep link to the Safe UI. The Worker does not sign the sweep — that's the Safe's job. token defaults to native.
{
"chain": "bsc",
"token": "usdt",
"contract": "0x171b0E75613954a82780973546dA87f3aD9FCB06",
"owner": "0x8Ef22fEd288e0b98413efc6fFE3Af0a1D9EC62C1",
"to": "0x171b0E75613954a82780973546dA87f3aD9FCB06",
"value": "0",
"data": "0x6e2e6c870000...c4f0aa76dca2ce4",
"summary": "Sweep 12.34 USDT to owner",
"safeUrl": {
"queue": "https://app.safe.global/transactions/queue?safe=bnb:0x8Ef22...",
"newTx": "https://app.safe.global/transactions/new?safe=bnb:0x8Ef22...",
"contract":"0x171b...",
"data": "0x6e2e6c..."
}
}
Webhook (Worker → Ares Core)
When the poller detects a PaymentReceived event, it POSTs a signed JSON body to ARES_CORE_WEBHOOK_URL:
POST <ARES_CORE_WEBHOOK_URL>
Content-Type: application/json
X-Webhook-Signature: 0x... # HMAC of body using WEBHOOK_SECRET
{
"intentId": "0x...",
"chain": "bsc",
"chainId": 56,
"token": "0x000...000",
"amount": "1000000000000000",
"payer": "0x...",
"orderRef": "0x...",
"txHash": "0x...",
"blockNumber": 12345678
}
Failed deliveries are dead-lettered to KV and retried on each cron tick.
Frontend integration
The checkout page is at [checkout/index.html](https://github.com/your-org/crypto-pay/blob/main/checkout/index.html) in the repo. To wire it into Ares Studio, inject these globals before loading checkout.js:
<script>
window.ARES_WORKER_BASE = "https://ares-crypto-pay.ajittadil7526.workers.dev";
window.ARES_INTENTS_PROXY = "/api/crypto/intents"; // Ares Core, same-origin
window.ARES_SUCCESS_URL = "/order/success";
</script>
<script src="/static/checkout.js"></script>
The /api/crypto/intents route in Ares Core is responsible for forwarding POST requests to the Worker with the X-Internal-Secret header. The browser never sees the secret.