import { IBVNVerificationService, BVNVerificationRequest, BVNWithFaceVerificationRequest, BVNAdvanceVerificationRequest, BVNByPhoneNumberRequest, BVNVerificationData, VerificationResponse, } from 'porkate-valid8'; import { BaseIdentityPassService } from './base.service'; /** * IdentityPass BVN Verification Service * * @see https://docs.prembly.com/reference/bvn-basic * @see https://docs.prembly.com/reference/bvn-advance * @see https://docs.prembly.com/reference/bvn-face-validation * @see https://docs.prembly.com/reference/get-bvn-with-phone-number-1 */ export class IdentityPassBVNService extends BaseIdentityPassService implements IBVNVerificationService { /** * BVN Basic Verification - Validate a bank verification number * @see https://docs.prembly.com/reference/bvn-basic */ async verifyBVN( data: BVNVerificationRequest, ): Promise> { return this.makeRequest( '/verification/bvn_validation', { number: data?.bvn, }, this.mapBVNData, ); } /** * BVN Advance Verification - Get detailed BVN information * @see https://docs.prembly.com/reference/bvn-advance */ async verifyBVNAdvance( data: BVNAdvanceVerificationRequest, ): Promise> { return this.makeRequest( '/verification/bvn', { number: data?.bvn, }, this.mapBVNData, ); } /** * BVN with Face Validation - Verify BVN against user's image * @see https://docs.prembly.com/reference/bvn-face-validation */ async verifyBVNWithFace( data: BVNWithFaceVerificationRequest, ): Promise> { return this.makeRequest( '/verification/bvn_w_face', { number: data?.bvn, image: data?.image, }, this.mapBVNData, ); } /** * Get BVN by Phone Number - Retrieve BVN information using phone number * @see https://docs.prembly.com/reference/get-bvn-with-phone-number-1 */ async getBVNByPhoneNumber( data: BVNByPhoneNumberRequest, ): Promise> { return this.makeRequest( '/verification/bvn_with_phone_advance', { phone_number: data?.phoneNumber, }, this.mapBVNData, ); } /** * Map BVN API response to BVNVerificationData * Handles various response field formats from Prembly API */ private mapBVNData( verificationData: Record, payload: Record, ): BVNVerificationData { return { bvn: (verificationData?.bvn as string) || (verificationData?.number as string) || (payload?.number as string), firstName: (verificationData?.firstName as string) || (verificationData?.first_name as string) || (verificationData?.firstname as string) || '', lastName: (verificationData?.lastName as string) || (verificationData?.last_name as string) || (verificationData?.lastname as string) || '', middleName: (verificationData?.middleName as string) || (verificationData?.middle_name as string) || (verificationData?.middlename as string), dateOfBirth: (verificationData?.dateOfBirth as string) || (verificationData?.date_of_birth as string) || (verificationData?.dob as string) || '', phoneNumber: (verificationData?.phoneNumber as string) || (verificationData?.phoneNumber1 as string) || (verificationData?.phone_number as string), phoneNumber2: (verificationData?.phoneNumber2 as string) || (verificationData?.phone_number2 as string), email: verificationData?.email as string, gender: verificationData?.gender as string, address: (verificationData?.residentialAddress as string) || (verificationData?.residential_address as string) || (verificationData?.address as string), photo: (verificationData?.photo as string) || (verificationData?.base64Image as string) || (verificationData?.image as string), enrollmentBank: (verificationData?.enrollmentBank as string) || (verificationData?.enrollment_bank as string), enrollmentBranch: (verificationData?.enrollmentBranch as string) || (verificationData?.enrollment_branch as string), registrationDate: (verificationData?.registrationDate as string) || (verificationData?.registration_date as string), watchListed: this.parseWatchListed( verificationData?.watchListed || verificationData?.watch_listed, ), levelOfAccount: verificationData?.levelOfAccount as string, lgaOfOrigin: verificationData?.lgaOfOrigin as string, lgaOfResidence: verificationData?.lgaOfResidence as string, maritalStatus: verificationData?.maritalStatus as string, nin: verificationData?.nin as string, nameOnCard: verificationData?.nameOnCard as string, nationality: verificationData?.nationality as string, stateOfOrigin: verificationData?.stateOfOrigin as string, stateOfResidence: verificationData?.stateOfResidence as string, title: verificationData?.title as string, ...verificationData, }; } /** * Parse watchListed value to boolean * Handles various formats: "YES"/"NO", "Yes"/"No", true/false */ private parseWatchListed(value: unknown): boolean | undefined { if (value === undefined || value === null) return undefined; if (typeof value === 'boolean') return value; if (typeof value === 'string') { const normalized = value.trim().toUpperCase(); if (normalized === 'YES' || normalized === 'TRUE') return true; if (normalized === 'NO' || normalized === 'FALSE') return false; } return undefined; } }