跳至主要内容

电子钱包充值

充值流程允许用户使用本地支付方式为其加密钱包充值 -- 移动支付、银行转账、本地银行卡和其他地区特定选项。ONE SDK(@one_deploy/sdk v1.1.0)通过 OnePayWidgetfund_wallet 模式和 OneEngineClient 上的 API 方法来提供此功能。

充值流程

  User initiates           SDK fetches           User selects         Payment is
top-up with amount --> local providers --> payment method --> processed
|
v
Tokens delivered
to wallet
  1. 用户指定希望添加到钱包的金额。
  2. SDK 查询用户所在国家可用的本地支付提供商。
  3. 用户选择支付方式并确认。
  4. 通过本地提供商处理支付。
  5. 等值的加密货币金额(扣除手续费后)将交付到用户的钱包。

Widget 用法(Web)

OnePayWidget 的 fund_wallet 模式

OnePayWidget 组件支持多种模式。设置为 fund_wallet 时,将渲染完整的充值流程。

import { OnePayWidget } from '@one_deploy/sdk';

function TopUpPage() {
return (
<OnePayWidget
mode="fund_wallet"
walletAddress="0xYourUserWalletAddress"
chainId={137}
defaultAmount={50}
defaultFiatCurrency="NGN"
targetToken="USDT"
country="NG"
onSuccess={(result) => {
console.log('Top-up complete:', result.transactionId);
console.log('Delivered:', result.cryptoAmount, result.cryptoCurrency);
}}
onError={(error) => {
console.error('Top-up failed:', error.message);
}}
onClose={() => {
console.log('Widget closed');
}}
theme="light"
/>
);
}

OneFundWalletWidget 预设

自动设置 mode="fund_wallet" 的快捷方式:

import { OneFundWalletWidget } from '@one_deploy/sdk';

function FundWalletPage() {
return (
<OneFundWalletWidget
walletAddress="0xAbc..."
chainId={137}
defaultFiatCurrency="KES"
targetToken="USDC"
country="KE"
defaultAmount={1000}
onSuccess={(result) => {
console.log('Wallet funded:', result.cryptoAmount, result.cryptoCurrency);
}}
/>
);
}

OnePayWidget Props(fund_wallet 模式)

interface OnePayWidgetProps {
/** 支付模式 */
mode: 'fund_wallet' | 'direct_payment' | 'transaction';
/** 目标钱包地址 */
walletAddress: string;
/** 目标链 ID */
chainId?: number;
/** 默认充值的法币金额 */
defaultAmount?: number;
/** 默认法币币种(ISO 4217) */
defaultFiatCurrency?: string;
/** 钱包中接收的加密代币 */
targetToken?: string;
/** 用于本地提供商的 ISO 3166-1 alpha-2 国家代码 */
country?: string;
/** 限制可用的支付方式 */
allowedPaymentMethods?: string[];
/** 充值完成时调用 */
onSuccess?: (result: TopupResult) => void;
/** 发生错误时调用 */
onError?: (error: { code: string; message: string }) => void;
/** 用户关闭 widget 时调用 */
onClose?: () => void;
/** Widget 颜色主题 */
theme?: 'light' | 'dark' | 'auto';
/** 覆盖 CSS 类名 */
className?: string;
}

API 方法(全平台)

getTopupProviders

列出指定国家可用的本地支付提供商。

import { OneEngineClient } from '@one_deploy/sdk';

const engine = new OneEngineClient({
apiKey: 'YOUR_API_KEY',
projectId: 'YOUR_PROJECT_ID',
});

const providers = await engine.getTopupProviders('NG');

console.log(providers);
// [
// {
// providerId: 'prov_ng_bank',
// name: 'Bank Transfer (Nigeria)',
// type: 'bank_transfer',
// currencies: ['NGN'],
// minAmount: 1000,
// maxAmount: 5000000,
// fee: { percentage: 1.5, fixed: 50, currency: 'NGN' },
// },
// {
// providerId: 'prov_ng_momo',
// name: 'Mobile Money',
// type: 'mobile_money',
// currencies: ['NGN'],
// minAmount: 500,
// maxAmount: 1000000,
// fee: { percentage: 2.0, fixed: 0, currency: 'NGN' },
// },
// ]

getTopupQuote

获取充值报价,显示预期的加密货币数量。

const quote = await engine.getTopupQuote({
country: 'NG',
providerId: 'prov_ng_bank',
fiatCurrency: 'NGN',
fiatAmount: 50000,
targetToken: 'USDT',
chainId: 137,
});

console.log(quote);
// {
// quoteId: 'tq_abc123',
// fiatAmount: 50000,
// fiatCurrency: 'NGN',
// cryptoAmount: '31.25',
// cryptoCurrency: 'USDT',
// exchangeRate: 1600,
// fee: { fiatAmount: 800, fiatCurrency: 'NGN' },
// providerId: 'prov_ng_bank',
// expiresAt: '2026-02-02T12:10:00Z',
// }

createTopup

发起充值交易。

const topup = await engine.createTopup({
quoteId: quote.quoteId,
walletAddress: '0xAbc...',
chainId: 137,
paymentDetails: {
providerId: 'prov_ng_bank',
accountName: 'Alice Adeyemi',
},
metadata: { userId: 'user_42' },
});

console.log(topup);
// {
// transactionId: 'top_xyz789',
// status: 'pending',
// paymentInstructions: {
// type: 'bank_transfer',
// bankName: 'ONE Payments Bank',
// accountNumber: '9876543210',
// accountName: 'One Deploy Ltd',
// reference: 'TOP-xyz789',
// expiresAt: '2026-02-02T13:00:00Z',
// },
// }

getTopupStatus

检查充值状态。

const status = await engine.getTopupStatus('top_xyz789');

console.log(status);
// {
// transactionId: 'top_xyz789',
// status: 'completed',
// fiatAmount: 50000,
// fiatCurrency: 'NGN',
// cryptoAmount: '31.25',
// cryptoCurrency: 'USDT',
// txHash: '0xabc...',
// completedAt: '2026-02-02T12:35:00Z',
// }

类型

interface TopupProvider {
/** 唯一提供商标识符 */
providerId: string;
/** 人类可读的提供商名称 */
name: string;
/** 支付类型 */
type: 'bank_transfer' | 'mobile_money' | 'card' | 'ussd' | 'qr_code';
/** 支持的法币币种 */
currencies: string[];
/** 最低充值金额(法币) */
minAmount: number;
/** 最高充值金额(法币) */
maxAmount: number;
/** 手续费结构 */
fee: {
percentage: number;
fixed: number;
currency: string;
};
}

interface TopupQuoteRequest {
/** 国家代码(ISO 3166-1 alpha-2) */
country: string;
/** 使用的提供商 */
providerId: string;
/** 法币币种 */
fiatCurrency: string;
/** 支付的法币金额 */
fiatAmount: number;
/** 接收的加密代币 */
targetToken: string;
/** 目标链 */
chainId: number;
}

interface TopupQuote {
/** 报价标识符 */
quoteId: string;
/** 法币金额 */
fiatAmount: number;
/** 法币币种 */
fiatCurrency: string;
/** 预计收到的加密货币 */
cryptoAmount: string;
/** 加密代币符号 */
cryptoCurrency: string;
/** 汇率(每 1 单位加密货币对应的法币金额) */
exchangeRate: number;
/** 手续费明细 */
fee: {
fiatAmount: number;
fiatCurrency: string;
};
/** 使用的提供商 */
providerId: string;
/** ISO 8601 过期时间 */
expiresAt: string;
}

interface TopupRequest {
/** 报价 ID */
quoteId: string;
/** 目标钱包 */
walletAddress: string;
/** 目标链 */
chainId: number;
/** 支付相关详情 */
paymentDetails: {
providerId: string;
accountName?: string;
mobileNumber?: string;
[key: string]: unknown;
};
/** 任意元数据 */
metadata?: Record<string, string>;
}

interface TopupResult {
/** 唯一交易标识符 */
transactionId: string;
/** 当前状态 */
status: PaymentStatus;
/** 支付的法币金额 */
fiatAmount?: number;
/** 法币币种 */
fiatCurrency?: string;
/** 交付的加密货币数量 */
cryptoAmount?: string;
/** 加密代币符号 */
cryptoCurrency?: string;
/** 链上交易哈希(完成后) */
txHash?: string;
/** 完成支付的指引(银行转账、USSD 等) */
paymentInstructions?: PaymentInstructions;
/** ISO 8601 完成时间戳 */
completedAt?: string;
}

interface PaymentInstructions {
/** 指引类型 */
type: string;
/** 转账银行名称 */
bankName?: string;
/** 收款账号 */
accountNumber?: string;
/** 账户名 */
accountName?: string;
/** 支付参考码 */
reference?: string;
/** 拨打的 USSD 代码 */
ussdCode?: string;
/** 二维码数据 URL */
qrCodeUrl?: string;
/** 这些指引的过期时间 */
expiresAt?: string;
}

type PaymentStatus =
| 'pending'
| 'processing'
| 'completed'
| 'failed'
| 'expired'
| 'refunded';

完整示例:完整充值流程

import { OneEngineClient } from '@one_deploy/sdk';

const engine = new OneEngineClient({
apiKey: process.env.ONE_API_KEY!,
projectId: process.env.ONE_PROJECT_ID!,
});

async function fundWallet(wallet: string, amountNGN: number) {
// 1. Discover local providers
const providers = await engine.getTopupProviders('NG');
const bankProvider = providers.find((p) => p.type === 'bank_transfer');
if (!bankProvider) throw new Error('No bank transfer provider available');

console.log(`Using provider: ${bankProvider.name}`);
console.log(`Fee: ${bankProvider.fee.percentage}% + ₦${bankProvider.fee.fixed}`);

// 2. Get a quote
const quote = await engine.getTopupQuote({
country: 'NG',
providerId: bankProvider.providerId,
fiatCurrency: 'NGN',
fiatAmount: amountNGN,
targetToken: 'USDT',
chainId: 137,
});

console.log(`Pay ₦${quote.fiatAmount} -> receive ${quote.cryptoAmount} USDT`);

// 3. Initiate the top-up
const topup = await engine.createTopup({
quoteId: quote.quoteId,
walletAddress: wallet,
chainId: 137,
paymentDetails: {
providerId: bankProvider.providerId,
accountName: 'Alice Adeyemi',
},
});

// 4. Display payment instructions to user
if (topup.paymentInstructions) {
const inst = topup.paymentInstructions;
console.log('--- Payment Instructions ---');
console.log(`Bank: ${inst.bankName}`);
console.log(`Account: ${inst.accountNumber}`);
console.log(`Name: ${inst.accountName}`);
console.log(`Reference: ${inst.reference}`);
console.log(`Expires: ${inst.expiresAt}`);
}

// 5. Poll for completion
let status = await engine.getTopupStatus(topup.transactionId);
while (status.status === 'pending' || status.status === 'processing') {
await new Promise((r) => setTimeout(r, 10000));
status = await engine.getTopupStatus(topup.transactionId);
console.log(`Top-up status: ${status.status}`);
}

if (status.status === 'completed') {
console.log(`Wallet funded with ${status.cryptoAmount} USDT`);
console.log(`On-chain tx: ${status.txHash}`);
} else {
console.error(`Top-up failed: ${status.status}`);
}
}

// Fund wallet with 50,000 NGN
await fundWallet('0xAbc...', 50000);

参见