import {z} from 'zod' export type RecordId = string; export type GetApiTransactionsIdArgs = {id: RecordId}; export type GetApiTransactionsIdOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const recordId = z.string(); 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 authorisationChannel = z.enum(["ECOMMERCE", "POINT_OF_SALE", "PAY_BY_LINK", "MAIL_ORDER", "TELEPHONE_ORDER"]); 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 authorisationCode = 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 paymentInstrumentGroupThin = z.union([z.object({category: paymentInstrumentCategory, brand: paymentInstrumentCardBrand, number: instrumentNumberMasked, subType: z.string().nullable().optional()}), z.object({category: paymentInstrumentCategory}), z.object({category: paymentInstrumentCategory, service: paymentInstrumentAlternativeService, number: instrumentNumberMasked.optional()})]); export const currencyCode = z.string().min(3).max(3).nullable(); export const transaction = z.object({id: recordId, posted: z.string(), authorised: z.string().optional(), status: z.enum(["CLEARED", "REJECTED", "PENDING"]), type: transactionType, channel: authorisationChannel, merchant: z.object({id: externalMerchantId, name: merchantTradeName.optional(), countryCode: merchantLocation, mcc: merchantCategoryCode, allianceCode: allianceCode, partnerCode: z.string().min(1).max(50).nullable().optional(), storeId: z.string().nullable().optional()}), meta: z.object({orderId: z.string().nullable().optional(), authorisationCode: authorisationCode.optional(), fundingDetailId: z.string().optional(), retrievalReferenceNumber: z.string().nullable().optional(), originalReference: z.string().nullable().optional(), terminalBatchNumber: z.string().nullable().optional(), merchantTransactionReference: z.string().nullable().optional(), acquirerReferenceNumber: z.string().nullable().optional()}), paymentInstrument: paymentInstrumentGroupThin, financial: z.object({amounts: z.object({currencyCode: z.string().min(3).max(3).nullable().optional(), transacted: z.string().optional(), cashback: z.string().nullable().optional(), tip: z.string().nullable().optional()}).optional(), fees: z.array(z.object({type: z.string(), currencyCode: currencyCode.optional(), amount: z.string()})).optional(), funding: z.object({currencyCode: z.string().min(3).max(3).nullable().optional(), gross: z.string().nullable().optional(), charges: z.string().nullable().optional(), net: z.string().nullable().optional()}).optional()}), captureEnvironment: z.object({platform: z.string().nullable().optional(), captureMethod: z.enum(["ECOMMERCE", "CHIP", "CHIP_CONTACTLESS", "CHIP_UNRELIABLE", "MAGNETIC", "MAGNETIC_CONTACTLESS", "MAGNETIC_UNREADABLE", "MAGNETIC_FALLBACK", "MANUAL_ENTRY", "OCR", "UNKNOWN"]).nullable().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()}).optional()}).optional(), _links: z.object({authorisations: z.object({href: z.string().optional()}).optional(), fundings: z.object({href: z.string().optional()}).optional()}).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 single transaction * * GET /transactions/{id} */ export const getApiTransactionsId = async (args: GetApiTransactionsIdArgs, options?: GetApiTransactionsIdOptions) => { 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") const url = `${baseUrl.replace(/\/+$/, '')}/transactions/${encodeURIComponent(String(args.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(transaction, await res.json()) };