import {z} from 'zod' export type Limit = number; export type Offset = number; export type Sort = string; export type GetApiAuthorisationsArgs = {createdAfter?: string | undefined, createdBefore?: string | undefined, limit?: Limit | undefined, offset?: Offset | undefined, sort?: Sort | undefined, 'Partner-Code'?: string | undefined, 'Merchant-Id'?: string | undefined, storeId?: string | undefined, terminalId?: string | undefined, orderId?: string | undefined}; export type GetApiAuthorisationsOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const recordId = z.string(); export const authorisationCreated = z.string(); export const authorisationStatus = z.enum(["APPROVED", "DECLINED", "PENDING"]); export const authorisationCode = z.string(); export const authorisationChannel = z.enum(["ECOMMERCE", "POINT_OF_SALE", "PAY_BY_LINK", "MAIL_ORDER", "TELEPHONE_ORDER"]); export const transactionType = z.enum(["PURCHASE", "PAYMENT", "CASH_ADVANCE", "REFUND", "PURCHASE_WITH_CASHBACK", "CARD_VERIFICATION", "PREPAID_LOAD", "BALANCE_ENQUIRY", "CHECK_VERIFICATION", "CHECK_GUARANTEE", "PURCHASE_ADJUSTMENT", "MOBILE_TOPUP", "PURCHASE_WITH_TIP", "ADMIN", "ACCOUNT_FUNDING_TRANSACTION", "ORIGINAL_CREDIT", "MONEY_TRANSFER"]); export const transactionSubtype = z.enum(["PRE_AUTH", "PRE_AUTH_INCREMENT", "PRE_AUTH_DECREMENT", "COMPLETION", "CANCEL", "OTHER"]).nullable(); export const transactionMessageTypeCode = z.string(); export const externalMerchantId = z.string().max(30); export const merchantTradeName = z.string(); export const merchantLocation = z.string().min(3).max(3).nullable(); export const merchantCategoryCode = z.string().min(4).max(4).nullable(); export const allianceCode = z.string().min(1).max(50).nullable(); export const partnerCode = z.string().min(1).max(50).nullable(); export const transactionProductID = z.string(); export const paymentInstrumentCategory = z.enum(["CARD", "CASH", "ALTERNATIVE"]); export const paymentInstrumentCardBrand = z.enum(["AMEX", "CUP", "DINERS", "GIRO", "JCB", "MAESTRO", "MC", "PAGO", "PP", "PRIV", "VISA", "VPAY", "GIFT", "C_EGIFT", "CARTBLANC", "RUPAY"]); export const instrumentNumberMasked = z.string(); export const paymentInstrumentAlternativeService = z.enum(["BLIK", "ELV", "IDEAL", "KLARNA", "PAYPAL", "PBL", "SEPADD", "SOFORT", "TOPUP", "EASYCASH", "VIPP", "MOBILEPAY", "TWINT", "SWISH", "ALIPAY", "WECHATPAY", "POSTFINANCE", "OTHER"]); export const paymentInstrumentGroup = z.union([z.object({category: paymentInstrumentCategory, brand: paymentInstrumentCardBrand, number: instrumentNumberMasked, expiryDate: z.string().nullable().optional(), subType: z.string().nullable().optional(), serviceType: z.enum(["CREDIT", "DEBIT", "PREPAID"]).nullable().optional(), token: z.string().nullable().optional()}), z.object({category: paymentInstrumentCategory}), z.object({category: paymentInstrumentCategory, service: paymentInstrumentAlternativeService, number: instrumentNumberMasked.optional(), token: z.string().nullable().optional(), expiryDate: z.string().nullable().optional()})]); export const transactionCurrencyCode = z.string().min(3).max(3).nullable(); export const transactionAuthorisedAmount = z.string(); export const dCCIndicator = z.enum(["NONE", "DCC", "DECLINED"]); export const authorisationReversalFlag = z.enum(["NON_REVERSED", "REVERSAL"]); export const authorisationPlatformCode = z.string(); export const authorisation = z.object({id: recordId, created: authorisationCreated, status: authorisationStatus, code: authorisationCode.optional(), channel: authorisationChannel, transactionType: transactionType, transactionSubtype: transactionSubtype.optional(), messageType: transactionMessageTypeCode, merchant: z.object({id: externalMerchantId, name: merchantTradeName.optional(), countryCode: merchantLocation, mcc: merchantCategoryCode, allianceCode: allianceCode, partnerCode: partnerCode.optional(), storeId: z.string().nullable().optional()}), meta: z.object({orderId: z.string().nullable().optional(), referenceId: z.string().nullable().optional(), GUID: z.string().nullable().optional(), retrievalReferenceNumber: z.string().nullable().optional(), merchantReference1: z.string().nullable().optional(), merchantReference2: z.string().nullable().optional(), reservationNumber: z.string().nullable().optional(), customerIPAddress: z.string().nullable().optional(), products: z.array(z.object({id: transactionProductID})).optional()}).optional(), paymentInstrument: paymentInstrumentGroup, financial: z.object({amounts: z.object({currencyCode: transactionCurrencyCode, authorised: transactionAuthorisedAmount, cashback: z.string().nullable().optional(), tip: z.string().nullable().optional()}), dcc: z.object({rate: z.string().nullable().optional(), indicator: dCCIndicator.optional(), currencyCode: z.string().min(3).max(3).nullable().optional()}).optional(), instalment: z.object({totalNumber: z.number().int().nullable().optional(), totalAmount: z.string().nullable().optional(), deferredPeriod: z.number().int().nullable().optional(), first: z.string().nullable().optional()}).optional()}), transactionAttributes: z.object({issuerResponseCode: z.string().nullable().optional(), avsResponse: z.string().nullable().optional(), cvv2Result: z.enum(["M", "N", "P", "S", "U"]).nullable().optional(), reversal: authorisationReversalFlag.optional()}).optional(), captureEnvironment: z.object({platform: authorisationPlatformCode.optional(), transactionSource: z.enum(["TERMINAL", "CONTACTLESS_TAP_TERMINAL", "CLOVER_TERMINAL", "NEXO_TERMINAL", "TERMINAL_ZVT", "API", "CONNECT", "VIRTUAL_TERMINAL"]).nullable().optional(), captureMethod: z.enum(["ECOMMERCE", "CHIP", "CHIP_CONTACTLESS", "CHIP_UNRELIABLE", "MAGNETIC", "MAGNETIC_CONTACTLESS", "MAGNETIC_UNREADABLE", "MAGNETIC_FALLBACK", "MANUAL", "OCR", "UNKNOWN"]).optional(), threeDS: z.enum(["NON_3DS", "MERCHANT_3DS", "FULL_3DS", "MERCHANT_UCAF", "MASTERPASS_MASTERCARD_DECISION", "MASTERPASS_ISSUER_DECISION", "MASTERPASS_MERCHANT_DECISION", "REMOTE_PAYMENT"]).nullable().optional(), terminal: z.object({id: z.string().nullable().optional(), workstationId: z.string().nullable().optional(), serialNumber: z.string().min(3).max(255).nullable().optional(), captureMode: z.enum(["OFFLINE", "ONLINE", "OFFLINE_ONLY"]).nullable().optional(), capability: z.enum(["MANUAL", "MAGNETIC", "CHIP", "KEY", "CONTACTLESS", "CONTACTLESS_MAGNETIC", "UNKNOWN", "CHIP_MAGNETIC_KEY", "MAGNETIC_KEY", "CHIP_MAGNETIC", "CHIP_KEY"]).nullable().optional(), activationFlag: z.enum(["ACTIVATED", "NOT_ACTIVATED"]).nullable().optional(), pinCaptureCapability: z.number().int().nullable().optional()}).optional()}).optional(), _links: z.object({transactions: z.object({href: z.string().optional()}).optional()}).optional()}); export const getApiAuthorisationsResponse = z.array(authorisation); 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 }; /** * List Authorisations * * GET /authorisations */ export const getApiAuthorisations = async (args: GetApiAuthorisationsArgs, options?: GetApiAuthorisationsOptions) => { const {baseUrl = "https://prod.emea.api.fiservapps.com/ipp/omnipay/acquirerprofile/v1.0", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.createdAfter != null) query.append("createdAfter", String(args.createdAfter)) if (args.createdBefore != null) query.append("createdBefore", String(args.createdBefore)) if (args.limit != null) query.append("limit", String(args.limit)) if (args.offset != null) query.append("offset", String(args.offset)) if (args.sort != null) query.append("sort", String(args.sort)) if (args['Partner-Code'] != null) headers.set("Partner-Code", String(args['Partner-Code'])) if (args['Merchant-Id'] != null) headers.set("Merchant-Id", String(args['Merchant-Id'])) if (args.storeId != null) query.append("storeId", String(args.storeId)) if (args.terminalId != null) query.append("terminalId", String(args.terminalId)) if (args.orderId != null) query.append("orderId", String(args.orderId)) const url = `${baseUrl.replace(/\/+$/, '')}/authorisations${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(getApiAuthorisationsResponse, await res.json()) };