跳至主要内容

账单支付

即将推出

账单支付目前仅通过 OneEngineClient纯 API 方式提供。专用 widget 和 React hook 正在开发中,将在未来版本中发布。该 API 已稳定并可用于生产环境。

账单支付 API 允许用户直接从加密钱包缴纳水电费、购买话费、支付订阅服务以及处理其他定期支付。ONE SDK(@one_deploy/sdk v1.1.0)处理提供商发现、账户验证、支付执行和历史追踪。

账单支付流程

  1. Discover          2. Select           3. Validate          4. Pay
providers --> provider & --> account --> and confirm
by country / enter account number
category number

API 方法

getBillProviders

按国家和/或类别发现账单支付提供商。

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

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

// All providers in Nigeria
const providers: BillProvider[] = await engine.getBillProviders('NG');

// Filter by category
const electricityProviders = await engine.getBillProviders('NG', 'electricity');
const airtimeProviders = await engine.getBillProviders('NG', 'airtime');

console.log(electricityProviders);
// [
// {
// providerId: 'bp_ng_ekedc',
// name: 'Eko Electricity (EKEDC)',
// country: 'NG',
// category: 'electricity',
// currency: 'NGN',
// minAmount: 1000,
// maxAmount: 500000,
// requiredFields: ['meterNumber', 'meterType'],
// logo: 'https://assets.one23.io/bills/ekedc.png',
// },
// {
// providerId: 'bp_ng_ikedc',
// name: 'Ikeja Electric (IKEDC)',
// country: 'NG',
// category: 'electricity',
// currency: 'NGN',
// minAmount: 1000,
// maxAmount: 500000,
// requiredFields: ['meterNumber', 'meterType'],
// logo: 'https://assets.one23.io/bills/ikedc.png',
// },
// ]
// Get all available categories (omit both parameters)
const allProviders = await engine.getBillProviders();
const categories = [...new Set(allProviders.map((p) => p.category))];
console.log(categories);
// ['electricity', 'airtime', 'data', 'water', 'cable_tv', 'internet', 'education']

validateBillAccount

在提交支付前验证提供商的账户号码。返回账户持有人姓名供用户确认。

const validation = await engine.validateBillAccount(
'bp_ng_ekedc', // providerId
'45678901234' // accountNumber (meter number)
);

console.log(validation);
// {
// valid: true,
// accountName: 'ALICE ADEYEMI',
// accountNumber: '45678901234',
// providerId: 'bp_ng_ekedc',
// metadata: {
// meterType: 'prepaid',
// address: '12 Example Street, Lagos',
// },
// }
// Handle invalid accounts
const invalid = await engine.validateBillAccount('bp_ng_ekedc', '00000000000');

if (!invalid.valid) {
console.error('Invalid account number');
}

payBill

执行账单支付。从用户钱包扣除加密货币并向提供商结算账单。

const payment: BillPayment = await engine.payBill({
providerId: 'bp_ng_ekedc',
accountNumber: '45678901234',
amount: 10000,
currency: 'NGN',
walletAddress: '0xAbc...',
chainId: 137,
payWithToken: 'USDT',
fields: {
meterNumber: '45678901234',
meterType: 'prepaid',
},
metadata: { userId: 'user_42' },
});

console.log(payment);
// {
// paymentId: 'bill_xyz789',
// status: 'completed',
// providerId: 'bp_ng_ekedc',
// providerName: 'Eko Electricity (EKEDC)',
// accountNumber: '45678901234',
// amount: 10000,
// currency: 'NGN',
// cryptoAmount: '6.25',
// cryptoCurrency: 'USDT',
// txHash: '0xdef...',
// receipt: {
// token: 'ELEC-8765-4321-0987',
// units: '45.2 kWh',
// },
// createdAt: '2026-02-02T12:00:00Z',
// }

getBillHistory

检索历史账单支付记录,支持可选的过滤和分页。

// Recent 20 payments
const history = await engine.getBillHistory();

// With filters
const filtered = await engine.getBillHistory({
walletAddress: '0xAbc...',
category: 'electricity',
status: 'completed',
limit: 50,
offset: 0,
fromDate: '2026-01-01T00:00:00Z',
toDate: '2026-02-02T23:59:59Z',
});

console.log(filtered);
// {
// payments: [ { paymentId: 'bill_xyz789', ... }, ... ],
// total: 12,
// limit: 50,
// offset: 0,
// }

类型

interface BillProvider {
/** 唯一提供商标识符 */
providerId: string;
/** 人类可读的提供商名称 */
name: string;
/** ISO 3166-1 alpha-2 国家代码 */
country: string;
/** 账单类别 */
category: BillCategory;
/** 提供商接受的币种 */
currency: string;
/** 最低支付金额 */
minAmount: number;
/** 最高支付金额 */
maxAmount: number;
/** 此提供商所需的字段(除 accountNumber 外) */
requiredFields: string[];
/** 提供商 logo URL */
logo?: string;
}

type BillCategory =
| 'electricity'
| 'airtime'
| 'data'
| 'water'
| 'cable_tv'
| 'internet'
| 'education'
| 'insurance'
| 'government'
| 'other';

interface BillValidation {
/** 账户号码是否有效 */
valid: boolean;
/** 账户持有人姓名(供用户确认) */
accountName?: string;
/** 回显的账户号码 */
accountNumber: string;
/** 提供商 ID */
providerId: string;
/** 来自提供商的附加元数据 */
metadata?: Record<string, string>;
/** 无效时的错误消息 */
error?: string;
}

interface BillPaymentParams {
/** 支付的提供商 */
providerId: string;
/** 账户 / 电表 / 用户号码 */
accountNumber: string;
/** 提供商法币币种金额 */
amount: number;
/** 法币币种代码 */
currency: string;
/** 扣款的钱包地址 */
walletAddress: string;
/** 钱包的链 ID */
chainId: number;
/** 支付使用的代币(从钱包扣除并兑换) */
payWithToken: string;
/** 提供商特定字段(meterType、packageCode 等) */
fields?: Record<string, string>;
/** 任意元数据 */
metadata?: Record<string, string>;
}

interface BillPayment {
/** 唯一支付标识符 */
paymentId: string;
/** 支付状态 */
status: PaymentStatus;
/** 提供商 ID */
providerId: string;
/** 提供商显示名称 */
providerName: string;
/** 账单类别 */
category: BillCategory;
/** 已付的账户号码 */
accountNumber: string;
/** 支付的法币金额 */
amount: number;
/** 法币币种 */
currency: string;
/** 从钱包扣除的加密货币金额 */
cryptoAmount: string;
/** 使用的加密代币 */
cryptoCurrency: string;
/** 链上交易哈希 */
txHash?: string;
/** 提供商收据(凭证码、单位数等) */
receipt?: Record<string, string>;
/** ISO 8601 创建时间戳 */
createdAt: string;
}

interface BillHistoryOptions {
/** 按钱包地址过滤 */
walletAddress?: string;
/** 按账单类别过滤 */
category?: BillCategory;
/** 按支付状态过滤 */
status?: PaymentStatus;
/** 最大返回结果数 */
limit?: number;
/** 分页偏移量 */
offset?: number;
/** 起始日期(ISO 8601) */
fromDate?: string;
/** 结束日期(ISO 8601) */
toDate?: string;
}

interface BillHistoryResult {
/** 账单支付列表 */
payments: BillPayment[];
/** 匹配的支付总数 */
total: number;
/** 当前 limit */
limit: number;
/** 当前 offset */
offset: number;
}

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 payElectricityBill(
wallet: string,
meterNumber: string,
amountNGN: number
) {
// 1. Find electricity providers in Nigeria
const providers = await engine.getBillProviders('NG', 'electricity');
console.log(`Found ${providers.length} electricity providers`);

// Use the first provider
const provider = providers[0];
console.log(`Using: ${provider.name}`);

// 2. Validate the meter number
const validation = await engine.validateBillAccount(
provider.providerId,
meterNumber
);

if (!validation.valid) {
throw new Error(`Invalid meter number: ${validation.error}`);
}

console.log(`Account holder: ${validation.accountName}`);
console.log(`Meter type: ${validation.metadata?.meterType}`);

// 3. Pay the bill
const payment = await engine.payBill({
providerId: provider.providerId,
accountNumber: meterNumber,
amount: amountNGN,
currency: 'NGN',
walletAddress: wallet,
chainId: 137,
payWithToken: 'USDT',
fields: {
meterNumber,
meterType: validation.metadata?.meterType ?? 'prepaid',
},
});

if (payment.status === 'completed') {
console.log('Payment successful!');
console.log(`Debited: ${payment.cryptoAmount} USDT`);
console.log(`Token: ${payment.receipt?.token}`);
console.log(`Units: ${payment.receipt?.units}`);
} else {
console.log(`Payment status: ${payment.status}`);
}

return payment;
}

// Pay 10,000 NGN electricity bill
await payElectricityBill('0xAbc...', '45678901234', 10000);

完整示例:购买话费

async function buyAirtime(
wallet: string,
phoneNumber: string,
amountNGN: number
) {
// 1. Find airtime providers
const providers = await engine.getBillProviders('NG', 'airtime');
const mtn = providers.find((p) => p.name.includes('MTN'));
if (!mtn) throw new Error('MTN provider not found');

// 2. Validate (for airtime, this checks the phone number)
const validation = await engine.validateBillAccount(
mtn.providerId,
phoneNumber
);

if (!validation.valid) {
throw new Error(`Invalid phone number: ${validation.error}`);
}

// 3. Pay
const payment = await engine.payBill({
providerId: mtn.providerId,
accountNumber: phoneNumber,
amount: amountNGN,
currency: 'NGN',
walletAddress: wallet,
chainId: 137,
payWithToken: 'USDT',
});

console.log(`Airtime top-up: ${payment.status}`);
console.log(`Debited: ${payment.cryptoAmount} USDT`);
return payment;
}

参见