Skip to content

Getting Started

On this page

Payment Flow

Follow an invoice from creation through asset selection, payment detection, confirmation, expiry, and the final webhook your system consumes.

Two ways to get paid

Paymos has two money-in products, and which one you use changes the shape of your integration:

Invoice Payment channel
What it is One payment request One payer's permanent deposit identity
Amount Fixed at creation None — every deposit at or above the token's minimum is credited
Expiry Yes Never
Address Derived per invoice One permanent address per network, never reassigned
Terminal state paid, paid_over, underpaid, expired, cancelled None — a channel keeps accepting until you block it
Best for Checkouts, orders, one-off payments Balance top-ups, recurring funding, accounts you invoice out of band

The rest of this page describes the invoice lifecycle. For the channel branch see Create Payment Channel — a channel has no lifecycle of its own; each deposit that arrives has one, and it is much shorter: confirmingconfirmed, with reorged in between if the chain reorganizes.

Lifecycle

Diagram: Payment Flow

both flows

token confirmed

cancel

timeout

detected

timeout

insufficient

overpayment

partial

timer expired

awaiting_client

awaiting_payment

cancelled

expired

confirming

underpaid

paid

paid_over

underpaid_waiting

The invoice ends in one terminal state: paid, paid_over, underpaid, expired, or cancelled. Most transitions fire a webhook event — the per-status table below lists which. Everything from confirming onward emits one. The two pre-payment states do not: opening in awaiting_client is silent, and so is the ordinary move into awaiting_payment when the checkout confirms the token. The one exception runs backwards — if a deep reorg removes every counted transfer, the invoice regresses to awaiting_payment and that regression does emit invoice.awaiting_payment.

Two creation flows

Both flows open the same way. The invoice is created in awaiting_client, with no address behind it yet. What differs is what you send and how much is left for the customer to decide. The address is allocated — and the invoice moves to awaiting_payment — at the moment the checkout confirms the token.

Direct crypto flow — provide amount + currency + network. The amount is the crypto amount to pay, and both the token and the chain are fixed at creation. The customer has nothing left to decide, so the checkout confirms that pair and the address is allocated straight away.

Fiat flow — provide amount + currency (no network). The amount is a fiat amount. The customer selects a token and network on the hosted checkout; at that moment Paymos locks the FX rate, assigns an address, and the invoice moves to awaiting_payment. Read the locked rate back from payment.exchange_rate on the invoice, alongside the exact payment.expected token amount.

See Supported currencies for the full list of fiat codes and tokens, and Create invoice for the request body.

Statuses

Status Description Webhook event
awaiting_client Opening status for every invoice — no address until the checkout confirms the token
awaiting_payment Address assigned, waiting for transfer — on the way in; invoice.awaiting_payment only on a reorg regression
confirming Payment detected, waiting for confirmations invoice.confirming
underpaid_waiting Partial payment received, waiting for remaining invoice.underpaid_waiting
underpaid Closed with insufficient payment invoice.underpaid
expired Timer ran out without payment invoice.expired
cancelled Cancelled by merchant (only from awaiting_client) invoice.cancelled

Cancellation

An invoice can only be cancelled while in awaiting_client — before the checkout confirms the token. After that the address is live and the customer has been quoted a fixed amount on a specific chain, so cancellation is off the table.

Timeouts and expiration

Setting Default
Token selection window (fiat flow) Configurable
Invoice expiration (after address assigned) Configurable
Underpayment threshold Configurable per project
Overpayment handling Credited in full

If the customer sends less than the required amount before the invoice expires, the resulting status depends on allow_multiple_payments:

  • allow_multiple_payments: true — status becomes underpaid_waiting, additional payments are accepted until the timer runs out
  • allow_multiple_payments: false — a single insufficient payment immediately closes the invoice with underpaid

If the timer runs out while in underpaid_waiting, the final status is resolved from the total received amount and the underpayment policy. If the customer sends more than expected, the full amount is credited and the status becomes paid_over.