Backstage pass · Sample event
Tap below to launch the embedded Flow widget and watch the lifecycle in the code panel on the right.
The buyer pays with any token from any wallet. The merchant's vault receives the configured stablecoin every time — Fireblocks Flow provides the swap, settlement, and webhook infrastructure[†].
Tap below to launch the embedded Flow widget and watch the lifecycle in the code panel on the right.
Your application should make clear to end-users that asset conversion and cross-chain routing are executed by independent third-party providers. Users keep full control of their assets and must explicitly sign each transfer. On-chain transactions are final and cannot be reversed.
By continuing, you agree to our Terms of Service and Privacy Policy.
Flow runs on mainnet networks only. Use a sandbox environment id with real mainnet addresses for development.
Server-side. Creates a flow with the buyer's amount, settlement asset(s), and merchant destination wallet — authenticated by an API token with flow.write scope. One flow per checkout when the amount or cart varies; reuse is possible only when amount and destination are identical.
// Runs on your server — one Flow per payment/deposit/withdraw.
// Requires an API token with flow.write scope.
const res = await fetch(
`https://app.dynamic.xyz/api/v0/server/${process.env.ENV_ID}/flow/payment`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.DYNAMIC_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: "5.00",
currency: "USD",
settlementConfig: {
strategy: "preferred_order",
settlements: [
{
chainName: "EVM",
chainId: "8453",
symbol: "USDC",
tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
tokenDecimals: 6,
},
],
},
destinationConfig: {
destinations: [
{
chainName: "EVM",
type: "address",
identifier: "<destination_address>",
},
],
},
}),
},
);
const { flow } = await res.json();
const flowId = flow.id;
// Pass flowId to your frontend.Declare the wallet and chain the buyer is paying from. Returns a session token (dft_…) that authenticates the rest of the lifecycle. Dynamic runs risk and sanctions screening here; a 403 means the source is blocked.
import { addEvmExtension } from "@dynamic-labs-sdk/evm";
import { attachFlowSource } from "@dynamic-labs-sdk/client";
addEvmExtension();
// Declare the payer's wallet + chain. Returns an updated flow and
// stores a session token (dft_…) for subsequent calls automatically.
await attachFlowSource({
flowId,
fromAddress: wallet.address,
fromChainId: String(fromChainId), // from the picked token — not getActiveNetworkData()
fromChainName: isSolanaChainId(fromToken.chainId) ? "SOL" : "EVM",
sourceType: "wallet",
});
// 403 → source blocked by risk/sanctions screening.Quote the cross-chain swap from the buyer's chosen token to the settlement asset. Pass fromChainId from the picked token. Quotes expire in 60 seconds — re-quote if the buyer takes longer.
import { getFlowQuote } from "@dynamic-labs-sdk/client";
const quoted = await getFlowQuote({
flowId,
fromTokenAddress: fromToken.address,
fromChainId: String(fromToken.networkId),
slippage: 0.005, // 0.5%
});
// quoted.quote.expiresAt — re-quote if the user takes longer than 60s.Three things happen here: Dynamic prepares the signing payload, the buyer signs it in their wallet, and your client notifies Dynamic that the chain tx is broadcast. The SDK collapses all three into submitFlowTransaction; the REST path keeps them separate so you can plug in your own wallet client.
import { submitFlowTransaction } from "@dynamic-labs-sdk/client";
// prepare → sign (wallet popup) → broadcast in one helper.
await submitFlowTransaction({
flowId,
walletAccount: wallet,
});Call getFlow to read executionState and settlementState. Production should subscribe to the flow.settlement.updated webhook for push-driven updates. Terminal success is settlementState === "completed"; terminal failure is executionState in ["failed", "expired", "cancelled"] or settlementState === "failed".
import { getFlow } from "@dynamic-labs-sdk/client";
const flow = await getFlow({ flowId });
// flow.executionState — lifecycle phase (e.g. "source_confirmed", "failed")
// flow.settlementState — "none" | "completed" | "failed"
// flow.settlement — { txHash?, … } once settledDynamic does not control the swap, bridge, or routing protocols used to convert and deliver assets. Rates and fees are sourced from third-party providers and may change between quote and execution.
Cross-chain transfers carry risk — including slippage, partial fills, and failed conversions. On-chain transactions are final and cannot be reversed.
These materials are not investment, financial, legal, or tax advice. You are responsible for evaluation at your own discretion. Please review Dynamic's terms and conditions for full details on acceptable use.