import {z} from 'zod' export type GetApiPayments3dsSessions3dsSessionIdArgs = {'3ds_session_id': string}; export type GetApiPayments3dsSessions3dsSessionIdOptions = {baseUrl?: string | undefined, ApiKey?: {username: string, password: string} | undefined, fetch?: typeof fetch | undefined}; export const cardExpiry = z.object({month: z.string(), year: z.string()}); export const acquirer = z.object({bin: z.string().min(6).max(11), merchantIdentifier: z.string(), country: z.string()}); export const threeDSChallenge = z.object({preference: z.enum(["no-preference", "challenge-requested", "challenge-mandated", "no-challenge-requested"]), reason: z.enum(["null", "data-sharing", "low-value", "low-risk", "secure-corporate-payment", "authentication-already-performed"]).nullable().optional()}); export const threeDSInitiator = z.union([z.object({type: z.literal("customer").optional()}), z.object({type: z.literal("merchant").optional(), reason: z.enum(["recurring", "installment", "mail-order", "telephone-order", "add-card", "maintain-card", "other-payment", "account-verification", "split-shipment", "delayed-shipment"]).optional(), initialSession: z.string().optional()})]); export const threeDSAccessControlServer = z.object({transactionIdentifier: z.string(), referenceNumber: z.string(), operatorIdentifier: z.string().nullable().optional()}); export const threeDSDirectoryServer = z.object({transactionIdentifier: z.string(), referenceNumber: z.string(), network: z.enum(["visa", "mastercard", "american-express", "discover", "jcb", "unionpay", "rupay"])}); export const threeDSDcap = z.object({qualified: z.boolean(), accepted: z.boolean().nullable().optional()}).nullable(); export const threeDSSession = z.object({id: z.string(), card: z.object({lastFour: z.string(), expiry: cardExpiry, brand: z.string(), funding: z.string(), segment: z.string(), issuer: z.string().optional(), country: z.string(), currency: z.string()}), acquirer: acquirer, merchant: z.object({name: z.string(), website: z.string(), categoryCode: z.string(), country: z.string()}), payment: z.union([z.object({type: z.literal("installment"), amount: z.number().int(), currency: z.string(), installments: z.number().int(), frequency: z.enum(["daily", "weekly", "monthly", "quarterly", "annually"]), expiry: z.number().int().optional()}), z.object({type: z.literal("one-off"), amount: z.number().int(), currency: z.string()}), z.object({type: z.literal("recurring"), amount: z.number().int(), currency: z.string(), frequency: z.enum(["daily", "weekly", "monthly", "quarterly", "annually"]), expiry: z.number().int()})]).optional(), challenge: threeDSChallenge.optional(), initiator: threeDSInitiator.optional(), accessControlServer: threeDSAccessControlServer.optional(), directoryServer: threeDSDirectoryServer.optional(), threeDSServer: z.object({transactionIdentifier: z.string().optional()}).optional(), version: z.literal("2.2.0"), status: z.enum(["action-required", "success", "failure"]), authentication: z.object({flow: z.enum(["frictionless", "challenge", "attempt"]), methods: z.array(z.enum(["static-passcode", "sms-otp", "emv-card-reader-otp", "app-otp", "other-otp", "knowledge-based", "push-confirmation", "oob-biometrics", "oob-login", "oob-other", "webauthn", "secure-payment-confirmation", "behavioral-biometrics", "electronic", "decoupled"])).optional()}).optional(), nextAction: z.object({type: z.literal("use-sdk")}).optional(), cryptogram: z.string().optional(), eci: z.object({value: z.enum(["00", "01", "02", "04", "05", "06", "07"]).optional(), descriptor: z.enum(["fully-authenticated", "attempted", "not-authenticated"]).optional(), liabilityShift: z.boolean().optional()}).optional(), failureReason: z.enum(["failed-authentication", "card-not-enrolled", "no-card-record", "suspected-fraud", "invalid-acquirer-details", "cancelled", "unsupported-version", "challenge-required", "authentication-timed-out", "acs-unavailable", "directory-server-unavailable", "transient-system-failure", "invalid-card-details", "transaction-not-permitted", "required-data-element-missing", "protocol-error"]).optional(), ares: z.object({transStatus: z.object({value: z.enum(["Y", "N", "U", "A", "C", "D", "R", "I"]).optional(), detail: z.string().optional()}).optional(), transStatusReason: z.object({value: z.string().optional(), detail: z.string().optional()}).nullable().optional(), cardholderInfo: z.string().nullable().optional()}).optional(), cres: z.object({transStatus: z.object({value: z.enum(["Y", "N"]).optional(), detail: z.string().optional()}).optional()}).nullable().optional(), rreq: z.object({transStatus: z.object({value: z.enum(["Y", "N", "U", "A", "R"]).optional(), detail: z.string().optional()}).optional()}).nullable().optional(), dcap: threeDSDcap.optional(), externalCustomerReference: z.string().optional(), createdAt: z.number().int(), updatedAt: z.number().int().optional()}); 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 }; /** * Retrieve a 3DS Session * * GET /payments/3ds-sessions/{3ds_session_id} */ export const getApiPayments3dsSessions3dsSessionId = async (args: GetApiPayments3dsSessions3dsSessionIdArgs, options?: GetApiPayments3dsSessions3dsSessionIdOptions) => { const {baseUrl = "https://api.evervault.com", fetch: fetchFn = fetch, ApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (ApiKey !== undefined) headers.set('authorization', `Basic ${btoa(`${ApiKey.username}:${ApiKey.password}`)}`) const url = `${baseUrl.replace(/\/+$/, '')}/payments/3ds-sessions/${encodeURIComponent(String(args['3ds_session_id']))}${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(threeDSSession, await res.json()) };