Docs / OpacusPay — 0G App Integration
Payments

OpacusPay — 0G App Integration

Send USDC.e payments on 0G Mainnet or Base from your app in a single API call. No wallet management, no gas juggling — Opacus handles execution.

Live on 0G Mainnet. OpacusPay executes real on-chain USDC.e transfers on 0G (chain ID 16661) and USDC on Base (chain ID 8453). Transactions confirm in <5 seconds on 0G.

How it works

Your app calls the Opacus REST API with a recipient address, amount, and chain. Opacus signs and broadcasts the on-chain transfer from your execution wallet, returns the tx hash, and records the payment in your history.

  1. Your app backend calls POST /api/x402/settle with an Opacus API key.
  2. Opacus verifies balance, signs the USDC transfer, and broadcasts it.
  3. Tx hash + explorer URL are returned immediately after on-chain confirmation.
  4. Payment is recorded in your history (queryable via GET /api/x402/payments).
Execution wallet. Every Opacus API key has a deterministic execution wallet on both Base and 0G. Fund it with USDC (Base) or USDC.e (0G) + a small amount of native gas (ETH on Base, A0GI on 0G) before making payments.

Supported chains

Chainchain valueTokenContractExplorer
0G Mainnet 0g USDC.e 0x1f3aa82227281ca364bfb3d253b0f1af1da6473e chainscan.0g.ai
Base Mainnet base USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 basescan.org
Stellar Testnet stellar USDC / XLM Native / Stellar Asset stellar.expert
Arc Testnet arc USDC 0x1f3aa82227281ca364bfb3d253b0f1af1da6473e explorer.testnet.arc.network

Authentication

Pass your API key in either header:

HEADERS
X-Opacus-Api-Key: opak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
Authorization: Bearer opak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Get your API key from Agentboard → Settings → API Keys.

Send a payment

POST https://opacus.xyz/api/x402/settle
{
  "recipient":      "0xRecipientAddress",   // required — destination EVM address
  "amountUsdc":     1.50,                   // required — USDC amount (max 1000)
  "chain":          "0g",                   // required — "0g" or "base"
  "memo":           "invoice #42",          // optional — up to 200 chars
  "idempotencyKey": "my-app-txn-id-001"     // optional — prevents duplicate sends on retry
}

Request fields

FieldTypeDescription
recipientstringrequired — destination 0x EVM address
amountUsdcnumberrequired — amount in USDC (0 < amount ≤ 1000)
chainstringrequired"0g" or "base"
memostringoptional — payment note, max 200 chars
idempotencyKeystringoptional — unique key; if the same key is re-submitted the original tx is returned (safe retries)

Response

200 OK
{
  "ok":          true,
  "settled":     true,
  "txHash":      "0xabc123...",
  "chain":       "0g",
  "amountUsdc":  1.50,
  "explorerUrl": "https://chainscan.0g.ai/tx/0xabc123...",
  "status":      "confirmed",
  "replayed":    false    // true if idempotencyKey was already used
}
400 Bad Request
{
  "ok":      false,
  "settled": false,
  "error":   "Insufficient USDC.e balance for x402 payment. Have: 0.000000, Need: 1.500000 on 0g"
}

Code examples

TSsend payment on 0G
const OPACUS_API_KEY = process.env.OPACUS_API_KEY; // opak_xxx

async function sendPayment(recipient: string, amountUsdc: number) {
  const res = await fetch('https://opacus.xyz/api/x402/settle', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Opacus-Api-Key': OPACUS_API_KEY,
    },
    body: JSON.stringify({
      recipient,
      amountUsdc,
      chain: '0g',
      memo: 'payment from my 0G app',
      idempotencyKey: `txn-${Date.now()}`,
    }),
  });

  const data = await res.json();
  if (!data.ok) throw new Error(data.error);

  console.log('Tx hash:', data.txHash);
  console.log('Explorer:', data.explorerUrl);
  return data;
}

// Usage
await sendPayment('0xRecipientAddress', 1.50);

List payment history

GET https://opacus.xyz/api/x402/payments
GET /api/x402/payments?chain=0g&limit=20
X-Opacus-Api-Key: opak_xxx
Query paramTypeDescription
chainstringoptional — filter by 0g or base
limitnumberoptional — max results, default 50, max 200
200 OK
{
  "ok": true,
  "count": 2,
  "payments": [
    {
      "id":          "x402_lv2abc",
      "chain":       "0g",
      "recipient":   "0xRecipientAddress",
      "amountUsdc":  1.50,
      "txHash":      "0xabc123...",
      "explorerUrl": "https://chainscan.0g.ai/tx/0xabc123...",
      "memo":        "invoice #42",
      "status":      "confirmed",
      "createdAt":   "2026-04-19T10:22:31.000Z"
    }
  ]
}

Fund your execution wallet

Find your execution wallet address in Agentboard → Billing → Balance tab.

0G network (for chain: "0g")

  1. Bridge USDC.e to 0G using Opacus Bridge or any 0G bridge.
  2. Send a small amount of A0GI (native gas, ≥ 0.001 A0GI) to the execution wallet address.
  3. USDC.e contract: 0x1f3aa82227281ca364bfb3d253b0f1af1da6473e

Base network (for chain: "base")

  1. Send USDC to the execution wallet on Base.
  2. Send a small amount of ETH (native gas, ≥ 0.001 ETH) to the execution wallet address.
  3. USDC contract: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Gas required. 0G transactions require A0GI for gas. If the execution wallet has no A0GI, the payment will fail with "Insufficient A0GI (native gas)". Always keep ≥ 0.01 A0GI in the wallet.

Idempotency (safe retries)

Pass a unique idempotencyKey with every request. If your network request fails before you receive a response, resend the exact same body — Opacus will return the original transaction instead of sending a second payment.

Tip: Use your internal transaction/invoice ID as the idempotencyKey. Example: "idempotencyKey": "order-8821"

Error reference

Error messageCauseFix
recipient must be a valid 0x EVM address Invalid recipient Pass a 42-char hex address starting with 0x
amountUsdc must be between 0 and 1000 Amount out of range Use a value between 0.000001 and 1000
chain must be base or 0g Unknown chain string Use exactly "base" or "0g"
Insufficient USDC.e balance … Not enough USDC.e in execution wallet Bridge more USDC.e to the execution wallet on 0G
Insufficient A0GI (native gas) … No gas in execution wallet on 0G Send ≥ 0.01 A0GI to the execution wallet
API key is required Missing or wrong auth header Include X-Opacus-Api-Key header with your key

Full integration example (Next.js API route)

TSapp/api/checkout/route.ts
// Next.js 14 App Router — pay a seller on 0G after checkout
export async function POST(req: Request) {
  const { sellerWallet, amountUsdc, orderId } = await req.json();

  const res = await fetch('https://opacus.xyz/api/x402/settle', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Opacus-Api-Key': process.env.OPACUS_API_KEY!,
    },
    body: JSON.stringify({
      recipient:      sellerWallet,
      amountUsdc:     amountUsdc,
      chain:          '0g',
      memo:           `Order ${orderId}`,
      idempotencyKey: `order-${orderId}`,   // idempotent — safe to retry
    }),
  });

  const data = await res.json();

  if (!data.ok) {
    return Response.json({ error: data.error }, { status: 400 });
  }

  return Response.json({
    success:     true,
    txHash:      data.txHash,
    explorerUrl: data.explorerUrl,
  });
}
That's it. No wallet management, no private keys in your frontend, no gas estimation. Opacus handles signing, broadcasting, and confirmation tracking. You get back a tx hash in under 5 seconds on 0G.

Related