Skip to content

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 ​

HookReturnsUpdates
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().order is cleared and the last order is kept on expiredOrder if you still need the payload.
  • After expiry, create a new order - do not reuse old checkout links.
  • isExpired from the countdown hook and useExchangePayOrder().isExpired should stay in sync; either is fine for UI.

Errors ​

These hooks do not throw. Order create / close errors come from useExchangePayOrder - see Errors.