Documentation Index
Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
Checkout lets you send a crypto payment from any supported chain and have it settled in a specific token on a specific chain.
This guide walks through the complete checkout flow, from creating a transaction to polling for settlement completion.
Prerequisites
Before starting a checkout flow, you need a checkoutId. Create one by calling the Create a checkout API endpoint:
curl --request POST \
--url https://app.dynamic.xyz/api/v0/environments/<YOUR_ENVIRONMENT_ID>/checkouts \
--header 'Authorization: Bearer <YOUR_API_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"mode": "payment",
"settlementConfig": {
"strategy": "cheapest",
"settlements": [
{
"chainName": "EVM",
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"chainId": "1",
"symbol": "USDC",
"tokenDecimals": 18,
"isNative": false
}
]
},
"destinationConfig": {
"destinations": [
{
"chainName": "EVM",
"type": "address",
"identifier": "0xYourSettlementAddress"
}
]
},
"enableOrchestration": true
}'
The response includes an id field — use this as the checkoutId when calling createCheckoutTransaction.
Supported Chains
The checkout flow supports the following chains:
Except for the EVM chains listed below, only mainnet is supported:
| Name | ID |
|---|
| Base Sepolia Testnet | "84532" |
| Arbitrum Sepolia Testnet | "421614" |
| Arc Testnet | "5042002" |
| OP Sepolia Testnet | "11155420" |
Overview
The checkout flow follows these steps:
- Create a transaction with
createCheckoutTransaction
- Attach the source wallet with
attachCheckoutTransactionSource
- Quote the conversion with
getCheckoutTransactionQuote
- Submit the transaction with
submitCheckoutTransaction (prepares, signs, and broadcasts)
- 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();
};