import {z} from 'zod' export type GetApiAccountHoldersIdTransactionRulesArgs = {id: string}; export type GetApiAccountHoldersIdTransactionRulesOptions = {baseUrl?: string | undefined, clientKey?: string | undefined, fetch?: typeof fetch | undefined}; export const transactionRuleEntityKey = z.object({entityReference: z.string().optional(), entityType: z.string().optional()}); export const duration = z.object({unit: z.enum(["days", "hours", "minutes", "months", "weeks"]).optional(), value: z.number().int().optional()}); export const transactionRuleInterval = z.object({dayOfMonth: z.number().int().optional(), dayOfWeek: z.enum(["friday", "monday", "saturday", "sunday", "thursday", "tuesday", "wednesday"]).optional(), duration: duration.optional(), timeOfDay: z.string().optional(), timeZone: z.string().optional(), type: z.enum(["daily", "lifetime", "monthly", "perTransaction", "rolling", "sliding", "weekly"])}); export const activeNetworkTokensRestriction = z.object({operation: z.string(), value: z.number().int().optional()}); export const brandVariantsRestriction = z.object({operation: z.string(), value: z.array(z.string()).optional()}); export const bankIdentification = z.object({country: z.string().optional(), identification: z.string().optional(), identificationType: z.enum(["bic", "iban", "routingNumber", "sortCode"]).optional()}); export const counterpartyBankRestriction = z.object({operation: z.string(), value: z.array(bankIdentification).optional()}); export const counterpartyTypesRestriction = z.object({operation: z.string(), value: z.array(z.enum(["balanceAccount", "bankAccount", "card", "transferInstrument"])).optional()}); export const countriesRestriction = z.object({operation: z.string(), value: z.array(z.string()).optional()}); export const dayOfWeekRestriction = z.object({operation: z.string(), value: z.array(z.enum(["friday", "monday", "saturday", "sunday", "thursday", "tuesday", "wednesday"])).optional()}); export const differentCurrenciesRestriction = z.object({operation: z.string(), value: z.boolean().optional()}); export const entryModesRestriction = z.object({operation: z.string(), value: z.array(z.enum(["barcode", "chip", "cof", "contactless", "magstripe", "manual", "ocr", "server", "unknown"])).optional()}); export const internationalTransactionRestriction = z.object({operation: z.string(), value: z.boolean().optional()}); export const matchingTransactionsRestriction = z.object({operation: z.string(), value: z.number().int().optional()}); export const matchingValuesRestriction = z.object({operation: z.string(), value: z.array(z.enum(["acquirerId", "amount", "currency", "merchantId", "merchantName"])).optional()}); export const mccsRestriction = z.object({operation: z.string(), value: z.array(z.string()).optional()}); export const stringMatch = z.object({operation: z.enum(["contains", "endsWith", "isEqualTo", "startsWith"]).optional(), value: z.string().optional()}); export const merchantNamesRestriction = z.object({operation: z.string(), value: z.array(stringMatch).optional()}); export const merchantAcquirerPair = z.object({acquirerId: z.string().optional(), merchantId: z.string().optional()}); export const merchantsRestriction = z.object({operation: z.string(), value: z.array(merchantAcquirerPair).optional()}); export const processingTypesRestriction = z.object({operation: z.string(), value: z.array(z.enum(["atmWithdraw", "balanceInquiry", "ecommerce", "moto", "pos", "recurring", "token", "unknown"])).optional()}); export const riskScores = z.object({mastercard: z.number().int().optional(), visa: z.number().int().optional()}); export const riskScoresRestriction = z.object({operation: z.string(), value: riskScores.optional()}); export const sameAmountRestriction = z.object({operation: z.string(), value: z.boolean().optional()}); export const sameCounterpartyRestriction = z.object({operation: z.string(), value: z.boolean().optional()}); export const sourceAccountTypesRestriction = z.object({operation: z.string(), value: z.array(z.enum(["balanceAccount", "businessAccount"])).optional()}); export const timeOfDay = z.object({endTime: z.string().optional(), startTime: z.string().optional()}); export const timeOfDayRestriction = z.object({operation: z.string(), value: timeOfDay.optional()}); export const tokenRequestorsRestriction = z.object({operation: z.string(), value: z.array(z.string()).optional()}); export const amount = z.object({currency: z.string(), value: z.number().int()}); export const totalAmountRestriction = z.object({operation: z.string(), value: amount.optional()}); export const walletProviderAccountScoreRestriction = z.object({operation: z.string(), value: z.number().int().optional()}); export const walletProviderDeviceScore = z.object({operation: z.string(), value: z.number().int().optional()}); export const walletProviderDeviceType = z.object({operation: z.string(), value: z.array(z.enum(["CARD", "MOBILE_PHONE", "OTHER", "PC", "TABLET_OR_EREADER", "UNKNOWN", "WATCH_OR_WRISTBAND", "WEARABLE"])).optional()}); export const transactionRuleRestrictions = z.object({activeNetworkTokens: activeNetworkTokensRestriction.optional(), brandVariants: brandVariantsRestriction.optional(), counterpartyBank: counterpartyBankRestriction.optional(), counterpartyTypes: counterpartyTypesRestriction.optional(), countries: countriesRestriction.optional(), dayOfWeek: dayOfWeekRestriction.optional(), differentCurrencies: differentCurrenciesRestriction.optional(), entryModes: entryModesRestriction.optional(), internationalTransaction: internationalTransactionRestriction.optional(), matchingTransactions: matchingTransactionsRestriction.optional(), matchingValues: matchingValuesRestriction.optional(), mccs: mccsRestriction.optional(), merchantNames: merchantNamesRestriction.optional(), merchants: merchantsRestriction.optional(), processingTypes: processingTypesRestriction.optional(), riskScores: riskScoresRestriction.optional(), sameAmountRestriction: sameAmountRestriction.optional(), sameCounterpartyRestriction: sameCounterpartyRestriction.optional(), sourceAccountTypes: sourceAccountTypesRestriction.optional(), timeOfDay: timeOfDayRestriction.optional(), tokenRequestors: tokenRequestorsRestriction.optional(), totalAmount: totalAmountRestriction.optional(), walletProviderAccountScore: walletProviderAccountScoreRestriction.optional(), walletProviderDeviceScore: walletProviderDeviceScore.optional(), walletProviderDeviceType: walletProviderDeviceType.optional()}); export const transactionRule = z.object({aggregationLevel: z.string().optional(), description: z.string().max(300), endDate: z.string().optional(), entityKey: transactionRuleEntityKey, id: z.string().optional(), interval: transactionRuleInterval, outcomeType: z.enum(["enforceSCA", "hardBlock", "scoreBased", "timedBlock"]).optional(), overridesRule: z.string().optional(), purpose: z.enum(["compliance", "fraud", "internalPolicy", "policy", "system"]).optional(), reference: z.string().max(150), requestType: z.enum(["authentication", "authorization", "bankTransfer", "tokenization"]).optional(), ruleRestrictions: transactionRuleRestrictions, score: z.number().int().optional(), startDate: z.string().optional(), status: z.enum(["active", "inactive"]).optional(), type: z.enum(["allowList", "blockList", "bypass", "maxUsage", "velocity"])}); export const transactionRulesResponse = z.object({transactionRules: z.array(transactionRule).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 }; /** * Get all transaction rules for an account holder * * GET /accountHolders/{id}/transactionRules * * Also accepts auth: BasicAuth, ApiKeyAuth */ export const getApiAccountHoldersIdTransactionRules = async (args: GetApiAccountHoldersIdTransactionRulesArgs, options?: GetApiAccountHoldersIdTransactionRulesOptions) => { const {baseUrl = "https://balanceplatform-api-test.adyen.com/bcl/v2", fetch: fetchFn = fetch, clientKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (clientKey !== undefined) query.set("clientKey", clientKey) const url = `${baseUrl.replace(/\/+$/, '')}/accountHolders/${encodeURIComponent(String(args.id))}/transactionRules${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(transactionRulesResponse, await res.json()) };