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/sdk2. 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>| Prop | Type | Default | Description |
|---|---|---|---|
| apiKey | string | — | PayDirect API key (pd_live_ or pd_test_) |
| baseUrl | string | "" | API base URL. Empty = same-origin proxied calls |
| theme | "light" | "dark" | "auto" | "auto" | Widget theme (inherits from parent by default) |
| onError | (err: string) => void | — | Global 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" />| Prop | Type | Description |
|---|---|---|
| amount | string | Fixed payment amount |
| token | "USDC" | "ETH" | "ADAO" | Token to accept |
| showForm | boolean | Show amount input + token selector |
| compact | boolean | Render as inline button instead of card |
| description | string | Payment description |
| merchantWallet | string | Custom settlement address |
| metadata | Record<string, string> | Custom metadata attached to payment |
| buttonText | string | Custom button label |
| onSuccess | (payment) => void | Callback on successful payment creation |
| onError | (error) => void | Callback 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)}
/>| Prop | Type | Description |
|---|---|---|
| defaultTokenIn | string | Input token (USDC, ETH, ADAO) |
| defaultTokenOut | string | Output token |
| defaultAmount | string | Pre-filled amount |
| walletType | "eoa" | "smart_wallet" | Wallet for executing swap (smart_wallet = gasless) |
| title | string | Widget title |
| onSuccess / onError | callbacks | Swap 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 />| Prop | Type | Description |
|---|---|---|
| showSmartWallet | boolean | Show smart wallet section (default: true) |
| showAddress | boolean | Show wallet addresses (default: true) |
| autoRefresh | number | Auto-refresh interval in seconds |
| compact | boolean | Render as inline pill (for navbars/headers) |
| onBalanceLoaded | (balance) => void | Callback 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"
/>| Prop | Type | Description |
|---|---|---|
| defaultToken | "USDC" | "ETH" | "ADAO" | Pre-selected token |
| defaultDestination | string | Pre-filled destination address |
| walletType | "eoa" | "smart_wallet" | Sending wallet type |
| title | string | Widget title |
| onSuccess / onError | callbacks | Result / 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 />| Prop | Type | Description |
|---|---|---|
| limit | number | Max transactions to show (default: 10) |
| showPayments | boolean | Include incoming payments (default: true) |
| showPayouts | boolean | Include outgoing payouts (default: true) |
| autoRefresh | number | Polling interval in seconds |
| compact | boolean | Compact 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 />| Prop | Type | Description |
|---|---|---|
| variant | "badge" | "card" | "status-bar" | Display variant |
| showDetails | boolean | Show 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)}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| defaultAsset | "USDC" | "ETH" | "USDC" | Pre-selected asset |
| defaultFiatAmount | number | — | Pre-fill fiat amount |
| fiatCurrency | string | "USD" | Fiat currency code |
| mode | "popup" | "inline" | "popup" | Open in popup window or inline iframe |
| onSuccess | function | — | Callback with { onrampUrl, channelId } |
| onError | function | — | Error callback |
| title | string | "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
| Widget | API Used | Variants | Use Case |
|---|---|---|---|
| PaymentButton | POST /payments | Card, Form, Compact | Checkout, donations, invoices |
| SwapWidget | GET /swap/quote, POST /swap | Card | Token exchange, OTC, rebalancing |
| BalanceDisplay | GET /wallet/balance | Card, Compact pill | Wallet dashboard, navbar, sidebar |
| PayoutForm | POST /payouts | Card | Send funds, vendor payouts, withdrawals |
| TransactionHistory | GET /payments, GET /payouts | Card, Compact | Activity feed, audit trail |
| ConnectBadge | GET /wallet/balance | Badge, Status bar, Card | Connection status, health check |
| OnrampWidget | POST /onramp/session | Popup, Inline | Buy 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 skeletonOption 2: Install via npm (coming soon)
npm install @paydirect/react-widgetsThis 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.