Backend Verification
Backend Verification
Section titled “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
Section titled “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
Section titled “Verification Flow”1. Frontend: onSwapSuccess fires with { orderId, txHash, ... }2. Frontend: POST to your backend with orderId and txHash3. Backend: GET /v1/orders/:address from the API4. Backend: Find the order matching the orderId5. Backend: Verify status is "filled" or another terminal status6. Backend: Confirm amounts match expected values7. Backend: Mark payment as verified in your databaseExample: Express.js Verification Endpoint
Section titled “Example: Express.js Verification Endpoint”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
Section titled “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
Section titled “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