Skip to content

Backend Verification

Read this page when a completed widget flow unlocks something valuable, such as an order, subscription, account credit, or in-app balance.

Should you read this?

Yes, if your app treats TokenFlight as a payment step. Browser callbacks are useful for UI, but your backend should decide whether a payment is complete.

If you are only building a demo, you can come back to this page later.

Success callbacks run 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 or onDepositSuccess on the frontend, confirm the order on your backend:

GET <your-api-endpoint>/v1/orders/:walletAddress

This returns a paginated list of orders for the given address, including status, amounts, and transaction hashes.

Verification Flow

1. Frontend: success callback 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 database

Example: 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 the success callback 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 getTransaction RPC 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 filled status
  • Idempotency — handle duplicate verification requests gracefully

Next step