Integration guide

Accept stablecoin payments with Node.js

Create USDT / USDC orders on your server, show checkout and fulfill only after verified payment notifications.

Steps to follow

Node.js USDT / USDC payment integration steps

Use this pattern for SaaS subscriptions, digital delivery, invoices, account credits, or any website that needs an auditable USDT / USDC payment state.

  1. 01

    Create and persist a unique internal order ID before calling the payment API.

  2. 02

    Call the BoltUtil create-order endpoint from your Node.js backend and return the checkout URL to the browser.

  3. 03

    Show the exact USDT / USDC network and amount. A browser redirect is not payment proof.

  4. 04

    Verify the raw webhook body and signature, then fulfill idempotently by order ID and transaction hash.

  5. 05

    Store the confirmed transaction hash, network, amount, and fulfillment result for support and reconciliation.

BoltUtil checks payments and sends signed callbacks. Your server verifies signatures and order status, deduplicates events, then delivers goods, activates service or credits accounts.

Integration notes

What matters before production

Keep keys on the server

Create orders from Node.js so private API keys and local cart validation stay out of browser code.

Direct wallet settlement

Customers pay the configured merchant wallet while BoltUtil monitors the selected USDT / USDC network and reports confirmation.

Safe fulfillment

A signed server-to-server webhook lets your application activate access or delivery without trusting a customer redirect.

Node.js 22+ · USDC / Base checkout
import crypto from 'node:crypto'

// Node.js 20+ server module. Call only after authenticating the buyer.
// order must come from your database, with ownership and price checked.
// Never pass req.body directly; persist externalOrderId before calling.
export async function createStablecoinCheckout(order) {
  const key = process.env.BOLTUTIL_API_KEY
  const secret = process.env.BOLTUTIL_API_SECRET
  if (!key || !secret) throw new Error('Missing server credentials')

  const payload = JSON.stringify({
    externalOrderId: order.externalOrderId,
    amount: order.amount,
    currency: 'USDC',
    network: 'BASE',
    notifyUrl: 'https://merchant.com/webhooks/boltutil',
    returnUrl: 'https://merchant.com/orders/complete'
  })
  const timestamp = Date.now().toString()
  const signature = crypto.createHmac('sha256', secret)
    .update(`${timestamp}.${payload}`).digest('hex')

  // A timeout does not prove creation failed. Query order/status using
  // the SAME externalOrderId before deciding whether to retry.
  const response = await fetch('https://api.boltutil.com/api/v1/order/create', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Bolt-Key': key,
      'X-Bolt-Timestamp': timestamp,
      'X-Bolt-Signature': signature
    },
    body: payload,
    signal: AbortSignal.timeout(10000)
  })
  const result = await response.json()
  if (!response.ok || result.code !== 200 || !result.data?.checkoutUrl) {
    throw new Error('Create order failed; reconcile the saved order')
  }
  // Save result.data on the server. Return only checkout data to the buyer.
  return result.data
}

Examples are for integration and troubleshooting only. No requests are sent. Use your order data, network configuration and current API documentation.

Read API docs

Choose a supported pair

TRON supports USDT only. Available USDT / USDC pairs on other networks depend on enabled channels and configured wallets. Compare the configured contract or mint, not just the token name.

Integration guide

Questions merchants ask before going live

Can this example run directly in the browser?

No. It is a Node.js 22+ server module. Add your authenticated route, database-backed price and ownership checks, saved order IDs and verified webhook handler. Keep credentials on the server.

What if the create request times out?

A timeout does not prove failure. Query the saved externalOrderId on the server before deciding whether to retry; do not generate a new order ID blindly.

Can a successful transfer alone complete an order?

No. Check the configured network and token, destination, payable amount, order window and confirmation progress. Verify callbacks and fulfill only once.

Do all six networks support both currencies?

TRON supports USDT only. Available USDT / USDC pairs on other networks depend on enabled channels and configured wallets. Compare the configured contract or mint, not just the token name.

Launch a cleaner USDT / USDC payment flow

Create orders, monitor transfers, and notify your backend without asking customers to send screenshots.