Skip to content

Card Payments

Card checkout is now a widget mode, not a separate public component. Use declarative methods and default-pay-method on <tokenflight-widget>.

Should you read this?

Read this page if users can pay by card, or if your checkout offers both crypto and card tabs.

Card-only payment does not need a wallet adapter for the card path. Mixed crypto/card checkout still needs a wallet adapter for the crypto tab.

Mixed Crypto + Card

html
<tokenflight-widget
  api-endpoint="https://api.hyperstream.dev"
  fiat-api-endpoint="https://fiat.hyperstream.dev"
  to-token="eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  trade-type="EXACT_OUTPUT"
  amount="100"
  methods='["crypto","card"]'
  theme="dark"
></tokenflight-widget>

<script type="module">
  import { registerWidgetElement } from '@tokenflight/swap/widget';

  registerWidgetElement();
</script>
AttributeTypeDefaultDescription
methodsstring["crypto"]JSON array: ["crypto"], ["card"], or ["crypto","card"]
default-pay-methodstring--Used by EXACT_INPUT swap mode to skip the picker; mixed receive/card checkout opens with the picker
fiat-currencystringUSDDefault fiat currency for card payments
fiat-api-endpointstringhttps://fiat.hyperstream.dev when omittedFiat API base URL
refund-tostring--End-user wallet to refund if ODA/card settlement cannot complete

Register your fiat API origin before launch

Browser access to https://fiat.hyperstream.dev uses an exact-origin allowlist. Before enabling card payments, email partners@tunnelvisionlabs.xyz to register every origin that will call the fiat API.

Send each complete origin as scheme://hostname[:port], for example https://app.example.com. Register production, staging, and preview origins separately. Paths and wildcard domains are not accepted. Requests from an unregistered browser origin are rejected by the fiat API.

The card flow always opens the provider (e.g. Transak) in a new browser window via window.open, and the widget polls order status until the transaction settles.

Contract recipients

If recipient is a contract or hook address, keep recipient pointed at that contract and set refund-to to the end user's wallet. The card path uses recipient for successful ODA settlement and refund-to for failed settlement fallback.

Payment Modes

Crypto Only (Default)

html
<tokenflight-widget
  to-token="eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  trade-type="EXACT_OUTPUT"
  amount="50"
></tokenflight-widget>

<script type="module">
  import { registerWidgetElement } from '@tokenflight/swap/widget';

  registerWidgetElement();
</script>

Card Only

html
<tokenflight-widget
  to-token="eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  trade-type="EXACT_OUTPUT"
  amount="50"
  methods='["card"]'
></tokenflight-widget>

<script type="module">
  import { registerWidgetElement } from '@tokenflight/swap/widget';

  registerWidgetElement();
</script>

Both Methods

html
<tokenflight-widget
  to-token="eip155:8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  trade-type="EXACT_OUTPUT"
  amount="100"
  methods='["crypto","card"]'
  theme="dark"
></tokenflight-widget>

<script type="module">
  import { registerWidgetElement } from '@tokenflight/swap/widget';

  registerWidgetElement();
</script>

Callbacks

Card and mixed-method flows use standard widget callbacks plus fiat-specific lifecycle callbacks:

CallbackPayloadDescription
onFiatOrderCreated{ orderId, widgetUrl }Called when the card provider widget URL is ready
onFiatOrderCompleted{ orderId, status, txHash? }Called when a card order reaches a terminal status
onDepositSuccessSwapSuccessDataCalled on successful fixed-output crypto completion
onDepositErrorSwapErrorDataCalled on fixed-output crypto or card execution error
onQuoteReceivedQuoteResponseCalled when a new quote is received
onAmountChangedAmountChangedDataCalled when the user changes an editable amount
onWalletConnectedWalletConnectedDataCalled on wallet connection

Next step