Instead of polling for status updates, you can configure webhooks to receive real-time notifications when swap or on-ramp order statuses change.
Setting Up Webhooks
Create a Webhook Endpoint
Set up an HTTPS endpoint on your server to receive webhook payloads.
Register the Webhook
Use the Partner API to register your webhook URL.
Verify Signatures
Validate incoming webhook signatures to ensure authenticity.
Process Events
Handle the webhook payload and update your application state.
Registering a Webhook
const webhook = await client.createWebhook({
url: "https://yourapp.com/webhooks/hypermid",
events: ["swap.completed", "swap.failed", "onramp.completed", "onramp.failed"],
secret: "whsec_your_signing_secret",
});
console.log("Webhook ID:", webhook.data.id);
console.log("Created:", webhook.data.createdAt);
Webhook Events
| Event | Description |
|---|
swap.pending | Swap transaction is being processed |
swap.completed | Swap completed successfully |
swap.failed | Swap failed |
deposit.received | Deposit was received |
deposit.completed | Deposit swap completed |
deposit.failed | Deposit swap failed |
onramp.payment_received | Fiat payment received |
onramp.crypto_sent | Crypto has been sent to the user’s wallet |
onramp.completed | On-ramp order completed |
onramp.failed | On-ramp order failed |
onramp.refunded | On-ramp payment was refunded |
Webhook Payload
Each webhook delivery includes a JSON payload with the event details:
{
"event": "swap.completed",
"timestamp": 1711234567,
"data": {
"transactionId": "txn_abc123",
"fromChain": 1,
"toChain": 42161,
"fromToken": "0x0000000000000000000000000000000000000000",
"toToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
"fromAmount": "1000000000000000000",
"toAmount": "3250000000",
"fromAddress": "0xSenderAddress",
"toAddress": "0xReceiverAddress",
"sourceTxHash": "0xSourceTxHash",
"destinationTxHash": "0xDestinationTxHash",
"status": "DONE",
"tool": "stargate",
"executionDuration": 120
}
}
Signature Verification
Every webhook request includes a X-Hypermid-Signature header containing an HMAC-SHA256 signature of the request body, signed with your webhook secret.
import crypto from "crypto";
import express from "express";
const app = express();
app.use(express.raw({ type: "application/json" }));
const WEBHOOK_SECRET = "whsec_your_signing_secret";
app.post("/webhooks/hypermid", (req, res) => {
const signature = req.headers["x-hypermid-signature"] as string;
const body = req.body;
// Compute expected signature
const expectedSignature = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(body)
.digest("hex");
// Verify signature
if (!crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
)) {
console.error("Invalid webhook signature");
return res.status(401).send("Invalid signature");
}
// Parse and process the event
const event = JSON.parse(body.toString());
console.log("Received event:", event.event);
switch (event.event) {
case "swap.completed":
handleSwapCompleted(event.data);
break;
case "swap.failed":
handleSwapFailed(event.data);
break;
case "onramp.completed":
handleOnrampCompleted(event.data);
break;
default:
console.log("Unhandled event:", event.event);
}
res.status(200).send("OK");
});
Always verify the webhook signature before processing the payload. Never trust incoming webhooks without signature validation, as anyone could send requests to your endpoint.
Managing Webhooks
List Webhooks
curl https://api.hypermid.io/v1/partner/webhooks \
-H "X-API-Key: your-api-key"
Delete a Webhook
curl -X DELETE "https://api.hypermid.io/v1/partner/webhooks/whk_abc123" \
-H "X-API-Key: your-api-key"
Best Practices
-
Respond quickly — Return a
200 status within 5 seconds. Process the event asynchronously if needed.
-
Handle duplicates — Webhooks may be delivered more than once. Use the
transactionId or orderUid to deduplicate.
-
Use HTTPS — Webhook URLs must use HTTPS for security.
-
Implement retry logic — If your endpoint returns a non-2xx status, Hypermid will retry the delivery with exponential backoff.
-
Log everything — Store the raw webhook payload for debugging purposes.
-
Keep your secret safe — Store the webhook signing secret securely and rotate it periodically.