Build fully custom payment UIs with these React hooks. Use them when the pre-built components don’t fit your needs.
Order Hooks
useAnyspendQuote
Get real-time pricing for token swaps and cross-chain transactions. Quotes auto-refresh every 10 seconds.
import { useAnyspendQuote } from "@b3dotfun/sdk/anyspend";
const {
anyspendQuote,
isLoadingAnyspendQuote,
getAnyspendQuoteError,
refetchAnyspendQuote
} = useAnyspendQuote(quoteRequest);
Parameters
Quote configuration object
interface QuoteRequest {
srcChain: number; // Source chain ID
dstChain: number; // Destination chain ID
srcTokenAddress: string; // Source token contract address
dstTokenAddress: string; // Destination token contract address
type: "swap" | "custom"; // Order type
tradeType: "EXACT_INPUT" | "EXACT_OUTPUT";
amount: string; // Amount in smallest unit (wei)
}
Returns
Quote data with pricing, fees, and expected output
Error if quote request failed
Manually refresh the quote
Example
function SwapQuote() {
const quoteRequest = {
srcChain: 1,
dstChain: 8453,
srcTokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum
dstTokenAddress: "0x0000000000000000000000000000000000000000", // ETH
type: "swap" as const,
tradeType: "EXACT_INPUT" as const,
amount: "1000000", // 1 USDC
};
const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError } =
useAnyspendQuote(quoteRequest);
if (isLoadingAnyspendQuote) return <div>Getting best price...</div>;
if (getAnyspendQuoteError) return <div>Failed to get quote</div>;
return (
<div>
<p>You'll receive: {anyspendQuote?.expectedOutput} ETH</p>
<p>Network fee: ${anyspendQuote?.networkFeeUsd}</p>
<p>Service fee: ${anyspendQuote?.serviceFeeUsd}</p>
</div>
);
}
useAnyspendCreateOrder
Create and execute AnySpend orders for crypto payments.
import { useAnyspendCreateOrder } from "@b3dotfun/sdk/anyspend";
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
onSuccess: (data) => console.log("Order created:", data.data.id),
onError: (error) => console.error("Failed:", error.message),
});
Parameters
options
UseAnyspendCreateOrderProps
Configuration with callback functions
UseAnyspendCreateOrderProps
interface UseAnyspendCreateOrderProps {
onSuccess?: (data: CreateOrderResponse) => void;
onError?: (error: Error) => void;
onSettled?: () => void;
}
Returns
createOrder
(params: CreateOrderParams) => void
Function to create an order
interface CreateOrderParams {
recipientAddress: string;
orderType: string; // "swap", "hype_duel", "custom_exact_in", etc.
srcChain: number;
dstChain: number;
srcToken: Token;
dstToken: Token;
srcAmount: string;
expectedDstAmount?: string;
creatorAddress?: string;
metadata?: Record<string, unknown>;
callbackMetadata?: Record<string, unknown>;
nft?: NFT & { price: string };
tournament?: Tournament & { contractAddress: string; entryPriceOrFundAmount: string };
payload?: any;
}
Example
function PaymentForm() {
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
onSuccess: (data) => {
router.push(`/payment/${data.data.id}`);
},
onError: (error) => {
toast.error("Payment failed. Please try again.");
},
});
const handlePayment = () => {
createOrder({
recipientAddress: merchantAddress,
orderType: "swap",
srcChain: 1,
dstChain: 8453,
srcToken: { chainId: 1, address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", name: "USD Coin", symbol: "USDC", decimals: 6 },
dstToken: { chainId: 8453, address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", name: "USD Coin", symbol: "USDC", decimals: 6 },
srcAmount: "10000000",
creatorAddress: userAddress,
});
};
return (
<button onClick={handlePayment} disabled={isCreatingOrder}>
{isCreatingOrder ? "Processing..." : "Pay 10 USDC"}
</button>
);
}
useAnyspendCreateOnrampOrder
Create orders for fiat onramp payments (Stripe, Coinbase Pay).
import { useAnyspendCreateOnrampOrder } from "@b3dotfun/sdk/anyspend";
const { createOrder, isCreatingOrder } = useAnyspendCreateOnrampOrder({
onSuccess: (data) => {
// Redirect user to onramp provider
window.location.href = data.data.oneClickBuyUrl;
},
});
Parameters
UseAnyspendCreateOnrampOrderProps
interface UseAnyspendCreateOnrampOrderProps {
onSuccess?: (data: CreateOrderResponse) => void;
onError?: (error: Error) => void;
}
Returns
createOrder
(params: CreateOnrampOrderParams) => void
Function to create a fiat onramp order
type CreateOnrampOrderParams = {
recipientAddress: string;
orderType: string;
dstChain: number;
dstToken: Token;
expectedDstAmount?: string;
srcFiatAmount: string; // Fiat amount (e.g., "10.00")
onramp: {
vendor: "coinbase" | "stripe";
paymentMethod: string; // e.g., "card"
country: string; // ISO country code
redirectUrl: string; // URL to redirect after payment
};
};
Order Tracking Hooks
useAnyspendOrderAndTransactions
Monitor order status and track associated blockchain transactions in real-time.
import { useAnyspendOrderAndTransactions } from "@b3dotfun/sdk/anyspend";
const {
orderAndTransactions,
isLoadingOrderAndTransactions,
getOrderAndTransactionsError
} = useAnyspendOrderAndTransactions(orderId);
Parameters
Returns
orderAndTransactions
OrderWithTransactions | null
Complete order data with transaction details
isLoadingOrderAndTransactions
Loading state
getOrderAndTransactionsError
Error if fetch failed
interface OrderWithTransactions {
data: {
order: Order; // Order details and status
depositTxs: Transaction[]; // User deposit transactions
relayTx?: Transaction; // Cross-chain relay transaction
executeTx?: Transaction; // Final execution transaction
refundTxs: Transaction[]; // Refund transactions (if any)
};
}
Example
function OrderTracker({ orderId }: { orderId: string }) {
const { orderAndTransactions, isLoadingOrderAndTransactions } =
useAnyspendOrderAndTransactions(orderId);
if (isLoadingOrderAndTransactions) return <div>Loading...</div>;
const { order, depositTxs, executeTx } = orderAndTransactions!.data;
return (
<div>
<h2>Order #{orderId.slice(0, 8)}</h2>
<p>Status: {order.status}</p>
{executeTx && (
<a href={`https://basescan.org/tx/${executeTx.txHash}`}>
View Transaction
</a>
)}
</div>
);
}
useAnyspendOrderHistory
Retrieve paginated order history for a user address.
import { useAnyspendOrderHistory } from "@b3dotfun/sdk/anyspend";
const { orderHistory, isLoadingOrderHistory } =
useAnyspendOrderHistory(creatorAddress, limit, offset);
Parameters
Number of orders to fetch (max 100)
Token & Chain Hooks
useAnyspendTokens
Fetch available tokens for a specific chain with optional search.
import { useAnyspendTokens } from "@b3dotfun/sdk/anyspend";
const { tokens, isLoadingTokens } = useAnyspendTokens(chainId, searchQuery);
Parameters
Chain ID to fetch tokens for
Optional search filter (token name or symbol)
useGasPrice
Fetch real-time gas prices for a chain with spike detection.
import { useGasPrice } from "@b3dotfun/sdk/anyspend";
const { gasPrice, isLoading, isSpike, refetch } = useGasPrice(chainId);
Parameters
Chain ID to fetch gas price for
interface UseGasPriceOptions {
/** Refetch interval in ms (default: 10000) */
refetchInterval?: number;
/** Enable/disable the query (default: true if chainId is supported) */
enabled?: boolean;
}
Returns
Gas price data including fast, standard, and slow estimates
Whether gas is currently spiking above normal levels
Manually refresh gas price
Payment Hooks
useDirectTransfer
Execute direct transfers when source and destination token/chain match, bypassing the swap backend for faster, cheaper transactions.
import { useDirectTransfer } from "@b3dotfun/sdk/anyspend";
const { executeDirectTransfer, isTransferring } = useDirectTransfer();
Returns
executeDirectTransfer
(params: DirectTransferParams) => Promise<string | undefined>
Execute a direct transfer. Returns the transaction hash on success.
interface DirectTransferParams {
chainId: number;
tokenAddress: string;
recipientAddress: string;
amount: bigint;
method: CryptoPaymentMethodType; // "CONNECT_WALLET" | "GLOBAL_WALLET"
}
Example
function DirectTransferButton({ token, recipient, amount }) {
const { executeDirectTransfer, isTransferring } = useDirectTransfer();
const handleTransfer = async () => {
const txHash = await executeDirectTransfer({
chainId: token.chainId,
tokenAddress: token.address,
recipientAddress: recipient,
amount: BigInt(amount),
method: CryptoPaymentMethodType.CONNECT_WALLET,
});
if (txHash) {
toast.success("Transfer complete!");
}
};
return (
<button onClick={handleTransfer} disabled={isTransferring}>
{isTransferring ? "Transferring..." : "Send Tokens"}
</button>
);
}
Fiat & Onramp Hooks
useGeoOnrampOptions
Get all available onramp options based on the user’s geographic location. Combines geo detection, Coinbase availability, and Stripe support.
import { useGeoOnrampOptions } from "@b3dotfun/sdk/anyspend";
const {
isOnrampSupported,
coinbaseOnrampOptions,
stripeOnrampSupport,
stripeWeb2Support,
isLoading,
} = useGeoOnrampOptions(fiatAmount);
Parameters
The fiat amount for the onramp (e.g., "50")
Returns
Whether any fiat onramp is available for the user’s location
Coinbase Pay configuration and available payment methods
coinbaseAvailablePaymentMethods
Available Coinbase payment methods for the user’s region
Whether Stripe redirect flow is supported
Whether Stripe embedded form is supported ({ isSupport: boolean })
User’s detected geographic data (country, city, timezone)
useCoinbaseOnrampOptions
Get Coinbase Pay onramp configuration for fiat payments.
import { useCoinbaseOnrampOptions } from "@b3dotfun/sdk/anyspend";
const { coinbaseOptions, isLoadingCoinbaseOptions } = useCoinbaseOnrampOptions(country);
Parameters
ISO country code (e.g., "US")
useStripeSupport
Check Stripe payment availability based on the user’s location and payment amount.
import { useStripeSupport } from "@b3dotfun/sdk/anyspend";
const {
stripeOnrampSupport,
stripeWeb2Support,
isLoadingStripeSupport,
} = useStripeSupport(usdAmount, visitorData, isLoadingVisitorData);
Parameters
USD amount for the payment
Fingerprint.js visitor data (optional, for fraud detection)
Whether visitor data is still loading
Returns
Whether Stripe redirect flow is available
Whether Stripe embedded form is available
useStripeClientSecret
Get a Stripe client secret for initializing the embedded Stripe payment form.
import { useStripeClientSecret } from "@b3dotfun/sdk/anyspend";
const { clientSecret, isLoadingClientSecret } = useStripeClientSecret(paymentIntentId);
Checkout Session Hooks
useCreateCheckoutSession
Create a checkout session for backend-tracked payment flows.
import { useCreateCheckoutSession } from "@b3dotfun/sdk/anyspend";
const { mutate: createSession, data, isPending } = useCreateCheckoutSession();
createSession({
success_url: "https://mysite.com/success/{SESSION_ID}",
metadata: { sku: "widget-1" },
});
useCheckoutSession
Query a checkout session with automatic polling. Stops polling when status reaches complete or expired.
import { useCheckoutSession } from "@b3dotfun/sdk/anyspend";
const { data: session, isLoading } = useCheckoutSession(sessionId);
Parameters
Checkout session ID to track
Returns
Session data including status, order_id, metadata
Example
function CheckoutSessionTracker({ sessionId }) {
const { data: session, isLoading } = useCheckoutSession(sessionId);
if (isLoading) return <div>Loading...</div>;
switch (session?.data.status) {
case "open":
return <div>Waiting for payment...</div>;
case "processing":
return <div>Payment received, processing order...</div>;
case "complete":
return <div>Order complete! Order ID: {session.data.order_id}</div>;
case "expired":
return <div>Session expired. Please create a new checkout.</div>;
}
}
Hook Patterns
Error Handling
function PaymentComponent() {
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
onError: (error) => {
switch (error.message) {
case "INSUFFICIENT_BALANCE":
toast.error("Insufficient balance. Please add funds.");
break;
case "SLIPPAGE":
toast.error("Price moved unfavorably. Please try again.");
break;
case "QUOTE_EXPIRED":
toast.info("Getting fresh quote...");
break;
default:
toast.error("Payment failed. Please try again.");
}
},
});
// ...
}
Loading State Composition
function SwapInterface() {
const { anyspendQuote, isLoadingAnyspendQuote } = useAnyspendQuote(quoteRequest);
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder();
const isLoading = isLoadingAnyspendQuote || isCreatingOrder;
return (
<div>
{isLoading && <LoadingSpinner />}
{/* Rest of component */}
</div>
);
}
Next Steps