UNPKG

ng-bank-account-validator

Version:
268 lines (267 loc) 10.3 kB
import { AccountValidationResponse, Bank, BankProperty, CardBinResponse, CardBrand, CardType, PaymentProvider } from "./types"; /** * Nigerian NUBAN Account Validator * @class Nuban * @description Validates Nigerian bank account numbers using * NUBAN algorithm and bank APIs */ declare class Nuban { private readonly apiKey; private readonly paymentProvider; static banks: Bank[]; static weightedBanks: Bank[]; /** * Creates an instance of NUBAN validator * @param apiKey - The API key for the payment provider (Paystack or Flutterwave) * @param paymentProvider - The payment provider to use (PAYSTACK or FLUTTERWAVE) * @throws Will throw an error if apiKey is empty or payment provider is invalid * * @example * ```typescript * // Initialize with Paystack * const nuban = new Nuban('sk_test_...', PaymentProvider.PAYSTACK); * * // Initialize with Flutterwave * const nuban = new Nuban('FLWSECK_TEST-...', PaymentProvider.FLUTTERWAVE); * ``` */ constructor(apiKey: string, paymentProvider: PaymentProvider); /** * Validates a Nigerian NUBAN account number * @param accountNumber - The account number to validate (10 digits) * @param bankCode - The bank code (e.g., "000015" for Zenith Bank) * @returns Promise<AccountValidationResponse> * * @example * ```typescript * const nuban = new Nuban('your-api-key', 'PAYSTACK'); * * // Validate account using Paystack * const result = await nuban.validateAccount('0123456789', '057'); * // { status: true, message: 'Account found', data: { account_name: 'John Doe', ... } } * * // Invalid account number * const invalid = await nuban.validateAccount('12345', '057'); * // { status: false, message: 'Invalid account number, digits should be exactly 10' } * ``` */ validateAccount(accountNumber: string, bankCode: string): Promise<AccountValidationResponse>; /** * Resolves card BIN (Bank Identification Number) information * @param firstSixDigits - First 6 digits of the card number * @returns Promise<CardBinResponse> Card BIN information including brand, type, and issuing bank * * @throws Will throw an error if the card BIN resolution fails * * @example * ```typescript * const nuban = new Nuban('your-api-key', PaymentProvider.PAYSTACK); * * // Resolve card BIN * const cardInfo = await nuban.resolveCardBin('123456'); * // { * // status: true, * // message: 'Card BIN resolved', * // data: { * // bin: '123456', * // brand: 'VISA', * // card_type: 'DEBIT', * // bank: 'Access Bank' * // } * // } * ``` */ resolveCardBin(firstSixDigits: string): Promise<CardBinResponse>; /** * Gets all possible Nigerian banks that could have issued a NUBAN account number * based on CBN's NUBAN algorithm standard * @see {@link https://www.cbn.gov.ng/out/2020/psmd/revised%20standards%20on%20nigeria%20uniform%20bank%20account%20number%20(nuban)%20for%20banks%20and%20other%20financial%20institutions%20.pdf CBN NUBAN Standard} * * @param accountNumber - The 10-digit NUBAN account number to validate * @param banks - Optional array of banks to check against (defaults to all Nigerian banks) * @returns Array of banks that could have issued the account number * * @example * ```typescript * // Get all possible banks for an account number * const possibleBanks = Nuban.getPossibleNubanBanks('0123456789'); * // [{ name: 'Access Bank', code: '000014' }, { name: 'Zenith Bank', code: '000015' }] * ``` * * Because of the irregularities in the NUBAN structure, a * request to check a bank account can result in alot of banks * returned, as I have 558 banks registered. So to streamline * this for your use case you can pass custom banks to check. * * To this end I provided a default weightedBanks list that * contains the most popular banks in the country that can be * used to streammline your response to those banks. * You can also pass custom banks. * * The optional weight param in the banks type is for you to * filter the results by relevance to your specific need. * @example * ```typescript * // Check against the default weighted banks * const specificBanks = Nuban.getPossibleNubanBanks('0123456789', Nuban.weightedBanks); * * // Check against custom banks * const specificBanks = Nuban.getPossibleNubanBanks('0123456789', [ * { id: '1', slug: '000014', name: 'Access Bank', code: '000014', weight: 1 } * ]); * ``` */ static getPossibleNubanBanks(accountNumber: string, banks?: Bank[]): Bank[]; /** * Get bank from slug, code or oldCode. * @param value - The value to find (e.g., '000013') * @param property - The bank property (e.g., BankProperty.CODE) * @returns Bank * * @example * ```typescript * const bank = getBank('000013', BankProperty.CODE); * // { * // id: 11; * // slug: 'bank_slug' * // name: 'bank_name', * // code: '000013' * // } * ``` */ static getBank(value: string, property: BankProperty): Bank | undefined; /** * Makes an API request to Paystack to validate account details * @param accountNumber - The account number to validate * @param bankCode - The bank code to validate against * @returns Promise<AccountValidationResponse> * @throws Will throw an error if the API request fails * @private */ private paystackQuery; /** * Makes an API request to Flutterwave to validate account details * @param accountNumber - The account number to validate * @param bankCode - The bank code to validate against * @throws Will throw an error if the API request fails * @private */ private flutterwaveQuery; /** * Validates NUBAN format * @param accountNumber - The account number to validate * @returns boolean */ private validateNuban; /** * Validates bank code format based on payment provider * @param bankCode - The bank code to validate * @returns boolean indicating if the bank code format is valid * @private * * @example * ```typescript * // Paystack (exactly 3 digits) * // Requires the old bank code * validateBankCode('057', PaymentProvider.PAYSTACK); // true * validateBankCode('000015', PaymentProvider.PAYSTACK); // false * * // Flutterwave (accepts 3 or 6 digits) * // Accepts both the old and new bank codes. * validateBankCode('057', PaymentProvider.FLUTTERWAVE); // true * validateBankCode('000015', PaymentProvider.FLUTTERWAVE); // true * ``` */ private validateBankCode; /** * Formats Flutterwave's card BIN response to match the standard CardBinResponse interface * @param response - Raw response from Flutterwave's card BIN API * @returns CardBinResponse Formatted card BIN information * * @example * ```typescript * // Raw Flutterwave response * const rawResponse = { * status: true, * message: "success", * data: { * issuing_country: "NIGERIA NG", * bin: "123456", * card_type: "DEBIT", * issuer_info: "VISA Access Bank" * } * }; * * const formatted = this.formatFlutterwaveCardBinResponse(rawResponse); * // { * // status: true, * // message: "success", * // data: { * // bin: "123456", * // country_code: "NG", * // country_name: "NIGERIA", * // card_type: "DEBIT", * // brand: "VISA", * // bank: "Access Bank" * // } * // } * ``` */ private formatFlutterwaveCardBinResponse; /** * Validates and type checks the API response * @param response - Raw API response * @returns AccountValidationResponse * @throws Will throw an error if the response format is invalid * @private */ private validateApiResponse; /** * Generates a seed array for NUBAN validation based on CBN's algorithm * @param length - Length of the seed array to generate * @returns Array of alternating numbers (3,7) based on the specified length * @private * * @example * [3, 7, 3, 3, 7, 3, 3, 7, 3] */ private static generateSeed; /** * Validates the NUBAN serial code format * @param nubanSerialCode - 9-digit NUBAN serial code * @throws {Error} If serial code is invalid or exceeds maximum length * @returns true if the serial code is valid * @private */ private static validateNubanSerialCode; /** * Generates the check digit for a NUBAN account number using CBN's algorithm * @see {@link https://www.cbn.gov.ng/out/2020/psmd/revised%20standards%20on%20nigeria%20uniform%20bank%20account%20number%20(nuban)%20for%20banks%20and%20other%20financial%20institutions%20.pdf CBN NUBAN Standard} * @param nubanSerialCode - First 9 digits of the account number * @param bankCode - 6-digit bank code * @returns The check digit (last digit) of the NUBAN * @private * * @example * ```typescript * const checkDigit = Nuban.generateCheckDigit('123456789', '000014'); * // Returns a number between 0-9 * ``` */ private static generateCheckDigit; /** * Checks if a bank could have issued a specific NUBAN account number * @param accountNumber - Complete 10-digit NUBAN account number * @param bankCode - 6-digit bank code to validate against * @returns boolean indicating if the bank could have issued the account number * @private * * @example * ```typescript * const isValid = Nuban.isPossibleNubanBank('0123456789', '000014'); * // Returns true if the check digit matches the bank's algorithm * ``` */ private static isPossibleNubanBank; } export { Nuban, PaymentProvider, Bank, BankProperty, AccountValidationResponse, CardType, CardBrand, CardBinResponse, };