Appearance
Expiry & countdown
Live order expiry state for the checkout screen.
When to use
Show time remaining while an order is active, and switch to expired UI when the timer hits zero. Prefer these hooks over manually parsing order.expiresAt.
Hooks
| Hook | Returns | Updates |
|---|---|---|
useExchangePayOrderExpiry() | { expiresAt, hasActiveOrder, timeLeftMs, isExpired } | When the active order changes |
useExchangePayOrderCountdown() | Same + { hours, minutes, seconds } | Ticks every 1 second while active |
Both wrap the active order from useExchangePayOrder, so they require ExchangePayContextProvider. Countdown is what you usually want for a visible timer.
Example
tsx
import {
useExchangePayOrder,
useExchangePayOrderCountdown,
} from '@swapped/connect-sdk/react'
function PendingPayment() {
const { order, isCompleted, closeOrder } = useExchangePayOrder()
const { hours, minutes, seconds, isExpired, hasActiveOrder } =
useExchangePayOrderCountdown()
if (!hasActiveOrder) return null
if (isCompleted) return <p>Payment received</p>
if (isExpired) return <p>Order expired — create a new one</p>
return (
<div>
<p>
Time left: {hours}:{minutes}:{seconds}
</p>
{order?.canClose && (
<button type="button" onClick={() => void closeOrder()}>
Cancel
</button>
)}
</div>
)
}For side effects when the order expires (navigate away, toast), use useOnExchangePayOrderExpired — see Event hooks.
Notes
- Expiry is per order, not a Coinbase submission cooldown.
- When the order expires,
useExchangePayOrder().orderis cleared and the last order is kept onexpiredOrderif you still need the payload. - After expiry, create a new order — do not reuse old checkout links.
isExpiredfrom the countdown hook anduseExchangePayOrder().isExpiredshould stay in sync; either is fine for UI.
Errors
These hooks do not throw. Order create / close errors come from useExchangePayOrder — see Errors.