import {z} from 'zod' export type GetApiPlatformV1CustomersCustomerReferenceArgs = {customerReference: string}; export type GetApiPlatformV1CustomersCustomerReferenceOptions = {baseUrl?: string | undefined, Hawk?: string | undefined, fetch?: typeof fetch | undefined}; export const taxResidence = z.object({country: z.string().min(2).max(2), tin: z.string().max(64).optional(), noTinReason: z.enum(["NOT_ISSUED", "UNABLE_TO_OBTAIN", "NOT_REQUIRED"]).optional(), noTinExplanation: z.string().max(1024).optional()}); export const addressCountryCode = z.string(); export const addressV2 = z.object({addressLine1: z.string().max(255), addressLine2: z.string().max(255).optional(), postalCode: z.string().max(255), city: z.string().max(255), countryCode: addressCountryCode, country: z.string().optional(), stateCode: z.string().max(2).optional()}); export const getCustomerResponseCompany = z.object({reference: z.string(), status: z.enum(["PENDING", "VERIFIED", "REJECTED"]), type: z.literal("COMPANY"), company: z.object({name: z.string().optional(), description: z.string().optional(), taxResidenceCountryCode: z.string().optional(), registrationNumber: z.string().optional(), industry: z.object({reference: z.string().optional(), name: z.string().optional(), children: z.array(z.object({})).optional()}).optional(), monthlyExpectedVolumes: z.object({reference: z.string().optional(), name: z.string().optional(), min: z.number().optional(), max: z.number().optional()}).optional(), address: z.object({addressLine1: z.string().optional(), addressLine2: z.string().optional(), postalCode: z.string().optional(), city: z.string().optional(), countryCode: z.string().optional(), country: z.string().optional(), stateCode: z.string().optional()}).optional(), representative: z.object({firstName: z.string().optional(), lastName: z.string().optional(), dateOfBirth: z.string().optional(), birthCountryCode: z.string().optional(), nationality: z.string().optional(), address: z.object({addressLine1: z.string().optional(), addressLine2: z.string().optional(), postalCode: z.string().optional(), city: z.string().optional(), countryCode: z.string().optional(), country: z.string().optional(), stateCode: z.string().optional()}).optional()}).optional(), taxResidences: z.array(taxResidence).optional(), countryOfIncorporation: z.string().optional(), crsClassification: z.enum(["ACTIVE_NFE", "PASSIVE_NFE", "FI_OTHER", "PMIE_PARTICIPATING", "PMIE_NON_PARTICIPATING"]).optional(), carfClassification: z.enum(["EXCLUDED_FI", "EXCLUDED_GOVERNMENT", "EXCLUDED_LISTED_PMIE", "EXCLUDED_LISTED", "ACTIVE_ENTITY", "OTHER_ENTITY"]).optional(), associates: z.array(z.object({person: z.object({reference: z.string().optional(), firstName: z.string().optional(), lastName: z.string().optional(), dateOfBirth: z.string().optional(), placeOfBirth: z.string().optional(), address: addressV2.optional()}).optional(), details: z.object({nationality: z.string().optional(), contactInfo: z.object({emailAddress: z.string().optional(), phoneNumber: z.string().optional()}).optional(), documentNumber: z.string().optional(), documentInfo: z.object({number: z.string().optional(), type: z.enum(["PASSPORT", "ID_CARD", "DRIVERS", "RESIDENCE_PERMIT", "OTHER"]).optional(), issuingCountryCode: z.string().optional()}).optional(), taxIdentification: z.object({number: z.string().optional(), taxResidenceCountryCode: z.string().optional()}).optional()}).optional(), title: z.enum(["BUSINESS_OWNER", "ACCOUNT_REPRESENTATIVE", "DIRECTOR"]).optional(), controls: z.object({hasOwnership: z.boolean().optional(), hasControl: z.boolean().optional(), isSigner: z.boolean().optional()}).optional(), ownership: z.object({type: z.enum(["DIRECT", "INDIRECT"]).optional(), percentage: z.number().optional()}).optional(), controllingPersonRole: z.enum(["LP_OWNERSHIP", "LP_OTHER_MEANS", "LP_SENIOR_MANAGING_OFFICIAL", "TRUST_SETTLOR", "TRUST_TRUSTEE", "TRUST_PROTECTOR", "TRUST_BENEFICIARY", "TRUST_OTHER", "ARR_SETTLOR_EQ", "ARR_TRUSTEE_EQ", "ARR_PROTECTOR_EQ", "ARR_BENEFICIARY_EQ", "ARR_OTHER_EQ"]).optional(), taxResidences: z.array(taxResidence).optional()})).optional()})}); export const getCustomerResponseIndividual = z.object({reference: z.string(), status: z.enum(["PENDING", "VERIFIED", "REJECTED"]), type: z.literal("INDIVIDUAL"), individual: z.object({description: z.string().optional(), person: z.object({reference: z.string().optional(), firstName: z.string().optional(), lastName: z.string().optional(), dateOfBirth: z.string().optional(), placeOfBirth: z.string().optional(), address: addressV2.optional(), taxResidences: z.array(taxResidence).optional()}).optional(), details: z.object({nationality: z.string().optional(), birthCountryCode: z.string().optional(), contactInfo: z.object({emailAddress: z.string().optional(), phoneNumber: z.string().optional()}).optional(), documentNumber: z.string().optional(), documentInfo: z.object({number: z.string().optional(), type: z.enum(["PASSPORT", "ID_CARD", "DRIVERS", "RESIDENCE_PERMIT", "OTHER"]).optional(), issuingCountryCode: z.string().optional()}).optional(), taxIdentification: z.object({number: z.string().optional(), taxResidenceCountryCode: z.string().optional()}).optional()}).optional(), cdd: z.object({intendedUseOfAccount: z.enum(["TRANSFERS_OWN_WALLET", "TRANSFERS_FAMILY_FRIENDS", "INVESTMENTS", "GOODS_SERVICES", "DONATIONS"]).optional(), pepStatus: z.enum(["NOT_PEP", "FORMER_PEP_2_YEARS", "FORMER_PEP_OLDER", "DOMESTIC_PEP", "FOREIGN_PEP", "CLOSE_ASSOCIATES", "FAMILY_MEMBERS"]).optional(), expectedMonthlyVolume: z.object({amount: z.number().optional(), currency: z.string().optional()}).optional(), employmentStatus: z.enum(["SELF_EMPLOYED", "SALARIED", "UNEMPLOYED", "RETIRED", "STUDENT"]).optional(), sourceOfFunds: z.enum(["SALARY", "PENSION", "SAVINGS", "SELF_EMPLOYMENT", "CRYPTO_TRADING", "GAMBLING", "REAL_ESTATE", "GIFT", "STUDENT_LOAN"]).optional(), estimatedYearlyIncome: z.enum(["INCOME_0_TO_50K", "INCOME_50K_TO_100K", "INCOME_100K_TO_250K", "INCOME_250K_TO_500K", "INCOME_500K_TO_750K", "INCOME_750K_TO_1M", "INCOME_ABOVE_1M"]).optional(), employmentIndustrySector: z.enum(["INVESTMENT", "HEDGE_FUND", "MONEY_SERVICE_BUSINESS", "STO_ISSUER", "PRECIOUS_METALS", "NON_PROFIT", "REGISTERED_INVESTMENT_ADVISOR", "AGRICULTURE_FORESTRY_FISHING_HUNTING", "MINING", "UTILITIES", "CONSTRUCTION", "MANUFACTURING", "WHOLESALE_TRADE", "RETAIL_TRADE", "TRANSPORTATION_WAREHOUSING", "INFORMATION", "FINANCE_INSURANCE", "REAL_ESTATE_RENTAL_LEASING", "PROFESSIONAL_SCIENTIFIC_TECHNICAL_SERVICES", "MANAGEMENT_OF_COMPANIES_ENTERPRISES", "ADMINISTRATIVE_SUPPORT_WASTE_MANAGEMENT_REMEDIATION_SERVICES", "EDUCATIONAL_SERVICES", "HEALTH_CARE_SOCIAL_ASSISTANCE", "ARTS_ENTERTAINMENT_RECREATION", "ACCOMMODATION_FOOD_SERVICES", "OTHER_SERVICES", "PUBLIC_ADMINISTRATION", "NOT_CLASSIFIED", "ADULT_ENTERTAINMENT", "AUCTIONS", "AUTOMOBILES", "BLOCKCHAIN", "CRYPTO", "DRUGS", "EXPORT_IMPORT", "E_COMMERCE", "FINANCIAL_INSTITUTION", "GAMBLING", "INSURANCE", "MARKET_MAKER", "SHELL_BANK", "TRAVEL_TRANSPORT", "WEAPONS"]).optional()}).optional()}), flowType: z.string().optional(), riskScore: z.enum(["LOW", "MEDIUM", "HIGH"]).optional(), verification: z.object({status: z.string().optional()}).optional()}); export const getCustomerResponse = z.discriminatedUnion("type", [getCustomerResponseCompany, getCustomerResponseIndividual]); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Get customer * * GET /platform/v1/customers/{customerReference} */ export const getApiPlatformV1CustomersCustomerReference = async (args: GetApiPlatformV1CustomersCustomerReferenceArgs, options?: GetApiPlatformV1CustomersCustomerReferenceOptions) => { const {baseUrl = "https://api.sandbox.bvnk.com", fetch: fetchFn = fetch, Hawk} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (Hawk !== undefined) headers.set("Authorization", Hawk) const url = `${baseUrl.replace(/\/+$/, '')}/platform/v1/customers/${encodeURIComponent(String(args.customerReference))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(getCustomerResponse, await res.json()) };