Skip to main content
AnySpend components support four layers of customization that can be combined for full control over appearance and behavior. Each layer targets a different concern:

Slots

Replace entire UI sections with your own components

Content

Override text and messages for different states

Theme

Configure colors and brand appearance

Classes

Apply CSS class overrides to specific elements
All core components (<AnySpend>, <AnySpendDeposit>, <AnySpendCheckout>, <AnySpendCheckoutTrigger>) accept slots, content, and theme props.

Slots

Slots let you replace entire UI sections with your own React components. Each slot receives props from AnySpend that you can use in your custom implementation.
AnySpendSlots Interface
interface AnySpendSlots {
  /** Replace the main action/payment button */
  actionButton?: (props: ActionButtonSlotProps) => ReactNode;
  /** Replace the connect wallet button */
  connectWalletButton?: (props: ConnectWalletButtonSlotProps) => ReactNode;
  /** Replace the header */
  header?: (props: { mode: "page" | "modal" }) => ReactNode;
  /** Replace the footer */
  footer?: ReactNode;
  /** Replace the success screen */
  successScreen?: (props: SuccessScreenSlotProps) => ReactNode;
  /** Replace the error screen */
  errorScreen?: (props: ErrorScreenSlotProps) => ReactNode;
  /** Replace the checkout form panel (checkout only) */
  checkoutForm?: (props: CheckoutFormComponentProps) => ReactNode;
  /** Replace the shipping method selector (checkout only) */
  shippingSelector?: (props: ShippingSelectorSlotProps) => ReactNode;
  /** Replace the discount code input (checkout only) */
  discountInput?: (props: DiscountInputSlotProps) => ReactNode;
}
The checkoutForm, shippingSelector, and discountInput slots are only used in <AnySpendCheckout> and <AnySpendCheckoutTrigger>. See the Checkout Guide for details on form/shipping/discount features.

Slot Prop Interfaces

interface ActionButtonSlotProps {
  onClick: () => void;
  disabled: boolean;
  loading: boolean;
  text: string;
}
interface ConnectWalletButtonSlotProps {
  onPayment: () => void;
  txLoading: boolean;
  connectedAddress?: string;
  paymentLabel: string;
}
interface SuccessScreenSlotProps {
  title: string;
  description: string;
  txHash?: string;
  orderId?: string;
  explorerUrl?: string;
  onDone: () => void;
  returnUrl?: string;
  returnLabel?: string;
}
interface ErrorScreenSlotProps {
  title: string;
  description: string;
  errorType: "failure" | "expired" | "refunded";
  orderId?: string;
  onRetry?: () => void;
  onDone?: () => void;
}
interface CheckoutFormComponentProps {
  onSubmit: (data: Record<string, unknown>) => void;
  onValidationChange: (isValid: boolean) => void;
  formData: Record<string, unknown>;
  setFormData: (data: Record<string, unknown>) => void;
}
interface ShippingSelectorSlotProps {
  options: ShippingOption[];
  selectedId: string | null;
  onSelect: (option: ShippingOption) => void;
}
interface DiscountInputSlotProps {
  onApply: (code: string) => Promise<DiscountResult>;
  appliedDiscount: DiscountResult | null;
  onRemove: () => void;
  loading: boolean;
}

Slot Examples

<AnySpend
  recipientAddress="0x..."
  slots={{
    actionButton: ({ onClick, disabled, loading, text }) => (
      <button
        onClick={onClick}
        disabled={disabled}
        className="my-custom-button"
      >
        {loading ? <MySpinner /> : text}
      </button>
    ),
  }}
/>

Content

Override text and messages displayed during different transaction states. Each field accepts a string or ReactNode.
AnySpendContent Interface
interface AnySpendContent {
  // Success state
  successTitle?: string | ReactNode;
  successDescription?: string | ReactNode;

  // Failure state
  failureTitle?: string | ReactNode;
  failureDescription?: string | ReactNode;

  // Expired state
  expiredTitle?: string | ReactNode;
  expiredDescription?: string | ReactNode;

  // Refunded state
  refundedTitle?: string | ReactNode;
  refundedDescription?: string | ReactNode;

  // Processing state
  processingTitle?: string | ReactNode;
  processingDescription?: string | ReactNode;

  // Button labels
  returnButtonLabel?: string;
  retryButtonLabel?: string;
}

Content Examples

<AnySpendCheckout
  recipientAddress="0x..."
  destinationTokenAddress="0x..."
  destinationTokenChainId={8453}
  items={cartItems}
  content={{
    successTitle: "Order Confirmed!",
    successDescription: "Your order is being prepared. Check your email for shipping updates.",
    failureTitle: "Payment Failed",
    failureDescription: "Your card was not charged. Please try again or use a different payment method.",
    processingTitle: "Processing Payment...",
    processingDescription: "Please don't close this window. This usually takes under a minute.",
    returnButtonLabel: "Back to Store",
    retryButtonLabel: "Try Again",
  }}
/>

Theme

Configure the visual appearance of AnySpend components with brand colors.
AnySpendTheme Interface
interface AnySpendTheme {
  /** Primary brand color (hex). Applied as the main accent color. */
  brandColor?: string;
  /** Individual color overrides (hex values) */
  colors?: Partial<{
    primary: string;         // Main text color
    secondary: string;       // Secondary text color
    tertiary: string;        // Muted text color
    surfacePrimary: string;  // Primary background color
    surfaceSecondary: string; // Secondary background (cards, panels)
    brand: string;           // Accent/brand color (buttons, links)
    borderPrimary: string;   // Primary border color
    borderSecondary: string; // Secondary border color
  }>;
}
The brandColor prop is a shortcut that sets the brand color. If both brandColor and colors.brand are provided, colors.brand takes precedence.

Theme Examples

// Quick branding — just set your brand color
<AnySpend
  recipientAddress="0x..."
  theme={{ brandColor: "#6366f1" }}
/>

CSS Class Overrides

Apply custom CSS classes to specific elements within AnySpend components. Each component has its own class interface.

AnySpendClasses

Used by <AnySpend>:
AnySpendClasses
interface AnySpendClasses {
  container?: string;
  header?: string;
  tabSection?: string;
  cryptoPaySection?: string;
  cryptoReceiveSection?: string;
  panelOnramp?: string;
  paymentButton?: string;
  navigationBar?: string;
}

AnySpendCheckoutClasses

Used by <AnySpendCheckout> and <AnySpendCheckoutTrigger>:

Layout & Structure

interface AnySpendCheckoutClasses {
  root?: string;               // Root container
  layout?: string;             // Two-panel layout wrapper
  paymentColumn?: string;      // Left column (payment + forms)
  cartColumn?: string;         // Right column (cart/summary)
}
{
  paymentPanel?: string;            // Payment panel container
  paymentTitle?: string;            // "Pay with" title
  paymentMethodSelector?: string;   // Method selector container
  paymentMethodButton?: string;     // Individual method button
  cryptoPanel?: string;             // Crypto payment section
  tokenSelector?: string;           // Token dropdown
  quoteDisplay?: string;            // Quote/price display
  payButton?: string;               // Pay button
  fiatPanel?: string;               // Fiat payment section
  stripeForm?: string;              // Stripe form container
  stripeSubmitButton?: string;      // Stripe submit button
  coinbasePanel?: string;           // Coinbase panel
}
{
  cartPanel?: string;               // Cart container
  cartTitle?: string;               // Cart header
  cartItemRow?: string;             // Individual item row
  cartItemImage?: string;           // Item image
  cartItemName?: string;            // Item name
  cartItemDescription?: string;     // Item description
  cartItemPrice?: string;           // Item price
  cartItemMetadata?: string;        // Metadata container
  cartItemMetadataLabel?: string;   // Metadata label
  cartItemMetadataValue?: string;   // Metadata value
  cartSummary?: string;             // Summary section
  cartSubtotal?: string;            // Subtotal row
  cartTotal?: string;               // Total row
  cartSummaryLine?: string;         // Extra summary line
  cartSummaryLineLabel?: string;    // Summary line label
  cartSummaryLineAmount?: string;   // Summary line amount
  cartDiscount?: string;            // Discount row
}
{
  formPanel?: string;          // Form panel container
  formField?: string;          // Individual form field
  formFieldLabel?: string;     // Field label
  formFieldInput?: string;     // Field input
  shippingSelector?: string;   // Shipping option selector
  discountInput?: string;      // Discount code input
  addressForm?: string;        // Address form
}
{
  poweredBy?: string;          // "Powered by" footer
  successPanel?: string;       // Success screen
  returnButton?: string;       // Return/redirect button
  orderStatusPanel?: string;   // Order status tracker
  retryButton?: string;        // Retry button
  transactionLink?: string;    // Transaction explorer link
}

AnySpendDepositClasses

Used by <AnySpendDeposit>:
AnySpendDepositClasses
interface AnySpendDepositClasses {
  root?: string;
  chainSelection?: string;
  form?: string;
  balance?: string;
  options?: string;
  chainsList?: string;
  divider?: string;
  backButton?: string;
}

AnySpendAllClasses

Combine multiple class interfaces together. Used by <AnySpendDeposit> and <AnySpendWorkflowTrigger>:
AnySpendAllClasses
interface AnySpendAllClasses {
  deposit?: AnySpendDepositClasses;
  anySpend?: AnySpendClasses;
  checkout?: AnySpendCheckoutClasses;
  cryptoPaySection?: CryptoPaySectionClasses;
  cryptoReceiveSection?: CryptoReceiveSectionClasses;
  panelOnramp?: PanelOnrampClasses;
  orderDetails?: OrderDetailsClasses;
  recipientSelection?: RecipientSelectionClasses;
  qrDeposit?: QRDepositClasses;
  warningText?: WarningTextClasses;
  tabSection?: TabSectionClasses;
  feeDetailPanel?: FeeDetailPanelClasses;
  pointsDetailPanel?: PointsDetailPanelClasses;
  orderDetailsCollapsible?: OrderDetailsCollapsibleClasses;
  transferCryptoDetails?: TransferCryptoDetailsClasses;
}

Class Override Example

Custom Styling
<AnySpend
  recipientAddress="0x..."
  classes={{
    container: "rounded-2xl shadow-xl border border-gray-200",
    header: "bg-gradient-to-r from-blue-500 to-purple-500 text-white",
    paymentButton: "bg-indigo-600 hover:bg-indigo-700 rounded-xl font-bold",
  }}
/>
Checkout Styling
<AnySpendCheckout
  recipientAddress="0x..."
  destinationTokenAddress="0x..."
  destinationTokenChainId={8453}
  items={items}
  classes={{
    layout: "max-w-4xl mx-auto",
    cartPanel: "bg-gray-50 rounded-xl p-6",
    paymentPanel: "bg-white rounded-xl shadow-sm",
    branding: "text-center py-4",
  }}
/>

Combining Customizations

All customization layers work together. Here’s a complete example:
Fully Customized Checkout
<AnySpendCheckout
  recipientAddress="0x..."
  destinationTokenAddress="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
  destinationTokenChainId={8453}
  items={cartItems}
  organizationName="Acme Store"
  organizationLogo="/acme-logo.svg"

  // Theme — brand colors
  theme={{
    brandColor: "#4f46e5",
    colors: {
      surfaceSecondary: "#f5f3ff",
    },
  }}

  // Content — custom messages
  content={{
    successTitle: "Thank you for your purchase!",
    successDescription: "Your order confirmation has been sent to your email.",
    returnButtonLabel: "Continue Shopping",
  }}

  // Slots — custom components
  slots={{
    footer: (
      <div className="flex items-center justify-center gap-2 py-4 text-sm text-gray-500">
        <LockIcon />
        <span>Secure checkout powered by AnySpend</span>
      </div>
    ),
    successScreen: ({ title, description, txHash, onDone }) => (
      <div className="text-center p-8">
        <ConfettiAnimation />
        <h2 className="text-2xl font-bold">{title}</h2>
        <p className="text-gray-600 mt-2">{description}</p>
        <button onClick={onDone} className="mt-6 btn-primary">
          Continue Shopping
        </button>
      </div>
    ),
  }}

  // Classes — CSS overrides
  classes={{
    layout: "max-w-5xl mx-auto",
    cartPanel: "bg-indigo-50/50 rounded-2xl",
  }}
/>

Next Steps