import {z} from 'zod' export type FraudioProvider = 'fraudio'; export type AcceptorKey = string; export type OpenapiComponentsSchemasPan3 = string; export type ComponentsSchemasExpiryMonth = number; export type OpenapiComponentsSchemasExpiryYear2 = number; export type OpenapiComponentsSchemasHolderName = string; export type ComponentsSchemasCardInput = {number: OpenapiComponentsSchemasPan3, expiryMonth: ComponentsSchemasExpiryMonth, expiryYear: OpenapiComponentsSchemasExpiryYear2, holderName?: OpenapiComponentsSchemasHolderName | undefined}; export type SchemasAmountValue = number; export type OpenapiComponentsSchemasCurrencyCode6 = string; export type OpenapiComponentsSchemasAmount3 = {value: SchemasAmountValue, currency: OpenapiComponentsSchemasCurrencyCode6}; export type Intent = 'purchase' | 'reservation' | 'account-status' | 'payout' | 'payout-status' | 'funding' | 'advice' | 'refund'; export type OpenapiComponentsSchemasCardEntry2 = 'e-commerce' | 'manual' | 'card-on-file' | 'token' | 'token-on-file' | 'terminal'; export type ComponentsSchemasOrder = 'checkout' | 'unspecified' | 'mail' | 'phone' | 'one-click' | 'recurring' | 'ucof' | 'installment' | 'counter'; export type OpenapiComponentsSchemasSequence = 'initial' | 'subsequent'; export type ComponentsSchemasTerminalEntryMode = 'contactless' | 'chip'; export type OpenapiComponentsSchemasChargeType2 = {intent: Intent, cardEntry: OpenapiComponentsSchemasCardEntry2, order: ComponentsSchemasOrder, sequence?: OpenapiComponentsSchemasSequence | undefined, terminalEntryMode?: ComponentsSchemasTerminalEntryMode | undefined}; export type ComponentsSchemasNameOfPeopleAndPlaces = string; export type Email = string; export type SchemasPhoneNumber = string; export type FraudioCustomer = {firstName?: ComponentsSchemasNameOfPeopleAndPlaces | undefined, lastName?: ComponentsSchemasNameOfPeopleAndPlaces | undefined, email?: Email | undefined, phoneNumber?: SchemasPhoneNumber | undefined}; export type SchemasLocalTransactionDateTime = string; export type CvcResult = 'none' | 'match' | 'no-match' | 'not-processed'; export type AvsResult = 'none' | 'match' | 'partial-match' | 'no-match' | 'not-processed'; export type ThreeDsResult = 'authenticated' | 'non-authenticated' | 'attempt'; export type Authentication = {cvc?: CvcResult | undefined, avs?: AvsResult | undefined, threeDsResult?: ThreeDsResult | undefined}; export type ResponseCode = string; export type ComponentsSchemasEci = string; export type Authorization = {responseCode?: ResponseCode | undefined, eci?: ComponentsSchemasEci | undefined}; export type FraudioRequest = {provider: FraudioProvider, merchantAcceptorKey: AcceptorKey, card: ComponentsSchemasCardInput, amount: OpenapiComponentsSchemasAmount3, chargeType: OpenapiComponentsSchemasChargeType2, customer?: FraudioCustomer | undefined, localTransactionDateTime?: SchemasLocalTransactionDateTime | undefined, authentication?: Authentication | undefined, authorizationFields?: Authorization | undefined}; export type CybersourceProvider = 'cybersource'; export type OpenapiComponentsSchemasCountryCodeAlpha2 = string; export type OpenapiComponentsSchemasStateOrProvince2 = string; export type OpenapiComponentsSchemasCity2 = string; export type OpenapiComponentsSchemasLine12 = string; export type OpenapiComponentsSchemasLine22 = string; export type OpenapiComponentsSchemasPostalCode2 = string; export type AddressInputAlpha2 = {countryCode: OpenapiComponentsSchemasCountryCodeAlpha2, stateOrProvince?: OpenapiComponentsSchemasStateOrProvince2 | undefined, city: OpenapiComponentsSchemasCity2, line1: OpenapiComponentsSchemasLine12, line2?: OpenapiComponentsSchemasLine22 | undefined, postalCode: OpenapiComponentsSchemasPostalCode2}; export type CybersourceCustomer = {firstName: ComponentsSchemasNameOfPeopleAndPlaces, lastName: ComponentsSchemasNameOfPeopleAndPlaces, email: Email, phoneNumber: SchemasPhoneNumber, billingAddress: AddressInputAlpha2}; export type CybersourceRequest = {provider: CybersourceProvider, merchantAcceptorKey: AcceptorKey, card: ComponentsSchemasCardInput, amount: OpenapiComponentsSchemasAmount3, chargeType: OpenapiComponentsSchemasChargeType2, customer: CybersourceCustomer, localTransactionDateTime?: SchemasLocalTransactionDateTime | undefined, authentication?: Authentication | undefined, authorizationFields?: Authorization | undefined}; export type RiskAssessmentRequest = FraudioRequest | CybersourceRequest; export type CreateApiRiskAssessmentsArgs = {body: RiskAssessmentRequest}; export type CreateApiRiskAssessmentsOptions = {baseUrl?: string | undefined, ApiKey?: {username: string, password: string} | undefined, fetch?: typeof fetch | undefined}; export const riskAssessmentKey = z.string().min(5).max(120); export const provider = z.union([z.literal("fraudio"), z.literal("cybersource")]); export const acceptorKey = z.string(); export const openapiComponentsSchemasVersion = z.number().int(); export const openapiComponentsSchemasAcceptorRef = z.object({key: acceptorKey, version: openapiComponentsSchemasVersion}); export const chargeKey = z.string().min(5).max(120); export const schemasOutputCard = z.object({last4: z.string().min(4).max(4)}); export const schemasAmountValue = z.number().int().gte(0).lte(900000000); export const openapiComponentsSchemasCurrencyCode6 = z.string(); export const openapiComponentsSchemasAmount3 = z.object({value: schemasAmountValue, currency: openapiComponentsSchemasCurrencyCode6}); export const intent = z.enum(["purchase", "reservation", "account-status", "payout", "payout-status", "funding", "advice", "refund"]); export const openapiComponentsSchemasCardEntry2 = z.enum(["e-commerce", "manual", "card-on-file", "token", "token-on-file", "terminal"]); export const componentsSchemasOrder = z.enum(["checkout", "unspecified", "mail", "phone", "one-click", "recurring", "ucof", "installment", "counter"]); export const openapiComponentsSchemasSequence = z.enum(["initial", "subsequent"]); export const componentsSchemasTerminalEntryMode = z.enum(["contactless", "chip"]); export const openapiComponentsSchemasChargeType2 = z.object({intent: intent, cardEntry: openapiComponentsSchemasCardEntry2, order: componentsSchemasOrder, sequence: openapiComponentsSchemasSequence.optional(), terminalEntryMode: componentsSchemasTerminalEntryMode.optional()}); export const schemasLocalTransactionDateTime = z.string(); export const componentsSchemasNameOfPeopleAndPlaces = z.string().min(1).max(120); export const email = z.string(); export const schemasPhoneNumber = z.string(); export const fraudioCustomer = z.object({firstName: componentsSchemasNameOfPeopleAndPlaces.optional(), lastName: componentsSchemasNameOfPeopleAndPlaces.optional(), email: email.optional(), phoneNumber: schemasPhoneNumber.optional()}); export const openapiComponentsSchemasCountryCodeAlpha2 = z.string(); export const openapiComponentsSchemasStateOrProvince2 = z.string().min(1); export const openapiComponentsSchemasCity2 = z.string().min(1); export const openapiComponentsSchemasLine12 = z.string().min(1); export const openapiComponentsSchemasLine22 = z.string().min(1); export const openapiComponentsSchemasPostalCode2 = z.string(); export const addressInputAlpha2 = z.object({countryCode: openapiComponentsSchemasCountryCodeAlpha2, stateOrProvince: openapiComponentsSchemasStateOrProvince2.optional(), city: openapiComponentsSchemasCity2, line1: openapiComponentsSchemasLine12, line2: openapiComponentsSchemasLine22.optional(), postalCode: openapiComponentsSchemasPostalCode2}); export const cybersourceCustomer = z.object({firstName: componentsSchemasNameOfPeopleAndPlaces, lastName: componentsSchemasNameOfPeopleAndPlaces, email: email, phoneNumber: schemasPhoneNumber, billingAddress: addressInputAlpha2}); export const cvcResult = z.enum(["none", "match", "no-match", "not-processed"]); export const avsResult = z.enum(["none", "match", "partial-match", "no-match", "not-processed"]); export const threeDsResult = z.enum(["authenticated", "non-authenticated", "attempt"]); export const authentication = z.object({cvc: cvcResult.optional(), avs: avsResult.optional(), threeDsResult: threeDsResult.optional()}); export const responseCode = z.string(); export const componentsSchemasEci = z.string(); export const authorization = z.object({responseCode: responseCode.optional(), eci: componentsSchemasEci.optional()}); export const score = z.number(); export const recommendation = z.enum(["green", "amber", "red"]); export const schemasFraudioResult = z.object({score: score, recommendation: recommendation}); export const cybersourceId = z.string(); export const cybersourceScore = z.number().int(); export const openapiComponentsSchemasStatus = z.enum(["ACCEPTED", "REJECTED", "PENDING_REVIEW", "DECLINED", "PENDING_AUTHENTICATION", "INVALID_REQUEST", "AUTHENTICATION_FAILED", "CHALLENGE"]); export const cybersourceResult = z.object({id: cybersourceId, score: cybersourceScore, status: openapiComponentsSchemasStatus}); export const openapiComponentsSchemasCreated2 = z.string(); export const openapiComponentsSchemasLastModified2 = z.string(); export const commonStatus = z.enum(["active", "archived"]); export const riskAssessmentResult = z.object({key: riskAssessmentKey, provider: provider, merchantAcceptorRef: openapiComponentsSchemasAcceptorRef, chargeKey: chargeKey.optional(), card: schemasOutputCard, amount: openapiComponentsSchemasAmount3, chargeType: openapiComponentsSchemasChargeType2, localTransactionDateTime: schemasLocalTransactionDateTime.optional(), customer: z.union([fraudioCustomer, cybersourceCustomer]).optional(), authentication: authentication.optional(), authorizationFields: authorization.optional(), result: z.union([schemasFraudioResult, cybersourceResult]), created: openapiComponentsSchemasCreated2, lastModified: openapiComponentsSchemasLastModified2.optional(), status: commonStatus, version: openapiComponentsSchemasVersion}); 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 }; /** * Perform a risk assessment for a given provider * * POST /riskAssessments * * Also accepts auth: BearerToken */ export const createApiRiskAssessments = async (args: CreateApiRiskAssessmentsArgs, options?: CreateApiRiskAssessmentsOptions) => { const {baseUrl = "https://eu-west-1.api.silverflow.com/v1", fetch: fetchFn = fetch, ApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (ApiKey !== undefined) headers.set('authorization', `Basic ${btoa(`${ApiKey.username}:${ApiKey.password}`)}`) const url = `${baseUrl.replace(/\/+$/, '')}/riskAssessments${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(riskAssessmentResult, await res.json()) };