Embeddable Widgets

NEW

Drop-in React components that bring full PayDirect functionality to any Next.js or React project. Wrap your app in a provider, pick the widgets you need, and you're live in minutes.

Quick Start — 3 Steps
From zero to crypto payments in under 5 minutes

1. Install the SDK

npm install @paydirect/sdk

2. Wrap your app with the Provider

// app/layout.tsx or _app.tsx
import { PayDirectProvider } from "@/components/widgets";

export default function Layout({ children }) {
  return (
    <PayDirectProvider
      apiKey={process.env.NEXT_PUBLIC_PAYDIRECT_API_KEY!}
      baseUrl=""  // same-origin, or "https://api.paydirect.com"
      theme="auto"
    >
      {children}
    </PayDirectProvider>
  );
}

3. Drop in any widget

import { PaymentButton, BalanceDisplay, SwapWidget } from "@/components/widgets";

export default function CheckoutPage() {
  return (
    <div className="space-y-6">
      <BalanceDisplay />
      <SwapWidget />
      <PaymentButton amount="25.00" token="USDC" description="Pro Plan" />
    </div>
  );
}
PayDirectProvider
Required
Context provider that supplies API credentials to all child widgets
<PayDirectProvider
  apiKey="pd_live_..."       // Your PayDirect API key
  baseUrl=""                 // API base URL (default: same origin)
  theme="auto"              // "light" | "dark" | "auto"
  onError={(err) => {}}     // Global error handler
>
  {children}
</PayDirectProvider>
PropTypeDefaultDescription
apiKeystringPayDirect API key (pd_live_ or pd_test_)
baseUrlstring""API base URL. Empty = same-origin proxied calls
theme"light" | "dark" | "auto""auto"Widget theme (inherits from parent by default)
onError(err: string) => voidGlobal error callback for all widgets
PaymentButton
Payments
Create payment invoices with a single click. Supports fixed-amount, form, and compact button modes.

Fixed Amount (checkout button)

<PaymentButton
  amount="25.00"
  token="USDC"
  description="Pro Plan — Monthly"
  onSuccess={(payment) => console.log("Payment created:", payment.id)}
/>

Custom Amount Form

<PaymentButton
  showForm
  token="USDC"
  description="Donation"
  buttonText="Donate with Crypto"
  onSuccess={(p) => router.push(`/thank-you?id=${p.id}`)}
/>

Compact Inline Button

<PaymentButton amount="5.00" token="USDC" compact buttonText="Pay" />
PropTypeDescription
amountstringFixed payment amount
token"USDC" | "ETH" | "ADAO"Token to accept
showFormbooleanShow amount input + token selector
compactbooleanRender as inline button instead of card
descriptionstringPayment description
merchantWalletstringCustom settlement address
metadataRecord<string, string>Custom metadata attached to payment
buttonTextstringCustom button label
onSuccess(payment) => voidCallback on successful payment creation
onError(error) => voidCallback on failure
SwapWidget
DEX Swaps
On-chain token swaps via Uniswap V3 with live quotes, slippage protection, and gasless execution.
<SwapWidget
  defaultTokenIn="USDC"
  defaultTokenOut="ETH"
  walletType="smart_wallet"
  onSuccess={(swap) => console.log("Swap tx:", swap.txHash)}
/>
PropTypeDescription
defaultTokenInstringInput token (USDC, ETH, ADAO)
defaultTokenOutstringOutput token
defaultAmountstringPre-filled amount
walletType"eoa" | "smart_wallet"Wallet for executing swap (smart_wallet = gasless)
titlestringWidget title
onSuccess / onErrorcallbacksSwap result / error callbacks
BalanceDisplay
Wallet
Real-time wallet balances for EOA and smart wallet, with auto-refresh and compact mode.

Full Card

<BalanceDisplay
  showSmartWallet
  showAddress
  autoRefresh={30}  // Refresh every 30 seconds
/>

Compact Inline (for navbars)

<BalanceDisplay compact />
PropTypeDescription
showSmartWalletbooleanShow smart wallet section (default: true)
showAddressbooleanShow wallet addresses (default: true)
autoRefreshnumberAuto-refresh interval in seconds
compactbooleanRender as inline pill (for navbars/headers)
onBalanceLoaded(balance) => voidCallback when balance data loads
PayoutForm
Payouts
Send crypto payouts to any wallet address. Gasless for smart wallet users.
<PayoutForm
  defaultToken="USDC"
  walletType="smart_wallet"
  onSuccess={(result) => console.log("Sent:", result.txHash)}
/>

// Pre-filled destination (e.g., vendor payouts)
<PayoutForm
  defaultToken="ADAO"
  defaultDestination="0xVendorWallet..."
  title="Pay Vendor"
/>
PropTypeDescription
defaultToken"USDC" | "ETH" | "ADAO"Pre-selected token
defaultDestinationstringPre-filled destination address
walletType"eoa" | "smart_wallet"Sending wallet type
titlestringWidget title
onSuccess / onErrorcallbacksResult / error callbacks
TransactionHistory
History
Live transaction feed showing payments and payouts with status, amounts, and block explorer links.
<TransactionHistory
  limit={20}
  showPayments
  showPayouts
  autoRefresh={15}
/>

// Compact mode (e.g., sidebar)
<TransactionHistory limit={5} compact />
PropTypeDescription
limitnumberMax transactions to show (default: 10)
showPaymentsbooleanInclude incoming payments (default: true)
showPayoutsbooleanInclude outgoing payouts (default: true)
autoRefreshnumberPolling interval in seconds
compactbooleanCompact view (hides dates and tx links)
ConnectBadge
Status
API connection status indicator in three variants: badge, status bar, and full card.
// Simple badge (for headers)
<ConnectBadge variant="badge" />

// Status bar (for dashboards)
<ConnectBadge variant="status-bar" />

// Full card with details
<ConnectBadge variant="card" showDetails />
PropTypeDescription
variant"badge" | "card" | "status-bar"Display variant
showDetailsbooleanShow API key, environment, rate limit, wallets (card variant)
OnrampWidget
Coinbase
Embed a crypto purchase button powered by Coinbase Onramp
import { OnrampWidget } from "@/components/widgets";

<OnrampWidget
  defaultAsset="USDC"
  defaultFiatAmount={50}
  mode="popup"
  onSuccess={({ onrampUrl }) => console.log("Onramp URL:", onrampUrl)}
/>
PropTypeDefaultDescription
defaultAsset"USDC" | "ETH""USDC"Pre-selected asset
defaultFiatAmountnumberPre-fill fiat amount
fiatCurrencystring"USD"Fiat currency code
mode"popup" | "inline""popup"Open in popup window or inline iframe
onSuccessfunctionCallback with { onrampUrl, channelId }
onErrorfunctionError callback
titlestring"Buy Crypto"Widget title
Complete Integration Examples
Copy-paste patterns for common use cases

E-Commerce Checkout Page

"use client"
import { PayDirectProvider, PaymentButton, BalanceDisplay } from "@/components/widgets";

export default function Checkout({ plan, price }) {
  return (
    <PayDirectProvider apiKey={process.env.NEXT_PUBLIC_PAYDIRECT_API_KEY!}>
      <div className="max-w-md mx-auto space-y-6">
        <h1>Subscribe to {plan}</h1>
        <PaymentButton
          amount={price}
          token="USDC"
          description={`${plan} Plan Subscription`}
          metadata={{ plan, userId: "user_123" }}
          onSuccess={(payment) => {
            // Redirect to success page
            window.location.href = `/success?id=${payment.id}`;
          }}
        />
      </div>
    </PayDirectProvider>
  );
}

Token Swap Platform

"use client"
import { PayDirectProvider, SwapWidget, BalanceDisplay } from "@/components/widgets";

export default function SwapPage() {
  return (
    <PayDirectProvider apiKey={process.env.NEXT_PUBLIC_PAYDIRECT_API_KEY!}>
      <div className="max-w-md mx-auto space-y-6">
        <BalanceDisplay compact />
        <SwapWidget
          defaultTokenIn="USDC"
          defaultTokenOut="ETH"
          walletType="smart_wallet"
          onSuccess={(swap) => {
            toast.success(`Swapped! Tx: ${swap.txHash.slice(0, 10)}...`);
          }}
        />
      </div>
    </PayDirectProvider>
  );
}

Admin Dashboard

"use client"
import {
  PayDirectProvider,
  ConnectBadge,
  BalanceDisplay,
  PayoutForm,
  TransactionHistory,
} from "@/components/widgets";

export default function Dashboard() {
  return (
    <PayDirectProvider apiKey={process.env.NEXT_PUBLIC_PAYDIRECT_API_KEY!}>
      <div className="space-y-6">
        <ConnectBadge variant="status-bar" />

        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
          <BalanceDisplay showSmartWallet autoRefresh={30} />
          <PayoutForm defaultToken="USDC" walletType="smart_wallet" />
        </div>

        <TransactionHistory limit={20} autoRefresh={15} />
      </div>
    </PayDirectProvider>
  );
}

AI Agent Payment Interface

"use client"
import {
  PayDirectProvider,
  BalanceDisplay,
  SwapWidget,
  TransactionHistory,
  ConnectBadge,
} from "@/components/widgets";

export default function AgentWallet() {
  return (
    <PayDirectProvider apiKey={process.env.NEXT_PUBLIC_PAYDIRECT_API_KEY!}>
      <div className="max-w-2xl mx-auto space-y-6">
        <div className="flex items-center justify-between">
          <h1>Agent Wallet</h1>
          <ConnectBadge variant="badge" />
        </div>
        <BalanceDisplay showSmartWallet autoRefresh={10} />
        <SwapWidget walletType="smart_wallet" title="Rebalance Portfolio" />
        <TransactionHistory limit={10} autoRefresh={10} />
      </div>
    </PayDirectProvider>
  );
}
Widget Reference
All available widgets at a glance
WidgetAPI UsedVariantsUse Case
PaymentButtonPOST /paymentsCard, Form, CompactCheckout, donations, invoices
SwapWidgetGET /swap/quote, POST /swapCardToken exchange, OTC, rebalancing
BalanceDisplayGET /wallet/balanceCard, Compact pillWallet dashboard, navbar, sidebar
PayoutFormPOST /payoutsCardSend funds, vendor payouts, withdrawals
TransactionHistoryGET /payments, GET /payoutsCard, CompactActivity feed, audit trail
ConnectBadgeGET /wallet/balanceBadge, Status bar, CardConnection status, health check
OnrampWidgetPOST /onramp/sessionPopup, InlineBuy crypto with fiat via Coinbase Onramp
Using Widgets in External Projects
How to use PayDirect widgets in any Next.js or React app

Option 1: Copy the widget files

Copy the components/widgets/ directory into your project. The widgets depend on shadcn/ui components (Card, Button, Input, Select, Badge, Skeleton) and lucide-react icons.

# Copy to your project
cp -r paydirect/components/widgets/ your-app/components/widgets/

# Install required dependencies
npm install lucide-react
npx shadcn@latest add card button input select badge skeleton

Option 2: Install via npm (coming soon)

npm install @paydirect/react-widgets

This package will include all widgets with zero-config theming and tree-shaking support.

Option 3: API-only (headless mode)

Use the PayDirect SDK directly for full control over the UI:

npm install @paydirect/sdk

import PayDirectClient from "@paydirect/sdk";

const client = new PayDirectClient({
  apiKey: process.env.PAYDIRECT_API_KEY!,
});

// All SDK methods available:
// client.createPayment(...)
// client.getBalance()
// client.sendPayout(...)
// client.getSwapQuote(...)
// client.executeSwap(...)
// client.listPayments(...)
// etc.