Pay Widget
The OnePayWidget is a unified payment component that consolidates multiple payment flows into a single, configurable widget. It supports three modes and ships with focused presets for common use cases. The ONE SDK (@one_deploy/sdk v1.1.0) exposes this as a web-only React DOM component.
OnePayWidget and all its presets render to the DOM and require a browser environment. They are not available in React Native or Node.js. Use the OneEngineClient API methods directly on those platforms.
Modes
| Mode | Description | Use Case |
|---|---|---|
fund_wallet | Fund a crypto wallet using fiat via local payment methods | Wallet top-up, onboarding new users |
direct_payment | Pay a merchant or recipient directly (fiat or crypto) | Checkout flows, invoices, donations |
transaction | Execute an arbitrary on-chain transaction with a payment UI | Smart contract interactions, NFT purchases |
OnePayWidget Component
import { OnePayWidget } from '@one_deploy/sdk';
OnePayWidgetProps
interface OnePayWidgetProps {
/** Payment mode */
mode: 'fund_wallet' | 'direct_payment' | 'transaction';
// --- Common props (all modes) ---
/** Connected wallet address */
walletAddress: string;
/** Chain ID */
chainId?: number;
/** Widget color theme */
theme?: 'light' | 'dark' | 'auto';
/** Override CSS class name */
className?: string;
/** Called on successful payment */
onSuccess?: (result: PayWidgetResult) => void;
/** Called on error */
onError?: (error: { code: string; message: string }) => void;
/** Called when user closes the widget */
onClose?: () => void;
// --- fund_wallet mode props ---
/** Default fiat amount to fund */
defaultAmount?: number;
/** Default fiat currency (ISO 4217) */
defaultFiatCurrency?: string;
/** Crypto token to deposit into wallet */
targetToken?: string;
/** User's country for local payment providers */
country?: string;
/** Restrict payment methods */
allowedPaymentMethods?: string[];
// --- direct_payment mode props ---
/** Recipient wallet address (merchant / payee) */
recipientAddress?: string;
/** Fixed payment amount (disables user editing) */
fixedAmount?: number;
/** Fixed fiat currency */
fixedFiatCurrency?: string;
/** Fixed crypto token */
fixedCryptoToken?: string;
/** Accept fiat payments */
acceptFiat?: boolean;
/** Accept crypto payments */
acceptCrypto?: boolean;
/** Order / invoice reference displayed to the user */
orderReference?: string;
/** Merchant name displayed in the widget */
merchantName?: string;
// --- transaction mode props ---
/** Target contract address */
contractAddress?: string;
/** Encoded transaction data */
transactionData?: string;
/** Native token value to send with the transaction */
transactionValue?: string;
/** Human-readable description of what the transaction does */
transactionDescription?: string;
/** Token required to execute (user can buy it in-widget if missing) */
requiredToken?: {
symbol: string;
address: string;
amount: string;
};
}
interface PayWidgetResult {
/** Payment mode that was used */
mode: 'fund_wallet' | 'direct_payment' | 'transaction';
/** Transaction identifier */
transactionId: string;
/** On-chain transaction hash */
txHash?: string;
/** Payment status */
status: PaymentStatus;
/** Amount paid (fiat, if applicable) */
fiatAmount?: number;
/** Fiat currency */
fiatCurrency?: string;
/** Crypto amount */
cryptoAmount?: string;
/** Crypto token */
cryptoCurrency?: string;
/** Recipient address */
recipientAddress?: string;
/** ISO 8601 timestamp */
completedAt: string;
}
type PaymentStatus =
| 'pending'
| 'processing'
| 'completed'
| 'failed'
| 'expired'
| 'refunded';
Mode 1: fund_wallet
Fund a user's crypto wallet using local fiat payment methods. This is the same flow described in E-wallet Top-up, wrapped in the unified Pay Widget.
import { OnePayWidget } from '@one_deploy/sdk';
function FundWalletExample() {
return (
<OnePayWidget
mode="fund_wallet"
walletAddress="0xUserWallet..."
chainId={137}
defaultAmount={50}
defaultFiatCurrency="NGN"
targetToken="USDT"
country="NG"
onSuccess={(result) => {
console.log('Wallet funded!');
console.log(`Received: ${result.cryptoAmount} ${result.cryptoCurrency}`);
}}
onError={(error) => console.error(error.message)}
theme="light"
/>
);
}
OneFundWalletWidget Preset
import { OneFundWalletWidget } from '@one_deploy/sdk';
function FundWalletPreset() {
return (
<OneFundWalletWidget
walletAddress="0xAbc..."
chainId={137}
defaultFiatCurrency="KES"
targetToken="USDC"
country="KE"
defaultAmount={5000}
onSuccess={(result) => console.log('Funded:', result)}
/>
);
}
Mode 2: direct_payment
Accept a payment from a user to a merchant or recipient. Supports both fiat and crypto payment paths. The widget handles currency selection, amount entry (or displays a fixed amount), and routes the payment.
import { OnePayWidget } from '@one_deploy/sdk';
function CheckoutExample() {
return (
<OnePayWidget
mode="direct_payment"
walletAddress="0xCustomerWallet..."
chainId={1}
recipientAddress="0xMerchantWallet..."
fixedAmount={29.99}
fixedFiatCurrency="USD"
acceptFiat={true}
acceptCrypto={true}
orderReference="ORDER-12345"
merchantName="Example Store"
onSuccess={(result) => {
console.log('Payment received!');
console.log(`Order: ORDER-12345, tx: ${result.txHash}`);
}}
onError={(error) => console.error(error.message)}
theme="dark"
/>
);
}
Crypto-only Direct Payment
import { OnePayWidget } from '@one_deploy/sdk';
function CryptoPaymentExample() {
return (
<OnePayWidget
mode="direct_payment"
walletAddress="0xCustomerWallet..."
chainId={137}
recipientAddress="0xMerchantWallet..."
fixedCryptoToken="USDC"
fixedAmount={50}
acceptFiat={false}
acceptCrypto={true}
merchantName="Crypto Cafe"
onSuccess={(result) => console.log('Paid with USDC:', result.txHash)}
/>
);
}
OneDirectPayWidget Preset
A shorthand for mode="direct_payment" with both fiat and crypto enabled:
import { OneDirectPayWidget } from '@one_deploy/sdk';
function DirectPayPreset() {
return (
<OneDirectPayWidget
walletAddress="0xCustomer..."
recipientAddress="0xMerchant..."
fixedAmount={100}
fixedFiatCurrency="USD"
merchantName="Acme Corp"
orderReference="INV-9876"
onSuccess={(result) => console.log('Paid:', result)}
/>
);
}
OneCryptoOnlyPayWidget Preset
Restricts the widget to crypto-only payments:
import { OneCryptoOnlyPayWidget } from '@one_deploy/sdk';
function CryptoOnlyPreset() {
return (
<OneCryptoOnlyPayWidget
walletAddress="0xCustomer..."
chainId={1}
recipientAddress="0xMerchant..."
fixedCryptoToken="ETH"
onSuccess={(result) => console.log('Crypto payment:', result.txHash)}
/>
);
}
OneFiatOnlyPayWidget Preset
Restricts the widget to fiat-only payments (on-ramp + transfer to recipient):
import { OneFiatOnlyPayWidget } from '@one_deploy/sdk';
function FiatOnlyPreset() {
return (
<OneFiatOnlyPayWidget
walletAddress="0xCustomer..."
recipientAddress="0xMerchant..."
fixedAmount={75}
fixedFiatCurrency="EUR"
merchantName="EU Store"
onSuccess={(result) => console.log('Fiat payment:', result)}
/>
);
}
Mode 3: transaction
Execute an arbitrary on-chain transaction with a payment UI layer. This is useful when the user needs to interact with a smart contract but may need to acquire tokens first.
import { OnePayWidget } from '@one_deploy/sdk';
function NFTPurchaseExample() {
return (
<OnePayWidget
mode="transaction"
walletAddress="0xBuyerWallet..."
chainId={1}
contractAddress="0xNFTContractAddress..."
transactionData="0xa0712d680000000000000000000000000000000000000000000000000000000000000001"
transactionValue="0.08"
transactionDescription="Mint 1 NFT from Cool Collection"
requiredToken={{
symbol: 'ETH',
address: '0x0000000000000000000000000000000000000000',
amount: '0.08',
}}
onSuccess={(result) => {
console.log('NFT minted!');
console.log(`Tx: ${result.txHash}`);
}}
onError={(error) => console.error('Mint failed:', error.message)}
theme="light"
/>
);
}
Token-gated Transaction
When the user does not have enough of the required token, the widget offers to buy or swap for it first, then executes the transaction:
function TokenGatedExample() {
return (
<OnePayWidget
mode="transaction"
walletAddress="0xUserWallet..."
chainId={137}
contractAddress="0xStakingContract..."
transactionData="0x..."
transactionDescription="Stake 1000 USDC in the yield pool"
requiredToken={{
symbol: 'USDC',
address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
amount: '1000',
}}
onSuccess={(result) => {
console.log('Staked successfully:', result.txHash);
}}
/>
);
}
The widget flow for token-gated transactions:
1. Check user balance 2. If insufficient, 3. Execute the
for required token offer buy/swap --> target transaction
| in-widget
v
Sufficient? ----yes---> Execute immediately
Styling
All OnePayWidget variants accept theme and className props:
<OnePayWidget
mode="direct_payment"
walletAddress="0x..."
recipientAddress="0x..."
theme="dark"
className="my-custom-pay-widget"
// ...
/>
Override internal styles with the className and CSS custom properties:
.my-custom-pay-widget {
--one-pay-primary: #6c5ce7;
--one-pay-background: #1a1a2e;
--one-pay-text: #eaeaea;
--one-pay-border-radius: 12px;
--one-pay-font-family: 'Inter', sans-serif;
max-width: 420px;
}
Preset Summary
| Preset | Mode | Fiat | Crypto | Description |
|---|---|---|---|---|
OneFundWalletWidget | fund_wallet | Yes | -- | Fund wallet via local payment methods |
OneDirectPayWidget | direct_payment | Yes | Yes | Accept fiat and crypto payments |
OneCryptoOnlyPayWidget | direct_payment | -- | Yes | Accept crypto payments only |
OneFiatOnlyPayWidget | direct_payment | Yes | -- | Accept fiat payments only |