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.
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 |
paid |
Yes | The expected amount cleared in full (or within the project's underpayment tolerance) |
paid_over |
Yes | More than the expected amount cleared; the whole transfer is credited |
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.