Order Lifecycle
Every status a Magma order can move through, who acts at each step, and the terminal states. Includes a full state machine diagram.
An order is the agreement between a buyer and a seller for one channel. It walks through a sequence of statuses from the moment a buyer initiates a purchase to the moment the channel is fully open on chain.
This page is the reference for every MarketOrderStatus and MarketOrderPaymentStatus value. If you're building an integration that polls or reacts to order updates, this is the table you'll keep open.
State machine
MarketOrderStatus - full reference
The 17 in-flight and terminal statuses. The "Who acts" column tells you which party is expected to do something next; if the answer is "nobody", the order has stalled or completed.
| Status | Who acts | Next states | What it means |
|---|---|---|---|
WAITING_FOR_SELLER_APPROVAL | Seller | WAITING_FOR_BUYER_PAYMENT, SELLER_REJECTED, SELLER_FAILED_TO_REACT | Order created. Seller must accept (with a HODL invoice) or reject. |
WAITING_FOR_BUYER_PAYMENT | Buyer | WAITING_FOR_CHANNEL_OPEN, BUYER_FAILED_TO_PAY, BUYER_REJECTED | Seller accepted. Buyer must pay the BOLT11 HODL invoice within its expiry. |
WAITING_FOR_CHANNEL_OPEN | Seller | SELLER_SENT_TRANSACTION, SELLER_FAILED_TO_OPEN_CHANNEL | Payment received and held. Seller must broadcast the channel funding tx. |
SELLER_SENT_TRANSACTION | - (chain) | WAITING_FOR_ON_CHAIN_CONFIRMATION, SELLER_FAILED_TO_SEND_SWAP | Seller submitted add_transaction. Funding TX is in the mempool. |
WAITING_FOR_ON_CHAIN_CONFIRMATION | - (chain) | ON_CHAIN_CONFIRMATION | Waiting for confirmations on the funding TX. |
ON_CHAIN_CONFIRMATION | - (Magma) | SELLER_OPENED_CHANNEL | TX confirmed. Magma verifying the channel exists in the graph. |
SELLER_OPENED_CHANNEL | - (Magma) | VALID_CHANNEL_OPENING, INVALID_CHANNEL_OPENING | Channel detected. Magma checking that capacity, peer, and locks match the order. |
VALID_CHANNEL_OPENING | - | CHANNEL_MONITORING_FINISHED | ✅ Channel confirmed valid. Buyer has the agreed inbound capacity. |
CHANNEL_MONITORING_FINISHED | - | (terminal) | ✅ Lock period (promises.locked_min_block_length) elapsed. Order fully complete. |
SELLER_REJECTED | - | (terminal) | ❌ Seller rejected the order. |
SELLER_FAILED_TO_REACT | - | (terminal) | ❌ Seller never accepted or rejected before timing out. |
BUYER_FAILED_TO_PAY | - | (terminal) | ❌ HODL invoice expired without payment. |
BUYER_REJECTED | - | (terminal) | ❌ Buyer cancelled before paying. |
SELLER_FAILED_TO_OPEN_CHANNEL | - | (terminal) | ❌ Seller accepted, payment landed, but the channel was never broadcast. |
SELLER_FAILED_TO_SEND_SWAP | - | (terminal) | ❌ Swap leg failed after the funding TX was sent. |
INVALID_CHANNEL_OPENING | - | (terminal) | ❌ Channel was opened but didn't match the agreed terms (wrong capacity, wrong peer, etc.). |
ADMIN_CLOSED | - | (terminal) | ❌ Manually closed by Amboss support. Rare. |
Success vs in-flight. VALID_CHANNEL_OPENING is the first success state - at this point the buyer can already route over the channel. CHANNEL_MONITORING_FINISHED adds the guarantee that the seller honoured the lock duration.
MarketOrderPaymentStatus - full reference
Tracks the Lightning payment leg specifically. Independent of the channel-opening state machine above.
| Payment status | Meaning |
|---|---|
PENDING_PAYMENT | Invoice issued, waiting for payment. |
SUCCESSFUL_PAYMENT | ✅ Buyer paid the HODL invoice. |
HODL_INVOICE_TIMEOUT | ❌ Invoice expired before payment. |
SELLER_INVOICE_EXPIRED | ❌ Seller's invoice expired before payment landed. |
PAYMENT_FAILED | ❌ Payment attempt failed at the wallet or routing layer. |
PAYMENT_REJECTED_BY_DESTINATION | ❌ Seller's node rejected the HTLC. |
INVALID_PAYMENT_SECRET | ❌ Preimage mismatch. |
Detecting terminal states programmatically
If you're polling an order, you only need to stop when it reaches one of these statuses:
const TERMINAL_STATUSES = new Set([
// Success
"VALID_CHANNEL_OPENING",
"CHANNEL_MONITORING_FINISHED",
// Failures
"SELLER_REJECTED",
"SELLER_FAILED_TO_REACT",
"BUYER_REJECTED",
"BUYER_FAILED_TO_PAY",
"SELLER_FAILED_TO_OPEN_CHANNEL",
"SELLER_FAILED_TO_SEND_SWAP",
"INVALID_CHANNEL_OPENING",
"ADMIN_CLOSED",
]);
const SUCCESS_STATUSES = new Set([
"VALID_CHANNEL_OPENING",
"CHANNEL_MONITORING_FINISHED",
]);
function isTerminal(status: string) {
return TERMINAL_STATUSES.has(status);
}
function isSuccess(status: string) {
return SUCCESS_STATUSES.has(status);
}Never hard-code the in-flight list. Statuses can be added or refined; the safe pattern is to enumerate terminal states (which only grow) and treat anything else as "still in flight".
Polling cadence by phase
The expected wait at each step is very different. Adapt your polling interval so you're not hammering the API while a 6-block confirmation runs.
| Phase | Typical duration | Recommended poll interval |
|---|---|---|
WAITING_FOR_SELLER_APPROVAL | Seconds to minutes | 5–10 s |
WAITING_FOR_BUYER_PAYMENT | Until buyer pays (max: HODL invoice expiry) | 5–10 s |
WAITING_FOR_CHANNEL_OPEN | Seconds | 5–10 s |
WAITING_FOR_ON_CHAIN_CONFIRMATION | One or more blocks (~10 min each) | 30–60 s |
ON_CHAIN_CONFIRMATION → SELLER_OPENED_CHANNEL | Seconds | 15–30 s |
See Tracking Orders for a complete polling reference implementation.
Next steps
- Tracking Orders - polling pattern with example code
- Orders and Offers - the data model behind each status
- Errors - what to do when an order hits a failure state
- Sell Liquidity - the seller-side mutations that drive these transitions