bankingcomponent-openbanking-consent
v0.2.11
Published
Open Banking Consent Widget for React and Next.js, powered by BankingComponent
Readme
BankingComponent: Open Banking SDK
A production-ready Open Banking Client SDK for React and Next.js applications, powered by BankingComponent.
Features
- Connect Account Flow (
<OpenBankingConnectAccount />): Discovered accounts listing with multi-select checkboxes, Select All toggle, real-time balance display, account type badges, and 4-digit Transaction PIN authorization. - Data Consent Flow (
<OpenBankingConsent />): Manage Open Banking data-sharing permissions, account access, transaction history, and consent duration. - Payment Authorization Flow (
<OpenBankingPayment />): Complete Strong Customer Authentication (SCA) with 4-digit PIN verification and interactive decline reason modals. - Granular Permissions: Enable or disable specific open banking scopes (
enableReadDataConsent,enableWriteDataConsent,enableMandateDebitConsent,enableVariableRecurringConsent,enableTransactionHistoryAccess). - Dual Modes: Use as an inline card widget or as a popup modal with backdrop overlay and dismiss handlers.
- Zero-Config Styles: Pre-compiled standalone CSS bundle (
dist/index.css) — no Tailwind setup required in consumer applications. - Default Never Expire: Consent duration defaults to
"never"for long-lived partner access. - Powered by BankingComponent: Integrated branding footer linking to https://bankingcomponent.com/.
- Dual Module Output: CommonJS (
.cjs) and ESM (.js) bundles with complete TypeScript types (.d.ts).
Installation
npm install bankingcomponent-openbanking-consent
# or
yarn add bankingcomponent-openbanking-consent
# or
pnpm add bankingcomponent-openbanking-consentQuick Start
1. Import Styles
Import the compiled CSS in your application root (e.g. layout.tsx, _app.tsx, or main.tsx):
import "bankingcomponent-openbanking-consent/dist/index.css";2. Data Consent Flow (<OpenBankingConsent />)
import { OpenBankingConsent } from "bankingcomponent-openbanking-consent";
export default function ConsentPage() {
return (
<div className="flex justify-center p-6">
{/* Automatically fetches business display name and consent parameters */}
<OpenBankingConsent
api_key="your_api_key_or_public_key"
consent_id="csnt_99821_alpha"
onError={(error) => {
console.error("Consent error:", error);
}}
onSuccess={(data) => {
console.log("Consent authorized successfully:", data);
}}
onCancel={() => {
console.log("Consent cancelled by user");
}}
isLoading={false}
/>
</div>
);
}Modal Mode
"use client";
import { useState } from "react";
import { OpenBankingConsent } from "bankingcomponent-openbanking-consent";
export default function Dashboard() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(true)}>
Connect Bank Account
</button>
<OpenBankingConsent
isModal={true}
isOpen={isOpen}
onClose={() => setIsOpen(false)}
partnerName="CarbonTech"
enableReadDataConsent={true}
enableTransactionHistoryAccess={true}
onSubmit={(e) => {
e.preventDefault();
setIsOpen(false);
}}
/>
</div>
);
}3. Payment Authorization Flow (<OpenBankingPayment />)
import { OpenBankingPayment } from "bankingcomponent-openbanking-consent";
export default function PaymentPage() {
return (
<div className="flex justify-center p-6">
{/* Automatically fetches business profile and payment details */}
<OpenBankingPayment
api_key="your_api_key_or_public_key"
initiation_reference="36936562831"
onError={(error) => {
console.error("Payment error:", error);
}}
onSuccess={(data) => {
console.log("Payment authorized successfully:", data);
}}
onCancel={() => {
console.log("Payment cancelled by user");
}}
isLoading={false}
/>
</div>
);
}Modal Mode
"use client";
import { useState } from "react";
import { OpenBankingPayment } from "bankingcomponent-openbanking-consent";
export default function Checkout() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(true)}>
Authorize Payment
</button>
<OpenBankingPayment
isModal={true}
isOpen={isOpen}
onClose={() => setIsOpen(false)}
merchantName="Bujeti Technologies"
amount="250,000.00"
currency="NGN"
narration="Vendor Payout Funding"
onAuthorize={({ pin, paymentId }) => {
console.log("Payment authorized:", paymentId);
setIsOpen(false);
}}
onDecline={({ reason, paymentId }) => {
console.log("Payment declined:", reason);
setIsOpen(false);
}}
/>
</div>
);
}4. Connect Account Flow (<OpenBankingConnectAccount />)
import { OpenBankingConnectAccount } from "bankingcomponent-openbanking-consent";
export default function LinkAccountsPage() {
return (
<div className="flex justify-center p-6">
<OpenBankingConnectAccount
api_key="your_api_key_or_public_key"
consent_id="CSN-991823741"
merchantName="Bujeti Technologies"
onError={(error) => {
console.error("Connect account error:", error);
}}
onSuccess={(data) => {
console.log("Connected accounts successfully:", data);
}}
onCancel={() => {
console.log("Connect account cancelled by user");
}}
onAuthorize={({ pin, selectedAccountIds, selectedAccounts, consentId }) => {
console.log("Connected accounts:", selectedAccountIds, "for consent:", consentId);
}}
/>
</div>
);
}Modal Mode
"use client";
import { useState } from "react";
import { OpenBankingConnectAccount } from "bankingcomponent-openbanking-consent";
export default function ConnectModal() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(true)}>
Link Bank Accounts
</button>
<OpenBankingConnectAccount
isModal={true}
isOpen={isOpen}
onClose={() => setIsOpen(false)}
merchantName="Bujeti Technologies"
onAuthorize={({ selectedAccountIds }) => {
console.log("Authorized accounts:", selectedAccountIds);
setIsOpen(false);
}}
/>
</div>
);
}Component Props
<OpenBankingConsent /> Props
| Prop | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| api_key / apiKey | string | undefined | Live API key or public key for auto-fetching consent & business info |
| consent_id / consentId | string | undefined | Unique consent reference/ID to fetch automatically |
| onError | (error: any) => void | undefined | Callback invoked when an error occurs during fetch or authorization |
| onSuccess | (data: any) => void | undefined | Callback invoked when consent is successfully authorized |
| onCancel | () => void | undefined | Callback invoked when user declines or cancels consent |
| onAuthorize | ({ otp, permissions, expiryType, expiresAt, consentReference }) => void | undefined | Callback invoked when the user submits OTP and approves consent |
| onDecline | ({ reason, consentReference }) => void | undefined | Callback invoked when consent is declined/cancelled |
| isLoading | boolean | false | Shows loading spinner / skeleton overlay state |
| status | "form" | "success" | "failed" | "form" | Current state of the consent widget flow |
| isModal | boolean | false | Renders the widget inside a centered modal backdrop overlay |
| isOpen | boolean | true | Visibility of the modal when isModal=true |
| onClose | () => void | undefined | Callback invoked on backdrop click, Escape key, or close button |
| defaultExpiryType | "never" | "date" | "never" | Default selected duration ("never" or "date") |
| partnerName | string | "Acme Accounting Ltd" | Name of the Third-Party Provider (TPP) requesting consent |
| securityBadgeText | string | "Open Banking Security" | Text displayed in the header security badge |
| enableReadDataConsent | boolean | true | Enables account details and live balance scopes |
| enableWriteDataConsent | boolean | false | Enables payment initiation write access scope |
| enableMandateDebitConsent | boolean | false | Enables direct debit mandate recurring consent |
| enableVariableRecurringConsent | boolean | false | Enables Variable Recurring Payments (VRP) scope |
| enableTransactionHistoryAccess | boolean | true | Enables transaction history records access scope |
| consentReference | string | "csnt_99821_alpha" | Consent reference ID for the authorization request |
| expiresOn | string | "Dec 31, 2026" | Formatted expiry date displayed on success screen |
| callbackUrl | string | "https://app.acme.com/callback" | Redirect URL for "Return to Application" buttons |
| errorMessage | string | "Invalid OTP provided..." | Error description displayed on failure screen |
| action | string | "/open-banking/v1/..." | Form action URL |
| method | string | "POST" | Form submission method |
| onSubmit | (e) => void | undefined | Custom submission handler |
<OpenBankingPayment /> Props
| Prop | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| api_key / apiKey | string | undefined | Live API key or public key for auto-fetching payment & business info |
| initiation_reference / initiationReference | string | undefined | Initiation reference to fetch and authorize payment automatically |
| onError | (error: any) => void | undefined | Callback invoked when an error occurs during fetch or authorization |
| onSuccess | (data: any) => void | undefined | Callback invoked when payment is successfully authorized |
| onCancel | () => void | undefined | Callback invoked when user declines or cancels authorization |
| onAuthorize | ({ pin, paymentId, initiationReference, paymentData }) => void | undefined | Callback invoked when user submits the PIN |
| onDecline | ({ reason, paymentId, initiationReference }) => void | undefined | Callback invoked when user declines with reason |
| isLoading | boolean | false | Shows loading spinner / skeleton overlay state |
| status | "form" | "success" | "failed" | "form" | Current state of the payment authorization widget |
| isModal | boolean | false | Renders the widget inside a centered modal backdrop overlay |
| isOpen | boolean | true | Visibility of the modal when isModal=true |
| onClose | () => void | undefined | Callback invoked on backdrop click, Escape key, or close button |
| merchantName | string | "Bujeti Technologies" | Name of the merchant requesting payment |
| merchantInitials | string | "BJ" | 2-letter avatar initials for the merchant |
| verifiedTppText | string | "Verified TPP" | Badge text for the merchant verification |
| amount | number | string | "250,000.00" | Formatted payment amount to debit |
| currency | string | "NGN" | Currency symbol or code |
| narration | string | "Vendor Payout Funding" | Payment purpose or description |
| debitAccountName | string | "Corporate Current Account" | Name of the payer account |
| debitAccountDetails | string | "0123456789 • GTBank" | Account number and bank name |
| beneficiaryAccount | string | "Bujeti Custody (057)" | Beneficiary recipient account details |
| paymentId | string | "pmt_99812_alpha" | Unique payment identifier |
| initiationReference | string | "" | Open Banking initiation reference identifier |
| pinLength | number | 4 | Number of security PIN digits |
| securityBadgeText | string | undefined | Optional header security badge text |
| complianceNote | string | undefined | Optional footer regulatory compliance statement |
| errorMessage | string | "Invalid PIN..." | Error description displayed on failure screen |
<OpenBankingConnectAccount /> Props
| Prop | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| api_key / apiKey | string | undefined | Live API key or public key for auto-fetching business info |
| consent_id / consentId | string | "CSN-991823741" | Open Banking consent identifier |
| onError | (error: any) => void | undefined | Callback invoked when an error occurs during linking |
| onSuccess | (data: any) => void | undefined | Callback invoked when accounts are successfully authorized |
| onCancel | () => void | undefined | Callback invoked on Cancel button click |
| onAuthorize | ({ pin, selectedAccountIds, selectedAccounts, consentId, businessData }) => void | undefined | Callback invoked when user authorizes accounts linking |
| onDecline | ({ reason, consentId }) => void | undefined | Callback invoked when user declines |
| status | "form" | "success" | "failed" | "form" | Current state of the account connection widget |
| isModal | boolean | false | Renders the widget inside a centered modal backdrop overlay |
| isOpen | boolean | true | Visibility of the modal when isModal=true |
| onClose | () => void | undefined | Callback invoked on close button click |
| merchantName | string | "Bujeti Technologies" | Name of the merchant or partner connecting accounts |
| accounts | DiscoveredAccount[] | DEFAULT_ACCOUNTS | Array of discovered bank accounts to display |
| pinLength | number | 4 | Number of Transaction PIN digits |
| errorMessage | string | "Unable to authorize..." | Error description displayed on failure screen |
Open Banking API Client & Dev Environment Routes
The SDK includes a typed API client mapped to the dev environment:
- Base URL:
https://dev-api.bankingcomponent.com/openbanking
1. Endpoints Mapped
| Method | Endpoint | Description |
| :--- | :--- | :--- |
| GET | /v1/consent.getConsent?consent_id={id}&consent_reference={ref} | Fetches consent details, required/optional permissions, and duration |
| POST | /v1/consent.authorization | Authorizes (APPROVE) or declines (DECLINE) consent with OTP |
| GET | /v1/business.getBusiness | Fetches registered business profile, branding, and merchant display info |
| POST | /v1/payment.initiate | Initiates a payment with reference, amount, and destination bank account |
| POST | /v1/payment.authorization | Authorizes (APPROVE) or declines (DECLINE) using token and initiation_reference |
| GET | /v1/payment.getPayment?initiation_reference={ref}&payment_id={id} | Fetches payment details, status, amounts, and dates by payment ID or initiation reference |
2. Using createOpenBankingClient
import { createOpenBankingClient } from "bankingcomponent-openbanking-consent";
const client = createOpenBankingClient({
baseUrl: "https://dev-api.bankingcomponent.com/openbanking",
});
// 1. Get consent details from endpoint
const consent = await client.getConsent("csnt_99821_alpha");
console.log(consent.data.permissions); // [{ id: "ReadAccountsDetail", required: true }, ...]
// 2. Get payment details
const payment = await client.getPayment("36936562831");
console.log(payment.data.status); // "APPROVED" | "PENDING"
// 2. Authorize payment with PIN token
await client.authorizePayment({
action: "APPROVE",
token: "1234",
initiation_reference: "36936562831",
});
// 3. Initiate payment
await client.initiatePayment({
initiation_reference: "36936562831",
type: "IMMEDIATE",
amount: 5000000,
narration: "Vendor Payment - Inv 402",
account_id: "ACC-11111",
destination: {
bank_code: "033",
account_name: "Test Name",
account_number: "9988776655",
},
});3. Using useOpenBankingPayment Hook
import { useOpenBankingPayment, OpenBankingPayment } from "bankingcomponent-openbanking-consent";
export default function Checkout() {
const {
paymentData,
status,
authorize,
decline,
} = useOpenBankingPayment({
baseUrl: "https://dev-api.bankingcomponent.com/openbanking",
initialInitiationReference: "36936562831",
});
return (
<OpenBankingPayment
status={status}
amount={paymentData?.amount ?? "5,000,000.00"}
currency={paymentData?.currency ?? "NGN"}
narration={paymentData?.narration ?? "Vendor Payment - Inv 402"}
initiationReference="36936562831"
onAuthorize={({ pin, initiationReference }) => {
authorize(pin, initiationReference);
}}
onDecline={({ reason, initiationReference }) => {
decline(reason, initiationReference);
}}
/>
);
}4. Using useOpenBankingConsent Hook
import { useOpenBankingConsent, OpenBankingConsent } from "bankingcomponent-openbanking-consent";
export default function ConsentView() {
const {
consentData,
status,
authorize,
decline,
} = useOpenBankingConsent({
baseUrl: "https://dev-api.bankingcomponent.com/openbanking",
initialConsentReference: "csnt_99821_alpha",
});
return (
<OpenBankingConsent
status={status}
consentData={consentData}
onAuthorize={({ otp, permissions, expiryType, expiresAt }) => {
authorize({ otp, permissions, expiryType, expiresAt });
}}
onDecline={({ reason }) => {
decline(reason);
}}
/>
);
}5. Using useOpenBankingConnectAccount Hook
import { useOpenBankingConnectAccount, OpenBankingConnectAccount } from "bankingcomponent-openbanking-consent";
export default function ConnectAccountsView() {
const {
consentId,
status,
authorize,
} = useOpenBankingConnectAccount({
baseUrl: "https://dev-api.bankingcomponent.com/openbanking",
initialConsentId: "CSN-991823741",
});
return (
<OpenBankingConnectAccount
status={status}
consent_id={consentId}
merchantName="Bujeti Technologies"
onAuthorize={({ pin, selectedAccountIds }) => {
authorize({ pin, selectedAccountIds });
}}
/>
);
}Development & Building
Run the Demo Playground
npm run devBuild Package for Distribution
npm run build:packageThis compiles TypeScript to ESM and CJS bundles in dist/ with .d.ts type declarations and builds dist/index.css.
License
MIT © BankingComponent
