Skip to main content

Invoices

Invoices are off-chain records that map to on-chain payments via paymentId + resourceId.

Create an invoice

import { createApiClient } from '@pepaylabs/bnbpay';

const api = createApiClient();
const invoice = await api.invoices.create({
title: 'Order #138',
merchantId: 'store-123',
merchantName: 'Runey',
amount: '25.00',
currencyToken: 'USDT',
network: 'bnb',
tokenAllowlist: ['0x55d398326f99059fF775485246999027B3197955'],
reference: 'order-138',
});

Build a payment intent

Use payments.buildIntent to get canonical intent + signing metadata:

const intentPayload = await api.payments.buildIntent({
mode: 'minimal',
network: 'bnb',
merchant: '0xMerchant',
token: '0x55d398326f99059fF775485246999027B3197955',
amount: '25.00',
scheme: 'permit2',
invoiceId: invoice.invoiceId,
payer: payerAddress,
});
  • intentPayload.derived contains intent, resourceId, paymentId, and intentHash.
  • intentPayload.signing includes the router domain + Permit2 witness type string.
  • Persist intentPayload.derived.intent.nonce with your invoice metadata; it is part of the paymentId binding.

Confirm invoice status

const status = await api.invoices.status(invoice.invoiceId);
if (status.status === 'paid') {
console.log('settled', status.paymentId);
}

Streams (SSE / WebSocket)

Use invoice streams to get real-time updates when payments settle.

const sseUrl = api.invoices.streamSseUrl(invoice.invoiceId);
const events = new EventSource(sseUrl);
  • SSE: GET /invoices/:invoiceId/stream-sse
  • WS: GET /invoices/:invoiceId/stream

Cancellation + fallback confirmation

await api.invoices.cancel(invoice.invoiceId);
await api.invoices.confirmPayment(invoice.invoiceId, {
txHash,
paidBy: payerAddress,
paidAmount: '25.00',
paidToken: '0x55d398326f99059fF775485246999027B3197955',
});

confirmPayment is a fallback if indexer-based matching does not fire automatically.