Documentation Index Fetch the complete documentation index at: https://anypay-trails-api-docs.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Pay with Trails
Trails revolutionizes crypto purchases by enabling users to buy NFTs, RWAs, or any other asset using any token a user holds from any supported chain. The payee simply specifies the settlement asset that they would like the payment to be reconciled in or to successfully complete the purchase, for example USDC, ETH, or any other token and the payer can select how they’d like to pay from their aggregated balance.
Accept USDC, USDT, or any token as payment. Your user pays with whatever they have—Trails handles the conversion automatically and any executions automatically.
You Settle In User Pays With Trails Handles USDC on Polygon ETH on Arbitrum Bridge + Swap USDC on Polygon POL on Polygon Swap USDC on Base USDC on Base Normal Execution
Use Cases
Pay flows in Trails are modeled as exact output by default. This means the developer simply defines the total amount the payee should receive for the payment and Trails will automatically include any additional fees to successfully fulfill the payment. For example, “I want to receive exactly 1 USDC tokens on the destination chain, so the user will send 1.01 USDC on the origin chain.”
Ideal for use cases such as the following:
Purchase and/or mint an NFT directly from a marketplace on any chain
Use crypto to make a purchase at an ecommerce platform
Transfer a specific amount of funds to a user
Make an x402 payment in any token from any chain
Execute smart contract calls with an attached payment
Stablecoin Payment Examples
Accept USDC on Polygon
Settle in USDC on Polygon—users pay from any chain:
import { TrailsWidget } from '0xtrails/widget'
< TrailsWidget
apiKey = "YOUR_API_KEY"
mode = "pay"
toAddress = "0xYOUR_MERCHANT_ADDRESS"
toAmount = "25"
toChainId = { 137 } // Polygon
toToken = "USDC"
onCheckoutComplete = { ({ sessionId }) => {
// Mark order as paid
updateOrderStatus ( orderId , 'paid' , sessionId )
} }
>
< button > Pay $25 </ button >
</ TrailsWidget >
Cross-Chain USDC with CCTP (Polygon Settlement)
Use Circle’s Cross-Chain Transfer Protocol for native USDC bridging:
< TrailsWidget
apiKey = "YOUR_API_KEY"
mode = "pay"
toAddress = "0xYOUR_MERCHANT_ADDRESS"
toAmount = "500"
toChainId = { 137 } // Polygon
toToken = "USDC"
bridgeProvider = "CCTP" // Native USDC bridging
onCheckoutComplete = { ({ sessionId }) => {
processLargePayment ( sessionId )
} }
>
< button > Pay $500 </ button >
</ TrailsWidget >
Purchasing an NFT on Arbitrum
This example shows how to use the Trails widget to purchase an NFT on Arbitrum, where the user can pay with any token from any chain that automatically gets converted to ETH to fulfill the purchase:
import { TrailsWidget } from '0xtrails/widget'
import { encodeFunctionData } from 'viem'
import { nftABI } from './abi.ts'
export const CrossChainNFTPurchase = () => {
// NFT contract address on Arbitrum
const NFT_CONTRACT = "0xAA3df3c86EdB6aA4D03b75092b4dd0b99515EC83"
// NFT purchase calldata
const purchaseCalldata = encodeFunctionData ({
abi: nftABI ,
functionName: 'mint' ,
args: [
"0x97c4a952b46becad0663f76357d3776ba11566e1" , // recipient address
],
})
return (
< TrailsWidget
apiKey = "YOUR_API_KEY"
mode = "pay"
toAddress = { NFT_CONTRACT }
toAmount = "0.00002"
toChainId = { 42161 } // Arbitrum
toToken = "ETH"
toCalldata = { purchaseCalldata }
onCheckoutComplete = { ({ sessionId }) => {
console . log ( 'NFT purchase completed:' , sessionId )
// Handle successful purchase
} }
onCheckoutError = { ({ sessionId , error }) => {
console . error ( 'Purchase failed:' , sessionId , error )
} }
theme = "auto"
>
< button className = "nft-purchase-button" >
Buy NFT (0.00002 ETH)
</ button >
</ TrailsWidget >
)
}
Merchant Integration Pattern
Complete ecommerce checkout flow with order verification:
import { TrailsWidget } from '0xtrails/widget'
import { useState } from 'react'
export function CheckoutButton ({ order }) {
const [ status , setStatus ] = useState ( 'pending' )
return (
< TrailsWidget
apiKey = { process . env . TRAILS_API_KEY }
mode = "pay"
toAddress = { process . env . MERCHANT_WALLET }
toAmount = { order . total . toString () }
toChainId = { 137 } // Polygon
toToken = "USDC"
onCheckoutStart = { ({ sessionId }) => {
// Create pending payment record
createPaymentRecord ({
orderId: order . id ,
sessionId ,
amount: order . total ,
status: 'processing'
})
setStatus ( 'processing' )
} }
onCheckoutComplete = {async ({ sessionId }) => {
// Verify payment on your backend
const verified = await verifyPayment ( sessionId )
if ( verified ) {
await fulfillOrder ( order . id )
setStatus ( 'complete' )
}
} }
onCheckoutError = { ({ sessionId , error }) => {
logPaymentError ( sessionId , error )
setStatus ( 'failed' )
} }
>
< button disabled = { status === 'processing' } >
{ status === 'processing' ? 'Processing...' : `Pay $ ${ order . total } ` }
</ button >
</ TrailsWidget >
)
}
Backend Payment Verification
Verify payments server-side before fulfilling orders:
// api/verify-payment.ts
import { Trails } from '@0xtrails/api'
const trails = new Trails ({ accessKey: process . env . TRAILS_ACCESS_KEY })
export async function verifyPayment ( sessionId : string , expectedAmount : string ) {
const receipt = await trails . getIntentReceipt ({ intentId: sessionId })
// Verify the payment completed successfully
if ( receipt . status !== 'COMPLETED' ) {
return { verified: false , reason: 'Payment not completed' }
}
// Verify the amount matches
const receivedAmount = receipt . destinationTransaction ?. amount
if ( receivedAmount !== expectedAmount ) {
return { verified: false , reason: 'Amount mismatch' }
}
return { verified: true , receipt }
}
API-Based Fee Estimation
For server-side fee estimation or custom UIs:
const quote = await fetch ( 'https://trails-api.sequence.app/rpc/Trails/QuoteIntent' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'X-Access-Key' : 'YOUR_ACCESS_KEY'
},
body: JSON . stringify ({
ownerAddress: userWallet ,
originChainId: 137 , // User's funds on Polygon
originTokenAddress: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174' , // USDC on Polygon
destinationChainId: 8453 , // Settle on Base
destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' , // USDC on Base
destinationToAddress: merchantAddress ,
destinationTokenAmount: '100000000' , // 100 USDC (6 decimals)
tradeType: 'EXACT_OUTPUT' ,
options: {
slippageTolerance: 0.005 // 0.5%
}
})
})
const { intent } = await quote . json ()
// Extract fee information
const fees = {
gasFee: intent . gasFee ,
bridgeFee: intent . bridgeFee ,
totalInput: intent . originAmount ,
estimatedOutput: intent . destinationAmount
}
Next Steps
Pay Mode Reference Complete configuration options and props
Gasless Payments Let users pay fees in stablecoins
x402 Payments HTTP 402 payment flows with Trails