Appearance
useExchangePayOrder
Create a deposit order, read checkout fields, track status, and close when supported.
When to use
Amount form submit → checkout screen → pending payment. Session must be active. Pair with expiry & countdown on the checkout step.
Must be used under ExchangePayContextProvider. createOrder() builds the request from the current selection.
Example — create
tsx
import {
useExchangePayAmount,
useExchangePayOrder,
useExchangePaySelection,
} from '@swapped/connect-sdk/react'
function DepositForm() {
const { canSubmit } = useExchangePaySelection()
const { error: amountError, setTouched } = useExchangePayAmount()
const { createOrder, isCreating, error, order } = useExchangePayOrder()
async function onSubmit() {
setTouched(true)
if (!canSubmit) return
await createOrder()
}
return (
<div>
{(amountError || error) && (
<p>{(amountError?.message ?? error?.message)}</p>
)}
<button
type="button"
disabled={isCreating || !canSubmit}
onClick={() => void onSubmit()}
>
{isCreating ? 'Creating…' : 'Continue'}
</button>
{order && <p>Order {order.id} created</p>}
</div>
)
}Example — checkout
tsx
import {
useExchangePayOrder,
useOnExchangePayOrderExpired,
} from '@swapped/connect-sdk/react'
function Checkout({ onExpired }: { onExpired: () => void }) {
const { order, closeOrder, status, isCompleted } = useExchangePayOrder()
useOnExchangePayOrderExpired(() => {
// e.g. toast.info('Order expired, please try again')
onExpired() // navigate back to deposit
})
if (!order) return null
if (isCompleted) return <p>Payment received</p>
const { qr, url, mobileUrl } = order.checkout
return (
<div>
<p>Status: {status}</p>
{/* 'PENDING' | 'PAY_SUCCESS' | 'AWAITING_PROVIDER_FUNDS' | null */}
{qr?.type === 'image' && <img src={qr.value} alt="Pay QR" />}
{qr?.type === 'url' && <QrCode value={qr.value} /> /* e.g. qrcode.react */}
{url && (
<a href={url} target="_blank" rel="noreferrer">
Open checkout
</a>
)}
{mobileUrl && mobileUrl !== url && (
<a href={mobileUrl}>Open in app</a>
)}
{order.canClose && (
<button type="button" onClick={() => void closeOrder()}>
Cancel order
</button>
)}
</div>
)
}On expiry, order is cleared. Handle toast / navigate with useOnExchangePayOrderExpired. expiredOrder is available if you still need the last order payload.
Checkout fields
| Field | Use for |
|---|---|
order.checkout.qr | { type: 'image' | 'url', value } |
order.checkout.url | Desktop link (may be null) |
order.checkout.mobileUrl | Mobile / deep link (may be null) |
order.expiresAt | Countdown — see Expiry |
order.canClose | Whether to show cancel (closeOrder) |
Closing: If canClose is true, call closeOrder() when the user leaves checkout. If false (Bybit, OKX), skip cancel UI; create a new order when needed. Starting a new order also clears the previous active order.
Returns
| Field | Purpose |
|---|---|
order | Active ExchangePayOrder or null (cleared on expiry) |
expiredOrder | Last expired order, or null (cleared on create / close / reset) |
status | Latest status string or null |
transaction | Full ExchangePayOrderStatus or null |
isCompleted / isExpired | Convenience flags |
createOrder / closeOrder / getOrder | Actions |
isCreating / isClosing / isFetchingStatus | In-flight flags |
error | Last action failure |
Errors
| Code | When | What to do |
|---|---|---|
REACT_EXCHANGE_PAY_PROVIDER_REQUIRED | Used outside ExchangePayContextProvider | Wrap with the provider |
EXCHANGE_PAY_SELECTION_INCOMPLETE | Missing provider / currency / amount | Complete selection first |
SESSION_NOT_ACTIVE | Session cannot pay again | restartSession() |
SESSION_REQUIRED | Session not loaded | loadSession() |
NO_ACTIVE_ORDER | Status/close without an order | Back to form / create |
CLOSE_ACTIVE_ORDER_FAILED | Close API failed | Retry or create again |
API_ERROR | Create / status / close failure | Retry |
See Errors.