Skip to main content

Checkout Flow

This guide walks through the complete checkout flow, from creating a transaction to polling for settlement completion.

Overview

The checkout flow follows these steps:
  1. Create a transaction with createCheckoutTransaction
  2. Attach the source wallet with attachCheckoutTransactionSource
  3. Quote the conversion with getCheckoutTransactionQuote
  4. Submit the transaction with submitCheckoutTransaction (prepares, signs, and broadcasts)
  5. Poll for completion with getCheckoutTransaction

Full example

import {
  createCheckoutTransaction,
  attachCheckoutTransactionSource,
  getCheckoutTransactionQuote,
  submitCheckoutTransaction,
  getCheckoutTransaction,
} from '@dynamic-labs-sdk/client';

const checkout = async (walletAccount) => {
  // Step 1: Create the transaction
  const { transaction } = await createCheckoutTransaction({
    amount: '25.00',
    currency: 'USD',
    checkoutId: 'checkout_abc123',
  });

  // Step 2: Attach the wallet source
  await attachCheckoutTransactionSource({
    transactionId: transaction.id,
    fromAddress: walletAccount.address,
    fromChainId: '1',
    fromChainName: walletAccount.chain,
  });

  // Step 3: Get a quote
  const quoted = await getCheckoutTransactionQuote({
    transactionId: transaction.id,
    fromTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
  });

  console.log('Quote:', quoted.quote);

  // Step 4: Submit (prepare + sign + broadcast)
  const result = await submitCheckoutTransaction({
    transactionId: transaction.id,
    walletAccount,
  });

  // Step 5: Poll for completion
  const final = await getCheckoutTransaction({
    transactionId: transaction.id,
  });

  console.log('Final state:', final.settlementState);
};

Handling cancellation and errors

import {
  submitCheckoutTransaction,
  cancelCheckoutTransaction,
} from '@dynamic-labs-sdk/client';

try {
  await submitCheckoutTransaction({
    transactionId: transaction.id,
    walletAccount,
  });
} catch (error) {
  if (error.message.includes('rejected')) {
    // User rejected the signing request in their wallet
    await cancelCheckoutTransaction({
      transactionId: transaction.id,
    });
    console.log('Transaction cancelled');
  } else {
    console.error('Checkout failed:', error.message);
  }
}

Polling for status

After submission, poll getCheckoutTransaction to track progress through execution and settlement states:
import { getCheckoutTransaction } from '@dynamic-labs-sdk/client';

const TERMINAL_EXECUTION = ['cancelled', 'expired', 'failed'];
const TERMINAL_SETTLEMENT = ['completed', 'failed'];

const pollTransaction = async (transactionId) => {
  const poll = async () => {
    const tx = await getCheckoutTransaction({ transactionId });

    if (
      TERMINAL_EXECUTION.includes(tx.executionState) ||
      TERMINAL_SETTLEMENT.includes(tx.settlementState)
    ) {
      return tx;
    }

    await new Promise((resolve) => setTimeout(resolve, 3000));
    return poll();
  };

  return poll();
};

Supported Chains

The checkout flow supports the following chains (mainnet only):
  • BTC
  • EVM
  • SOL
  • SUI