Skip to content
Open .md
On this page

Get

Retrieve one invoice by ID, inspect its payment and confirmation state, and reconcile the response with your own external order reference.

GET/v1/invoices/:invoice_id

API key: Payment

Returns the current state of an invoice. It uses the same response contract as invoice creation; the payment object appears once a token and network are selected.

Response (200 OK)

{
  "invoice_id": "inv_5CcyDYmMUGtzYL10q0Iimr",
  "project_id": "prj_xFukZuAJZR06pLVBh3uwzv",
  "status": "paid",
  "is_final": true,
  "is_test": false,
  "payment_url": "https://checkout.paymos.io/invoice/inv_5CcyDYmMUGtzYL10q0Iimr",
  "order": {
    "external_id": "order-12345",
    "client_id": "customer-67890",
    "amount": "50.00",
    "currency": "USDT",
    "network": "TRC20"
  },
  "payment": {
    "currency": "USDT",
    "network": "TRC20",
    "chain_id": 728126428,
    "contract_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "expected": "50.00",
    "address": "TLfGqSVPbET2KFczh3xb12Ja2RKfMCBPgp",
    "exchange_rate": "1.000000",
    "paid": "50.00",
    "remaining": "0",
    "fee": "0.50",
    "net": "49.50",
    "transfers": [
      {
        "tx_hash": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
        "amount": "50.00",
        "status": "confirmed",
        "created_at": 1739280712,
        "confirmed_at": 1739280912,
        "required_confirmations": 19,
        "estimated_confirmation_at": 1739280772,
        "explorer_url": "https://tronscan.org/#/transaction/abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
      }
    ]
  },
  "created_at": 1739280600,
  "updated_at": 1739280912,
  "expires_at": 1739284200,
  "completed_at": 1739280912
}

Payment fields

When payment is present, it contains:

Field Type Description
payment.currency string Crypto asset symbol selected for payment (e.g. USDT, USDC)
payment.network string Blockchain network code (e.g. ERC20, TRC20, BEP20, POLYGON, BASE, TON, SOL)
payment.chain_id integer Numeric chain id matching EIP-155 / TRON / TON conventions (e.g. 1 for Ethereum mainnet, 728126428 for Tron)
payment.contract_address string? The token's on-chain identifier — contract address on EVM and Tron, jetton master on TON, SPL mint on Solana. Nullable in the schema because a native coin has none; no native coin is an accepted asset, so on a real invoice it always carries a value. GET /v1/payment-channel-deposits/:id states the same rule for its own contract_address
payment.expected string Expected crypto amount the customer must send
payment.address string? Deposit address the customer pays to. While the invoice sits in awaiting_client the whole payment object is absent from the response, so this field never surfaces as null on a pending invoice — there is simply no payment to read yet
payment.exchange_rate string? Fiat-to-crypto exchange rate that produced expected
payment.paid string? Sum of confirmed incoming transfers
payment.remaining string? Outstanding amount the customer still needs to send (expected - paid, never negative). Only present once at least one transfer was confirmed
payment.fee string? Platform fee amount taken from paid
payment.net string? Merchant-receivable amount (paid - fee)
payment.transfers array? Per-transfer details — present once at least one on-chain transfer was detected. See below.

Transfer Fields

Each entry in payment.transfers[]:

Field Type Description
tx_hash string On-chain transaction hash (network-specific format)
amount string Transferred crypto amount
status string confirming (waiting for confirmations) or confirmed
created_at unix timestamp When our pipeline first observed the transfer in a processed block. Wall-clock on our server, not on-chain block timestamp — they differ if the pipeline was lagging. Use this (not the top-level invoice created_at) for the "seconds remaining" formula below.
confirmed_at unix timestamp? When the transfer reached the required confirmation count. null while still pending
required_confirmations integer? Confirmations needed to reach confirmed for this transfer's USD value tier. null on every network that settles by the chain's own finalized commitment instead of a block count — today BNB Smart Chain, Polygon, Solana, Avalanche and Plasma. Branch on the null, not on a network list: which chains confirm by finality is operational and can change
estimated_confirmation_at unix timestamp? When the transfer is expected to reach settlement. On block-count networks it is computed at observation time as transfer.created_at + required_confirmations × network_block_time; on finality networks, where there is no block count, it is transfer.created_at plus that chain's typical finality, so a wait can still be rendered. Static — does NOT shift between requests, same value on every poll until the transfer is confirmed (or its USD-tier shifts). For "seconds remaining" compute on the client: max(0, estimated_confirmation_at − now).
explorer_url string? Direct link to this transaction in the network's block explorer (Tronscan / Etherscan / Tonviewer / etc). null if the network has no public explorer configured. Safe to render as a clickable link verbatim — no transformation needed.

Invoice statuses

Every invoice reports a status string. The same value drives the merchant API response, the SSE checkout stream, and the webhook payload — there is one source of truth. The table below is the per-status reference: when the value appears, whether it is terminal, and the precise condition behind it. For the transition diagram and the two creation flows, see Payment flow.

A terminal status is final: the invoice settles there and never moves again. Five statuses are terminal — paid, paid_over, underpaid, expired, cancelled.

Status Terminal When it applies
awaiting_client No The opening status for every invoice. No token or network is chosen yet, so no deposit address exists. Cancellation is allowed only here
awaiting_payment No A token, network, and deposit address are locked in. Paymos is watching the address for an incoming transfer
confirming No A transfer landed on-chain and is accruing the confirmations required for its amount tier
underpaid_waiting No Less than the expected amount has cleared and the invoice stays open for the rest. Reached only when allow_multiple_payments is true
underpaid Yes The invoice closed short — either it expired below the expected amount, or a single payment fell short with allow_multiple_payments set to false
expired Yes The timer ran out with nothing received, or the fiat-flow token-selection window lapsed before a token was picked
cancelled Yes The merchant cancelled the invoice while it was still in awaiting_client

Errors

See Error Codes for the full catalogue. The type URI in every error response deep-links to the matching row.