H2H integration

Host-to-host is for merchants who build their own checkout UI: one API call returns the wallet address and the exact crypto amount, and you render the payment screen yourself. The buyer never leaves your site or bot.

1. Create an H2H payment

Unlike the widget flow, you pick the crypto currency up front with target_currency - the merchant must have an active wallet attached for it.

curl -X POST https://api.cryptunnel.io/v1/payments/h2h \
  -H 'content-type: application/json' \
  -H 'x-merchant-id: <your merchant id>' \
  -H 'x-api-key: ct_live_...' \
  -d '{
    "amount": 100,
    "currency": "USD",
    "external_id": "order-1042",
    "target_currency": "USDT",
    "auto_trace": true,
    "callback_url": "https://your-shop.example/webhooks/cryptunnel"
  }'

The response has everything your payment screen needs:

{
  "id": "n9cdFaTccYbXecVekHKW8Q",
  "external_id": "order-1042",
  "status": "pending",
  "wallet_address": "0x8dF3b1A1c1E71f6D4A49D6ce23eB8875eDA41cf5",
  "amount": "100.0034",
  "currency": "USDT",
  "created_at": "2026-08-23T12:00:00.000Z"
}

2. Show the payment screen

Display wallet_address and amount (a QR code helps) and tell the buyer to send exactly that amount in currency. The transfer is matched by the amount arriving at the wallet, so a different amount will not confirm the payment.

Why auto_trace matters

With auto_trace: true, Cryptunnel adds a tiny unique markup to the amount (fractions of a cent). Since matching is amount-based, this is what tells two buyers apart when they pay to the same wallet at the same time. Keep it on unless every payment goes to a dedicated address.

3. Wait for confirmation

The payment is already pending; when the exact transfer is detected on-chain it becomes confirmed. Learn about it via the signed webhook to your callback_url (see Webhook verification) or by polling GET /v1/payments/{id}.

Notes

  • amount/currency in the request are the fiat price (USD or EUR); the crypto amount is converted at the live rate at creation time.
  • is_test: true creates a sandbox payment - target_currency must then be attached on a test network (Test your integration).
  • If the merchant has no active wallet for target_currency, the request fails with 400 - attach one on the Wallets page first.

Did this page help you?