Framework-neutral payment integration surface for many payment channels.
License · Docs · Contributing · Security · Support
payba3 is an open-source collection of payment-channel integrations built for developers, teams, codebases, automations, and AI agents that need a simple way to plug into different payment providers from server-side TypeScript or JavaScript.
Configure the provider you want, select it through payba3, and call the channel.
const paystack = payba3.use('paystack');
await paystack.initializeOneTimeCheckout({
email: 'customer@example.com',
amountInKobo: 500000,
currency: 'NGN',
});payba3 is growing. More providers, methods, adapters, and examples will be added over time.
Detailed Mintlify documentation lives in docs/ with the site map in docs.json.
The repository supports both Mintlify project-directory layouts:
- repository root:
docs.json - docs subdirectory:
docs/docs.json
Preview locally:
bun run docs:devPreview the /docs project-directory setup:
bun run docs:dev:docsUse a Mintlify-supported LTS Node runtime for docs commands. Node 26 is not supported by the Mintlify CLI at the moment.
The docs cover installation, configuration, provider-specific usage, examples for common frameworks, agent and IDE integration, security, migration, and a separate API Reference tab.
Modern products rarely stay tied to one payment provider forever. A team may start with one checkout provider, add virtual accounts later, route a payout through another provider, run identity checks with a verification API, and still need a clean way for application code, scripts, background jobs, and AI agents to call those channels without learning every provider from scratch.
payba3 is a developer-friendly payment integration layer for that reality. It gives each provider a named channel, keeps provider credentials in configuration, and exposes direct methods for common actions such as checkout, virtual accounts, transfers, subaccounts, account linking, and identity checks.
Use payba3 when you want:
- One dependency for multiple payment and verification providers.
- A simple provider selector:
payba3.use('provider'). - Provider-specific methods without rewriting authentication and token-refresh logic.
- A project that can be used by normal application code, workflow automations, scripts, and AI agents.
- A growing open-source base where more providers can be added over time.
| Channel | Common use cases | Provider signup | Provider docs |
|---|---|---|---|
| Paystack | Checkout, subscriptions, transfers, dedicated accounts | Create account | Docs |
| Safehaven | Virtual accounts, subaccounts, banking APIs | Sandbox | Docs |
| SeerBit | Collections, virtual accounts, online payments | Create account | Docs |
| OPay | Checkout, signed payment APIs, refunds | Merchant dashboard | Docs |
| Mono | Open banking, account linking, DirectPay, lookup | Create account | Docs |
| Monnify | Checkout, reserved accounts, transfers, wallets | Create account | Docs |
| QoreID | KYC, CAC lookup, identity verification | Create account | Docs |
npm install @grtsnx/payba3yarn add @grtsnx/payba3pnpm add @grtsnx/payba3bun add @grtsnx/payba3payba3 ships compiled JavaScript, TypeScript declarations, and an npm exports map. It is tested with npm and Bun install smoke checks in CI. Yarn and pnpm can consume the same npm package metadata.
payba3 2.x is framework-neutral. It does not require Nest, Express, Fastify, Next.js, or any other framework package to import or use the provider clients.
Use it in server-side JavaScript or TypeScript with a runtime that provides fetch, URLSearchParams, and Node-compatible crypto APIs. Node.js 18+ and Bun are covered by package smoke tests.
If you are using the repository directly:
bun installCreate a payba3 client, configure the providers you want, then select a channel.
import { createPayba3 } from '@grtsnx/payba3';
const payba3 = createPayba3({
paystack: {
secretKey: process.env.PAYSTACK_SECRET_KEY,
},
safehaven: {
environment: 'sandbox',
clientId: process.env.SAFEHAVEN_CLIENT_ID,
clientAssertion: process.env.SAFEHAVEN_CLIENT_ASSERTION,
},
});
const checkout = await payba3.use('paystack').initializeOneTimeCheckout({
email: 'customer@example.com',
amountInKobo: 250000,
currency: 'NGN',
reference: 'order_123',
});
const subAccount = await payba3.use('safehaven').createSubAccount({
phoneNumber: '08000000000',
identityType: 'vID',
identityId: 'identity-id',
emailAddress: 'customer@example.com',
externalReference: 'customer_123',
});You can also use a channel directly when you want provider-specific methods:
const monnify = payba3.use('monnify');
await monnify.createReservedAccount({
accountReference: 'customer_123',
accountName: 'Jane Doe',
customerName: 'Jane Doe',
customerEmail: 'jane@example.com',
bvn: '00000000000',
});Only configure the providers you use. Missing credentials for unused providers should not block your application from starting.
You can configure providers through createPayba3() options, environment variables, or a mix of both. Explicit constructor options win over environment variables.
const payba3 = createPayba3({
monnify: {
environment: 'live',
apiKey: process.env.MONNIFY_LIVE_API_KEY,
secretKey: process.env.MONNIFY_LIVE_SECRET_KEY,
contractCode: process.env.MONNIFY_LIVE_CONTRACT_CODE,
},
qoreid: {
clientId: process.env.QOREID_CLIENT,
secret: process.env.QOREID_SECRET,
},
});PAYSTACK_ENVIRONMENT=sandbox
PAYSTACK_SECRET_KEY=
PAYSTACK_SECRET_KEY_LIVE=SAFEHAVEN_ENVIRONMENT=sandbox
SAFEHAVEN_CLIENT_ID=
SAFEHAVEN_CLIENT_ASSERTION=
SAFEHAVEN_LIVE_CLIENT_ID=
SAFEHAVEN_LIVE_CLIENT_ASSERTION=
SAFEHAVEN_TIMEOUT_MS=10000Switch to production:
SAFEHAVEN_ENVIRONMENT=liveSEERBIT_ENVIRONMENT=sandbox
SEERBIT_BASE_URL=
SEERBIT_PUBLIC_KEY=
SEERBIT_SECRET_KEY=
SEERBIT_LIVE_PUBLIC_KEY=
SEERBIT_LIVE_SECRET_KEY=OPAY_ENVIRONMENT=sandbox
OPAY_MERCHANT_ID=
OPAY_PUBLIC_KEY=
OPAY_SECRET_KEY=
OPAY_LIVE_MERCHANT_ID=
OPAY_LIVE_PUBLIC_KEY=
OPAY_LIVE_SECRET_KEY=MONO_ENVIRONMENT=sandbox
MONO_SECRET_KEY=
MONO_LIVE_SECRET_KEY=MONNIFY_ENVIRONMENT=sandbox
MONNIFY_API_KEY=
MONNIFY_SECRET_KEY=
MONNIFY_CONTRACT_CODE=
MONNIFY_LIVE_API_KEY=
MONNIFY_LIVE_SECRET_KEY=
MONNIFY_LIVE_CONTRACT_CODE=QOREID_ENVIRONMENT=sandbox
QOREID_BASE_URL=
QOREID_CLIENT=
QOREID_SECRET=
QOREID_LIVE_CLIENT=
QOREID_LIVE_SECRET=payba3.use('paystack');
payba3.use('safehaven');
payba3.use('seerbit');
payba3.use('opay');
payba3.use('mono');
payba3.use('monnify');
payba3.use('qoreid');Unsupported providers throw a clear error.
payba3.use('unknown'); // throws Unsupported payment channelpayba3 refreshes expiring provider tokens before they become stale.
- Safehaven uses
expires_infrom the token response. - Safehaven stores
ibs_client_idfrom the token response for account-callClientIDheaders. - QoreID accepts
expiresInorexpires_infrom the token response. - Monnify derives expiry from the JWT
expclaim when available.
payba3 is intended to be easy for agents, IDE assistants, code generators, and automation workflows to reason about:
- Provider names are explicit.
- Configuration is environment based.
- Request signing and token refresh are handled by payba3.
- Provider-specific actions remain discoverable through named channels.
The npm package includes an LLM index, a full LLM context file, an agent guide, a machine-readable manifest, a suggested MCP-style tool schema, and provider-specific references. Agents and IDEs can read these files from an installed package instead of scraping source code.
import { readFileSync } from 'node:fs';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const indexPath = require.resolve('@grtsnx/payba3/llms.txt');
const fullContextPath = require.resolve('@grtsnx/payba3/llms-full.txt');
const agentGuidePath = require.resolve('@grtsnx/payba3/agents.md');
const manifestPath = require.resolve('@grtsnx/payba3/agents.json');
const paystackPath = require.resolve('@grtsnx/payba3/llms/paystack.txt');
const payba3Guide = readFileSync(indexPath, 'utf8');
const fullContext = readFileSync(fullContextPath, 'utf8');
const agentGuide = readFileSync(agentGuidePath, 'utf8');
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
const paystackGuide = readFileSync(paystackPath, 'utf8');Available agent and provider docs:
@grtsnx/payba3/llms.txt
@grtsnx/payba3/llms-full.txt
@grtsnx/payba3/agents.md
@grtsnx/payba3/agents.json
@grtsnx/payba3/agents/ide-prompt.md
@grtsnx/payba3/agents/mcp-tools.json
@grtsnx/payba3/llms/paystack.txt
@grtsnx/payba3/llms/safehaven.txt
@grtsnx/payba3/llms/seerbit.txt
@grtsnx/payba3/llms/opay.txt
@grtsnx/payba3/llms/mono.txt
@grtsnx/payba3/llms/monnify.txt
@grtsnx/payba3/llms/qoreid.txt
For IDEs, coding agents, and internal app generators:
- Install
@grtsnx/payba3. - Read
@grtsnx/payba3/llms.txt. - Read
@grtsnx/payba3/agents.md. - Read
@grtsnx/payba3/agents.jsonwhen a machine-readable manifest is useful. - Read the provider file for the requested channel.
- Generate server-side code that imports from
@grtsnx/payba3. - Ask the developer for only the provider environment variables they need.
- Keep secrets on the server and verify provider callbacks before delivering value.
Example prompt for an IDE agent:
Use @grtsnx/payba3 to add Paystack checkout.
Read @grtsnx/payba3/llms.txt, @grtsnx/payba3/agents.md, and @grtsnx/payba3/llms/paystack.txt first.
Only add server-side code.
Use PAYSTACK_SECRET_KEY from the environment.
Verify transactions server-side before marking an order paid.
For MCP servers or similar tool runtimes, use @grtsnx/payba3/agents/mcp-tools.json as a starting contract. It describes safe, narrow tool shapes and marks actions that should generally require human approval, such as account creation and money-moving flows.
For AI tool servers, expose small provider actions instead of exposing raw secrets:
import { createPayba3, type Payba3ChannelName } from '@grtsnx/payba3';
type PaymentToolInput = {
channel: Payba3ChannelName;
action: 'initializeCheckout' | 'verifyTransaction';
payload: Record<string, unknown>;
};
const payba3 = createPayba3({
paystack: {
secretKey: process.env.PAYSTACK_SECRET_KEY,
},
});
export class PaymentTool {
async run(input: PaymentToolInput) {
const provider = payba3.use(input.channel);
if (input.channel === 'paystack' && input.action === 'initializeCheckout') {
return provider.initializeOneTimeCheckout({
email: String(input.payload.email),
amountInKobo: Number(input.payload.amountInKobo),
reference: String(input.payload.reference),
});
}
throw new Error('Unsupported payment tool action');
}
}bun install --frozen-lockfile
bun run lint
bun run test
bun run test:providers
bun run test:e2e
bun run build
bun run pack:dry
bun run test:package
bun run test:package:bun
bun auditpayba3 welcomes provider additions, method coverage, docs, tests, examples, and security hardening.
Read CONTRIBUTING.md before opening a pull request.
Do not open public issues for vulnerabilities. Read SECURITY.md for supported reporting channels and safe disclosure guidance.
MIT. See LICENSE.