Skip to content

API

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. Always set: every accepted asset is a contract-based stablecoin, never a native coin.
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 finality-flag networks (BSC, Polygon, Solana), where we wait for the chain's finalized commitment instead of counting blocks
estimated_confirmation_at unix timestamp? When the transfer is expected to reach required_confirmations. Computed at observation time as transfer.created_at + required_confirmations × network_block_time. 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). null on finality-flag networks (BSC, Polygon, Solana) where there's no fixed block-count target.
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.