Payment integration

Crypto Payment API for USDT & USDC

Create stablecoin orders, query payment status and verify signed webhooks from your backend. Integrate wallet checkout or manual transfers with USDT and USDC.

Supported payment networks

USDC is not supported on TRON. Routes must be enabled and have an active receiving wallet. USDbC, USDC.e and other contracts are not interchangeable with the listed assets.

Circle-issued USDC on Ethereum, Polygon, Solana and Base. BNB Smart Chain uses Binance-Peg USDC, with 18 decimals. It is not Circle-issued native USDC. Native USDC and Bridged USDT on Base mainnet. Availability depends on enabled payment routes and an active receiving wallet.

Steps to follow

Four integration steps, with a check at each boundary

For custom websites, SaaS and digital-product backends. The example uses USDC / Base; match an enabled token and network pair.

  1. 01

    Persist your order ID, price, buyer and token/network first. Use the same merchant’s API key and active webhook secret to sign the exact outgoing JSON on your server.

  2. 02

    Save checkoutUrl and the returned payment details. Display the full payable amount. After a timeout, query the original externalOrderId; a duplicate rejection does not mean another payment is needed.

  3. 03

    Verify the webhook timestamp and signature over the raw body before parsing. Check the saved order, network, asset, receiving address and expected/received amounts. A browser return is not payment proof.

  4. 04

    Persist the valid notification in a transaction or durable queue, fulfill the order once and then return 2xx. CONFIRMED already represents confirmed payment; do not wait exclusively for COMPLETED.

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

Sign the exact request body

Keep API credentials on your server. Sign the timestamp, a dot and the exact outgoing JSON with HMAC-SHA256.

Reconcile timeouts

A timeout does not prove creation failed. Query the saved externalOrderId before retrying; do not blindly generate another ID.

Verify, then fulfill once

BoltUtil checks payments and sends signed callbacks. Your server verifies the signature, checks the local order and payment information, deduplicates and fulfills.

Node.js 22+ · USDC / Base
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
}

Server-side integration example only; no requests are sent. Supply the API key, timestamp and exact-body signature, and validate local orders and prices.

Read API docs

Payment integration

Questions merchants ask before going live

Can I deploy the GitHub demo as my production payment service?

The demos check request creation, amounts and raw-body signatures. They do not include your order database or durable deduplication. The receiver returns 503 by default to avoid acknowledging unsaved notifications. Add your order transaction and fulfillment flow after local contract tests. WooCommerce should use the official plugin and its integration API.

Can I create the same merchant order twice?

externalOrderId must be unique within a merchant account. Duplicate creation is rejected; query the original order after a timeout before deciding to retry.

Does BoltUtil hold the payment?

No. Customers transfer directly to your configured wallet. BoltUtil checks orders and payments without custody or access to private keys, seed phrases or withdrawal authority.

Do all networks support USDT and USDC?

TRON supports USDT only. Other networks support the configured USDT / USDC versions. Availability depends on enabled channels and merchant wallets; use the API and checkout response as the source of truth.

Can I fulfill when a customer returns?

returnUrl is navigation, not payment evidence. Use a verified callback or trusted server-side status query, check the order and fulfill once.

How are payment differences handled?

Free merchants can view their own review records. Qualifying manual-transfer differences can create review records; verify ownership when several orders are candidates. Active membership is required to accept or reject an association. Acceptance confirms payment and triggers the configured callback.

Can customers connect a wallet without entering the amount?

Yes. Wallet checkout prepares the recipient, token and complete payable amount on supported networks and devices. Customers review and confirm in their wallet. First use may require unlocking, connection approval or a network switch. QR codes and copied addresses remain available for manual transfer; both methods require on-chain confirmation.

Launch a cleaner USDT / USDC payment flow

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