Backend Verification
Backend Verification
The onSwapSuccess callback runs in the user's browser and can be spoofed. For any business-critical flow (e-commerce payments, SaaS subscriptions, etc.), always verify the order server-side.
Verify via API
After receiving onSwapSuccess on the frontend, confirm the order on your backend:
GET <your-api-endpoint>/v1/orders/:walletAddressThis returns a paginated list of orders for the given address, including status, amounts, and transaction hashes.
Verification Flow
1. Frontend: onSwapSuccess fires with { orderId, txHash, ... }
2. Frontend: POST to your backend with orderId and txHash
3. Backend: GET /v1/orders/:address from the API
4. Backend: Find the order matching the orderId
5. Backend: Verify status is "filled" or another terminal status
6. Backend: Confirm amounts match expected values
7. Backend: Mark payment as verified in your databaseExample: Express.js Verification Endpoint
js
const API_ENDPOINT = process.env.HYPERSTREAM_API_URL;
app.post('/api/verify-payment', async (req, res) => {
const { orderId, walletAddress } = req.body;
// Query the API directly — don't trust frontend data
const response = await fetch(
`${API_ENDPOINT}/v1/orders/${walletAddress}`
);
const data = await response.json();
// Find the specific order
const order = data.data?.find((o) => o.id === orderId);
if (!order) {
return res.status(404).json({ error: 'Order not found' });
}
if (order.status !== 'filled') {
return res.status(400).json({ error: 'Order not yet complete', status: order.status });
}
// Verify the order matches your expected payment
// (check token, amount, recipient, etc.)
// Mark as verified in your database
await db.payments.update({
where: { orderId },
data: { verified: true },
});
return res.json({ verified: true });
});Transaction Hash Verification
The txHash from onSwapSuccess is the source chain transaction hash. You can also verify it directly on the source chain's block explorer or via an RPC call:
- EVM chains: Query the transaction receipt via
eth_getTransactionReceipt - Solana: Query via
getTransactionRPC method
This confirms the transaction was actually broadcast and included in a block.
Security Best Practices
- Never trust frontend callbacks alone for payment verification
- Always query the API from your backend using the wallet address and order ID
- Validate amounts and tokens — ensure the order matches what you expected
- Check for terminal status — only accept orders with a
filledstatus - Idempotency — handle duplicate verification requests gracefully