Webhooks

You can create a webhook in your project dashboard under the Universal Bridge tab. You'll be prompted to copy a secret key before saving the webhook. This will be used for verification on all webhook requests received by your backend.

Response Objects

To get the TypeScript type for webhook responses, see the Webhook.Payload type in the SDK.

Example Payloads

{
"version": 2,
"data": {
"transactionId": "0x7baae858e28628fe57cb0ca93c86fcda68f556563199cb4472044bfd9fbe5ec8",
"paymentId": "0xbea711bf1da223b29b176cff7f01596834dd63c7ad85477a3504f4b9285b33a2",
"clientId": "c56b27030ad22846003fafbb4302b5d7",
"action": "SELL",
"status": "COMPLETED",
"originToken": {
"chainId": 466,
"address": "0x675C3ce7F43b00045a4Dab954AF36160fb57cB45",
"symbol": "USDC",
"name": "USD Coin",
"decimals": 6,
"priceUsd": 0.99995,
"iconUri": "https://coin-images.coingecko.com/coins/images/6319/large/usdc.png?1696506694"
},
"originAmount": "24875000",
"destinationToken": {
"chainId": 8453,
"address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"symbol": "USDC",
"name": "USD Coin",
"decimals": 6,
"priceUsd": 0.99995,
"iconUri": "https://coin-images.coingecko.com/coins/images/6319/large/usdc.png?1696506694"
},
"destinationAmount": "24794905",
"sender": "0xb4523A0D69612B9A4629A70E42021B2F384CC8Fa",
"receiver": "0x044A83bA68f36CF1F27836Cb93614f86d8B0ea96",
"type": "sell",
"transactions": [
{
"chainId": 466,
"transactionHash": "0xc507bde1da0832d097c2160aacc2c9333ac3a0516c8dca4fb955f4c949da1ef6"
},
{
"chainId": 8453,
"transactionHash": "0xc44b372284061a11ec96c67acfc96a67cc6180d14753b55a93c1f780d16ddc95"
}
],
"developerFeeBps": 20,
"developerFeeRecipient": "0x66d3d733e597bdf8b794ab6e13c8f2be0fcda39b"
}
}

Webhook Verification

There are two ways to verify a webhook request authenticity:

  • Checking that the bearer token in the Authorization header matches the secret key received when you created the webhook.
  • Decrypting the payload signature from the x-payload-signature header and verifying it against the received webhook body.

Decrypting the Payload Signature

The payload signature is constructed using the x-timestamp header and the webhook's full body:

const signature = crypto
.createHmac("sha256", decryptedSecret)
.update(`${timestamp}.${payload}`)
.digest("hex");

The x-timestamp header is a UNIX timestamp in seconds, and the webhook body is the JSON payload received by your webhook endpoint.

Then verify that the signature matches the x-payload-signature header.

When using webhooks to distribute purchased items, always verify that the proper amount was paid to the proper address.