Skip to content

NullSwap Merchant Docs

NullSwap lets your backend accept crypto payments. You ask for a deposit address, show it to your customer, and we tell you over a webhook when the money has actually arrived and cleared screening.

Everything on this site describes the merchant API — a machine-to-machine HTTP API authenticated with a single API key. There is no browser flow, no OAuth and no session.

https://api.pay.nullswap.com

The same API also publishes an interactive Swagger reference at api.pay.nullswap.com/docs, generated from the API itself. Use it to check an exact field name or try a call; use this site to understand the flows. See Outside the version prefix.

Two ways to take money

The API offers two collection models. They are independent; use either or both.

Invoice Static wallet
Address belongs to one order one customer, forever
Expected amount stated up front none — you reconcile whatever arrives
Expires yes, 60604800 seconds never
Tells you when paid webhooks no webhooks — you poll
Screening per payment, before it counts per payment, before it is swept
Use it for checkouts, one-off orders account top-ups, recurring deposits

Start with invoices. Reach for static wallets when you need a long-lived per-customer address rather than a per-order one.

The invoice flow end to end

sequenceDiagram
    autonumber
    participant B as Your backend
    participant N as NullSwap
    participant C as Customer
    participant W as Your webhook endpoint

    B->>N: POST /api/v1/invoices (chain, token, expectedAmount)
    N-->>B: 201 { id, depositAddress, expiresAt, status: WAITING }
    B->>C: show depositAddress + exact amount, until expiresAt
    C->>N: sends the tokens on chain

    N->>W: invoice.payment_detected · status PAYMENT_DETECTED
    Note over W: unconfirmed — show progress, ship nothing

    N->>N: confirmation depth reached, AML screening runs
    N->>W: invoice.payment_confirmed · payment CONFIRMED
    N->>W: invoice.paid · status PAID, paidAmount >= expectedAmount
    Note over W: this is the fulfilment signal

    W-->>N: 2xx

Steps 5–9 are all webhook deliveries. Polling GET /api/v1/invoices/{invoiceId} returns the same state, but it is a reconciliation tool for when your endpoint has been down — not the integration.

Getting started

  1. Get an API key. Open your merchant in the cabinet and copy it from Settings → API key. It starts with sk_live_. Keys, IP whitelists and webhook subscriptions are all created there by a person; the API can read them but never create or change them. See Authentication.
  2. Resolve a chain and a token. GET /api/v1/chains and GET /api/v1/tokens give you the UUIDs an invoice is addressed with. Cache them. See Chains and tokens.
  3. Create an invoice. POST /api/v1/invoices. The response carries depositAddress — show it, or its QR code, to your customer. See Invoices.
  4. Handle the webhook. Verify the HMAC signature, deduplicate on the delivery id, answer 2xx quickly, and fulfil on invoice.paid. See Webhooks.

Fulfil on invoice.paid, never on invoice.payment_detected

invoice.payment_detected means a transaction is visible on chain. It has not been confirmed and it has not been screened, so it can still be reorged away or flagged. Releasing goods on it is the one integration mistake that costs real money.

Two things that trip people up

Amounts are strings, never JSON numbers. Every amount crosses the wire as a decimal string of an integer in the token's base units, paired with the token's decimals. 25.50 USDT on TRON is "25500000" with decimals: 6. See Amounts.

Errors are identified by a name, not by prose. The body carries a stable machine-readable name in message; branch on that, never on the HTTP status alone and never on wording.

{
  "statusCode": 422,
  "message": "InvalidInvoiceAmountError",
  "timestamp": "2026-01-01T00:00:00.000Z"
}

See Errors for the full list.

Where to go next

  • Authentication

    The API key, IP whitelisting, and what a blocked merchant can still do.

  • API conventions

    Amounts, pagination, filtering, timestamps, and which calls are safe to retry.

  • Invoices

    Creating one, the status lifecycle, under- and overpayment, expiry.

  • Invoice payments

    Individual deposits, screening, and what to do with a payment you did not expect.

  • Static wallets

    Long-lived per-customer addresses and the payments that land on them.

  • Webhooks

    The event catalogue, payload format, signature verification, retries and ordering.

  • Chains and tokens

    The catalogue every other route is addressed in terms of.

  • Balances and withdrawals

    Reading your balance and paying yourself out.

  • Address screening

    Checking an address before you pay it.

  • Errors

    Every error name, what raises it, and whether retrying helps.