Component showcase Every checkout state, rendered live from the real SDK components — click any card to flip it and see the code.
These are not screenshots — every card below renders the actual
components from @runtab/sdk, the same code that runs inside a real
checkout. Every value on the cards (amounts, addresses, you@example.com)
is sample display data — nothing here touches the network. Use the
Code button on any card to flip it and copy the JSX.
PayButton trigger </> Code
Pay $12.00
The idle trigger — the only thing a merchant renders. PayButton trigger Copy Preview
<PayButton
apiBaseUrl="https://app.your-tab.example"
publishableKey="pk_test_…"
intentUrl="/api/payment-intent"
onSuccess={(txId, changes) => confirm(txId)}
/> Flowline </> Code
Progress strip — advances only on real checkout events. Flowline Copy Preview
<Flowline stage="confirming" /> Balance </> Code
$12.00
to Museum Shop
Your balance $20.00 available Sandbox funds — no real value
Pay $12.00 Real balance read; test mode reads Base Sepolia USDC on-chain. Balance Copy Preview
<BalanceState
amount="12.00" balance="20.00"
merchantName="Museum Shop"
mode="test" onConfirm={confirm}
/> Insufficient — test mode </> Code
Not enough to complete this payment
Your balance $0.00 available $12.00 short . Nothing has been charged.
Get free test funds Add funds Cancel The exact shortfall, plus an in-flow test-funds grant. Insufficient — test mode Copy Preview
<InsufficientState
balance="0.00" shortfall="12.00" mode="test"
onGetTestFunds={claim} onRecheck={recheck}
onAddFunds={open} onCancel={close}
/> Add funds </> Code
Add funds
Send test USDC to this address. Sandbox funds — no real value.
0x1111111111111111111111111111111111111111
Copy address Check balance again Cancel The buyer's real deposit address — selectable, copyable. Add funds Copy Preview
<AddFundsState
address="0x1111…1111" mode="test"
onRecheck={recheck} onCancel={close}
/> Device approval </> Code
Approve this new device
We sent an approval link to yo•••@example.com . Approve from your inbox — this screen continues automatically.
Start over A real state, not a failure — continues automatically. Device approval Copy Preview
<DeviceApprovalState
email="you@example.com"
onStartOver={restart}
/> Processing </> Code
Honest loading — no fake progress bars. Processing Copy Preview
<LoadingState label="Processing your payment…" /> Still working </> Code
Taking longer than expected
It may still complete — do not submit it again. You can close this window; the result will appear in your receipt.
Close — check receipts later After 20s confirming: money may be in flight — never claims failure. Still working Copy Preview
<StuckState onClose={close} /> Success </> Code
amount $12.00
Reference #TAB-7K2M9
Settled · Test Payment complete
Done Receipt with reference code and the stamped 402 → 200. Success Copy Preview
<SuccessState
amount="12.00" mode="test"
refCode="TAB-7K2M9" onDone={close}
/> Honest error </> Code
!
Something didn’t go through
Nothing has been charged.
Try again Cancel "Nothing has been charged" — only promised when provably true. Honest error Copy Preview
<ErrorState
title="Not enough to complete this payment"
body="Nothing has been charged."
onCancel={close} onRetry={retry}
/>
The full interactive checkout — with a real intent, real balance reads,
and in-flow test funds — runs at /demo on your app origin.
Every component above responds to the appearance prop on <PayButton>:
< PayButton
// …
appearance = {{
actionColor: "#161310" , // primary pay button
accentColor: "#0e4fd7" , // progress / emphasis
}}
/>