Skip to main content

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.

Web Only

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

ModeDescriptionUse Case
fund_walletFund a crypto wallet using fiat via local payment methodsWallet top-up, onboarding new users
direct_paymentPay a merchant or recipient directly (fiat or crypto)Checkout flows, invoices, donations
transactionExecute an arbitrary on-chain transaction with a payment UISmart 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

PresetModeFiatCryptoDescription
OneFundWalletWidgetfund_walletYes--Fund wallet via local payment methods
OneDirectPayWidgetdirect_paymentYesYesAccept fiat and crypto payments
OneCryptoOnlyPayWidgetdirect_payment--YesAccept crypto payments only
OneFiatOnlyPayWidgetdirect_paymentYes--Accept fiat payments only

See Also