Skip to main content

Payments SDK Methods

@pepaylabs/bnbpay keeps you out of ABI weeds. Always derive paymentId / resourceId with the SDK and persist both for reconciliation.

Core exports

ExportDescription
createFlexIntent(options)Returns {intent, witness, paymentId, resourceId, schemeId, referenceId} for router calls.
sendRouterPayment(params)Push payment helper that selects the correct router method (native/token + session).
payWithPermit2 / payWithEIP2612 / payWithEIP3009Pull helpers for Permit2/EIP-2612/EIP-3009 schemes.
decodePaymentSettledEvent(log)Parses PaymentSettledV2 logs into typed objects.
buildFlexResponseBuilds HTTP 402 payloads for x402Flex.
createApiClient(options)Typed REST client for bnbpay-api (payments, invoices, sessions, relay, gift cards).
hashPaymentIntent / hashFlexWitnessDeterministic hashes for typed-data verification.
deriveResourceId / derivePaymentIdLow-level hash helpers for custom workflows.
deriveEip3009NonceDerives the intent-bound EIP-3009 nonce (authNonce).
buildSessionContext / auditSessionReceiptsSessionGuard helpers for tagging + reconciliation.
X402FlexRouter__factory / X402FlexRegistry__factoryTypeChain factories for on-chain contracts.

Permit2 pull example

import {
createFlexIntent,
getFlexSchemeId,
hashPaymentIntent,
X402FlexRouter__factory,
} from '@pepaylabs/bnbpay';
import { ethers } from 'ethers';

const intentBundle = createFlexIntent({
merchant: MERCHANT,
token: TOKEN,
amount: ethers.parseUnits('25', 6),
chainId: 56,
referenceId: 'order_402_001',
scheme: 'exact:evm:permit2',
});

const witness = {
schemeId: getFlexSchemeId('exact:evm:permit2'),
intentHash: hashPaymentIntent(intentBundle.intent),
payer: customerAddress,
salt: ethers.id('salt:customerAddress:order_402_001'),
};

const router = X402FlexRouter__factory.connect(ROUTER_ADDRESS, signer);

await router.payWithPermit2(
intentBundle.intent,
witness,
witnessSignature,
permit2Permit,
transferDetails,
permit2Signature,
intentBundle.referenceId,
);
  • createFlexIntent handles deterministic references + ID derivation.
  • Persist intentBundle.paymentId and intentBundle.resourceId for webhooks + HTTP 402 flows.
  • Persist the per-invoice nonce (inside intentBundle.intent.nonce); it is required to reproduce paymentId.
  • Use the Permit2 witness type string from /networks or PERMIT2_WITNESS_TYPESTRING export.
  • For session-guarded payments, pass sessionId into createFlexIntent or pre-tag references with formatSessionReference so referenceHash matches the router’s tagged reference.
  • EIP-3009 signatures must use ReceiveWithAuthorization with to = router.
  • EIP-3009 authNonce must be derived from intent hash + router + chainId.

EIP-3009 pull example

import {
createFlexIntent,
deriveEip3009Nonce,
hashPaymentIntent,
X402FlexRouter__factory,
} from '@pepaylabs/bnbpay';

const intentBundle = createFlexIntent({
merchant: MERCHANT,
token: TOKEN,
amount: 1_000_000n,
chainId: 56,
referenceId: 'order_402_3009',
scheme: 'exact:evm:eip3009',
});

const intentHash = hashPaymentIntent(intentBundle.intent);
const authNonce = deriveEip3009Nonce({
intentHash,
router: ROUTER_ADDRESS,
chainId: 56,
});

// sign ReceiveWithAuthorization { from, to: ROUTER_ADDRESS, value, validAfter, validBefore, nonce: authNonce }

const router = X402FlexRouter__factory.connect(ROUTER_ADDRESS, signer);
await router.payWithEIP3009(
intentBundle.intent,
intentBundle.witness,
witnessSignature,
validAfter,
validBefore,
authNonce,
v,
r,
s,
intentBundle.referenceId
);

Push / agent example

import { createFlexIntent, sendRouterPayment, RpcTransport } from '@pepaylabs/bnbpay';
import { ethers } from 'ethers';

const intent = createFlexIntent({
merchant: MERCHANT,
chainId: 56,
token: ethers.ZeroAddress,
amount: ethers.parseEther('0.75'),
referenceId: 'table-14',
scheme: 'push:evm:direct',
});

await sendRouterPayment({
transport: new RpcTransport(signer),
routerAddress: ROUTER_ADDRESS,
intent: intent.intent,
witness: intent.witness,
reference: intent.referenceId,
});

AI agents (via the MCP server) use the same helpers before forwarding receipts back to your API or UI. Keep references short (< 64 bytes) for easy reconciliation.