Daimo Pay SDK
The best way to embed Daimo Pay into your app is via the @daimo/pay
SDK.
The SDK is open source. You can find it on NPM and GitHub. For installation instructions, see the Quickstart. For a live demo of common use-cases, see the DaimoPayButton Demo. For details, see below.

DaimoPayButton Reference
- Name
appId
*- Type
- string
- Description
Your public app ID. Use
pay-demo
for prototyping only.
- Name
intent
- Type
- string
- Description
The intent verb, such as "Pay", "Deposit", or "Purchase".
- Name
toAddress
*- Type
- string
- Description
The destination address to transfer to, or contract to call.
- Name
toChain
*- Type
- number
- Description
Destination chain ID.
- Name
toUnits
- Type
- string
- Description
Controls the exact amount to receive. Must be a precise decimal string (e.g. "1.00" for $1.00 USDC). Providing more decimals than the underlying token supports will result in an error.
When specified: User pays a fixed amount. You receive exactly this amount, with no rounding from fees or slippage. Ideal for checkouts.
When omitted: User can input any amount to send. Ideal for deposits or top-ups into your app.
- Name
toToken
*- Type
- string
- Description
The destination token to send, completing payment. Must be an ERC-20 token or the zero address
0x0000000000000000000000000000000000000000
, indicating the native token such as ETH. For ERC-20, iftoCallData
is specified, then the payment amount will be approved to the destinationtoAddress
immediately before calling the contract. Otherwise, the amount will be transferred totoAddress
.
- Name
toCallData
- Type
- string
- Description
Optional calldata to execute an arbitrary contract call if
toAddress
is a contract. If specified, we'll automatically make a token approval oftoUnits
to the contract before executing the call.
- Name
paymentOptions
- Type
- string[]
- Description
Optional filter to show only a subset of payment options. By default, all are enabled. The available options are:
Coinbase
,Binance
,Solana
,RampNetwork
, andExternalChains
.ExternalChains
includes Bitcoin, Tron, Zcash, and other non-EVM chains. With these options, even users with no crypto wallet can complete payment.
- Name
preferredChains
- Type
- number[]
- Description
Optional preferred chain IDs. Assets on these chains will appear first.
- Name
preferredTokens
- Type
- object[]
- Description
Optional preferred tokens. Assets in these specific tokens will appear first, taking precedence over
preferredChains
. Each token has the format:{ chain: number, address: string }
.
- Name
externalId
- Type
- string
- Description
Optional. Associates this payment with an external ID, such as your system's unique checkout or deposit ID. Passed in webhooks and returned in API responses.
Multiple calls with the same
externalId
will return the same Payment instead of creating new ones. This prevents accidentally creating duplicate payments.
- Name
metadata
- Type
- object
- Description
Optional. Attach key-value data to the payment object that persists across webhooks and API responses. For example, attach your system’s unique ID to simplify tracking, or store customer information with their payment.
You can specify up to 50 key-value pairs. Keys and values are stored as strings.
- Name
redirectReturnUrl
- Type
- string
- Description
Optional. Redirect URL to return to the app. After the user pays with Coinbase, Binance, or RampNetwork, they will be redirected back to this URL.
import { encodeFunctionData } from "viem";
<DaimoPayButton
{/* Required props */}
appId="pay-demo"
toAddress="0x1234567890123456789012345678901234567890"
toChain={10} // Optimism
toUnits="1.00" // $1, Optimism USDC
toToken="0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"
{/* Optional props */}
intent="Purchase NFT"
toCallData=toCallData={encodeFunctionData({ // Example contract call
abi: yourContractAbi,
functionName: "mintNFT",
args: ["RECIPIENT_ADDRESS", quantity],
})}
paymentOptions={["Coinbase", "Binance"]}
preferredChains={[10, 8453]} // Prefer Optimism, Base
preferredTokens={[ // Prefer Optimism USDC
{ chain: 10, address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85" }
]},
externalId="123",
metadata={{ mySystemId: "123", name: "John Doe" }}
{/* Event handlers */}
onPaymentStarted={(e) => console.log(e)}
onPaymentCompleted={(e) => console.log(e)}
onPaymentBounced={(e) => console.log(e)}
/>
Themes and Customization
You can customize the appearance of both the button and the modal according to preset themes or using customTheme
.
- Name
mode
- Type
- string
- Description
Light mode, dark mode, or auto.
- Name
theme
- Type
- string
- Description
Named theme. See docs for options.
- Name
customTheme
- Type
- object
- Description
Custom theme. See docs for options.
- Name
closeOnSuccess
- Type
- boolean
- Description
Automatically close the modal after a successful payment.
- Name
disabled
- Type
- boolean
- Description
Disable interaction.
<DaimoPayButton
appId="pay-demo"
toAddress="0x1234567890123456789012345678901234567890"
toChain={8453} // Base
toUnits="0.001" // 0.001 ETH
toToken="0x0000000000000000000000000000000000000000"
mode="dark"
theme="rounded"
{/* alternatively, customTheme={...} */}
closeOnSuccess
/>
Event Handlers
- Name
onPaymentStarted
- Type
- function
- Description
Called when the user sends payment and the transaction is seen on the chain.
- Name
onPaymentCompleted
- Type
- function
- Description
Called when the destination transfer or call completes successfully.
- Name
onPaymentBounced
- Type
- function
- Description
Called when the destination call reverts and funds are refunded.
The events passed to the onPayment...
handlers match the events passed to
webhooks. You can use them for immediate feedback, while using
webhooks for things like backend order status tracking. This ensures robust
tracking even if the user loses network during payment.
const [latest, setLatest] = useState<DaimoPayEvent>();
return (<>
<DaimoPayButton
{/* For existing payments created via API, use payId. */}
payId="72hebvwpDJDA9qNubzb2jYjAbdDgjH4uD53rBnh8BR3A"
{/* Either way, the onPayment... handlers always work. */}
onPaymentStarted={setLatest}
onPaymentCompleted={setLatest}
onPaymentBounced={setLatest}
/>
{latest.type === 'payment_started' && <Spinner />}
{latest.type === 'payment_completed' && <SuccessLink txHash={latest.txHash} />}
{latest.type === 'payment_bounced' && <RevertLink txHash={latest.txHash} />}
</>);
DaimoPayButton.Custom
In addition, you can replace the DaimoPayButton entirely with your own button using DaimoPayButton.Custom.
- Name
children
*- Type
- function
- Description
Custom renderer function that receives show/hide methods and returns React node.
<DaimoPayButton.Custom
appId="pay-demo"
toAddress="0x1234567890123456789012345678901234567890"
toChain={10} /* Optimism */
toUnits="1.23" /* $1.23 USDC */
toToken="0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"
>
{({ show, hide }) => <button onClick={show}>Custom Pay Button</button>}
</DaimoPayButton.Custom>
Configuration Reference
The @daimo/pay
SDK uses a configuration object to set up providers for your application. This configuration is essential for initializing the SDK and ensuring compatibility with the supported chains and transports. Below is a detailed reference to the configuration options available in defaultConfig
.
defaultConfig
Parameters
- Name
appName
- Type
- string
- Description
The name of your application. This is displayed to users during wallet connections and other interactions. Default is "Daimo Pay".
- Name
appIcon
- Type
- string
- Description
Optional URL pointing to the app's icon. Used in wallet connection UIs.
- Name
appDescription
- Type
- string
- Description
Optional description of your app. Shown to users in wallet connection prompts.
- Name
appUrl
- Type
- string
- Description
Optional URL of your app. Used in wallet connection interfaces.
- Name
ssr
- Type
- boolean
- Description
Indicates whether the app uses server-side rendering (SSR). Set to
true
for SSR-enabled projects. Default isfalse
.
- Name
walletConnectProjectId
- Type
- string
- Description
Optional WalletConnect Project ID. Tracks usage statistics and ensures proper connection. Defaults to Daimo's WalletConnect Project ID.
- Name
connectors
- Type
- function[]
- Description
Specifies wallet connectors. Defaults to Daimo's recommended connectors and configurations. Will override all default connectors and
additionalConnectors
.
- Name
additionalConnectors
- Type
- function[]
- Description
Optional additional wallet connectors to use in the configuration. Extend the list of default connectors with custom wallet connectors.
- Name
transports
- Type
- object
- Description
Defines the network transport (e.g., HTTP) for each supported chain. If not provided, default wagmi HTTP transports are used.
import { getDefaultConfig } from "@daimo/pay";
import { createConfig, http } from "wagmi";
import { mainnet, optimism } from "wagmi/chains";
// Define your configuration
const config = createConfig(
getDefaultConfig({
appName: "My Ethereum App",
appIcon: "https://example.com/icon.png",
appDescription: "An app for seamless crypto payments",
appUrl: "https://example.com",
walletConnectProjectId: "your-project-id", // Replace with your WalletConnect Project ID
additionalConnectors: [], // Add custom wallet connectors here
transports: {
[mainnet.id]: http("https://eth.llamarpc.com"),
[optimism.id]: http("https://optimism-rpc.publicnode.com"),
},
}),
);