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.

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. Neither pre-payment state (awaiting_client, awaiting_payment) emits one; everything from confirming onward does.

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 stablecoin 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
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.