When orders expire and what happens if a payment never arrives
Learn when StableOps orders expire, how late transfers are handled, how to choose payment windows, and why expired and canceled orders need reconciliation.
Every payment order carries an expiresAt timestamp. If no matching transfer
arrives before then, the order is moved to expired and a payment.expired
webhook is sent.
How expiration is processed
A background worker scans for expired orders on a short repeating interval
(roughly once a minute), so an order flips to expired shortly after
expiresAt passes, not at the exact second. Each expiration runs in a
transaction that:
- moves the order from
createdtoexpired, - releases the addresses that were allocated to it back to the pool, and
- enqueues a
payment.expiredwebhook.
Only orders still in created can expire. Once an order reaches detected,
confirmed, or finalized, the deadline no longer applies. A payment already
in flight is never dropped just because the clock ran out.
A payment that arrives after expiry
If a customer pays after the order has expired, the transfer will not revive the order:
- The order is no longer in
created, so the exact-match rule can't promote it. - The address may already have been released and reused by another order.
Handle this the same way as any other misdirected transfer: reconcile or refund manually against the address the funds landed on. With BYO addresses those funds are in an address you control.
Choosing an expiration window
- Pick a window long enough for a real human to open a wallet, copy the amount, and have the transfer confirm. A few minutes is usually too tight; 15–60 minutes is a common range.
- Don't set it so long that abandoned orders hold addresses (in single-address mode) far longer than needed.
- If you don't need an order anymore before anyone has paid, cancel it
instead of waiting for expiry. Cancellation also releases the addresses and
emits
payment_order.canceled. Only orders still increatedcan be canceled.
expired vs canceled
| State | Trigger | Emits |
|---|---|---|
expired | expiresAt passed with no matching transfer | payment.expired |
canceled | You called the cancel endpoint while still created | payment_order.canceled |
Both release any addresses still held by the order.
Related
How is this guide?
Last updated
A customer underpaid, overpaid, or sent on the wrong chain
Learn how StableOps records underpayments, overpayments, wrong-chain transfers, and late payments, plus when to use its refund API or recover funds manually.
A payment was confirmed but then reverted
Understand why StableOps payments can revert after detection or confirmation, how to reverse provisional fulfillment, and why orders should await finalized.