import {z} from 'zod' export type MerchantTransactionId = string; export type GetApiPaymentsPaymentIdRefundsArgs = {merchantTransactionId?: MerchantTransactionId | undefined}; export type GetApiPaymentsPaymentIdRefundsOptions = {baseUrl?: string | undefined, ServerApiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const merchantTransactionId = z.string().min(1).max(50); export const customerId = z.string().max(255); export const pspName = z.string().max(50); export const ipAddress = z.string(); export const phoneNumber = z.string().max(255); export const buildingNumberOrName = z.string().max(100); export const addressLineOne = z.string().min(1).max(255); export const addressLineTwo = z.string().max(255); export const addressLineThree = z.string().max(255); export const town = z.string().min(1).max(255); export const county = z.string().max(255); export const postcode = z.string().max(255); export const countryIsoCode = z.string().min(2).max(2); export const address = z.object({firstName: z.string().max(255).optional(), lastName: z.string().max(255).optional(), phoneNumber: phoneNumber.optional(), buildingNumberOrName: buildingNumberOrName.optional(), address1: addressLineOne.optional(), address2: addressLineTwo.optional(), address3: addressLineThree.optional(), town: town.optional(), county: county.optional(), postcode: postcode.optional(), country: countryIsoCode.optional(), countrySubdivisionCode: z.string().min(1).max(3).optional()}); export const dateOfBirth = z.string(); export const trueLayerCustomer = z.object({address: address.optional(), dateOfBirth: dateOfBirth.optional(), customerId: z.string().optional(), name: z.string().optional()}); export const accountNumber = z.string(); export const sortCode = z.string(); export const iban = z.string().min(15).max(34); export const revolutFingerprint = z.string().min(44).max(44); export const revolutPayBillingAddress = z.object({street_line_1: z.string().max(100).optional(), street_line_2: z.string().max(100).optional(), region: z.string().max(100).optional(), city: z.string().max(100).optional(), country_code: z.string().max(2).optional(), postcode: z.string().max(100).optional()}); export const vaultId = z.string().min(1).max(255); export const paymentSource = z.object({name: z.string().min(1).max(255).optional(), email: z.string().min(1).max(254).optional(), accountId: z.string().min(1).max(255).optional(), vaultId: vaultId.optional()}); export const additionalInfo = z.discriminatedUnion("type", [z.object({type: z.string(), customerFirstName: z.string().optional(), customerLastName: z.string().optional(), customerDateOfBirth: z.string().optional(), customerIpAddress: ipAddress.optional(), customerId: z.string().optional(), paysafecardCustomerId: z.string().optional()}), z.object({type: z.string(), customerPaymentOptionId: z.string().optional()}), z.object({type: z.string(), customerPaymentOptionId: z.string().optional()}), z.object({type: z.string(), customer: trueLayerCustomer.optional(), providerId: z.string().optional(), paymentSourceId: z.string().optional(), originalTransactionId: z.string().optional(), accountNumber: accountNumber.optional(), sortCode: sortCode.optional(), iban: iban.optional()}), z.object({type: z.string(), fingerprint: revolutFingerprint.optional(), name: z.string().min(2).optional(), emailAddress: z.string().min(2).optional(), paymentRevTag: z.string().min(2).optional(), revolutCustomerId: z.string().optional(), billingAddress: revolutPayBillingAddress.optional()}), z.object({type: z.string(), vaultId: vaultId.optional(), paymentSource: paymentSource.optional()}), z.object({type: z.string(), pin: z.string().max(12).optional(), serialNumber: z.string().max(12).optional()})]); export const rawPspResponse = z.object({httpStatusCode: z.number().int().optional(), body: z.string().optional(), pspName: pspName, headers: z.record(z.string(), z.array(z.string())).optional()}); export const pspInfo = z.object({name: pspName, transactionId: z.string(), switchAccountId: z.string().min(1).max(255).optional(), pspToken: z.string().optional(), pspCardFingerprint: z.string().optional(), provisionedUserId: z.string().optional(), additionalInfo: additionalInfo.optional(), rawPspResponses: z.array(rawPspResponse).nullable().optional(), paymentAccountReference: z.string().optional()}); export const cardExpiryDate = z.string(); export const cardMetadata = z.object({cardBrand: z.string().optional(), issuer: z.string().optional(), type: z.enum(["DEBIT", "CREDIT", "CHARGE_CARD", "CHARGE", "DEFERRED_DEBIT", "PREPAID", "PREPAID_RELOADABLE", "UNKNOWN"]).optional(), category: z.string().optional(), countryIsoA2: countryIsoCode.optional(), commercial: z.boolean().optional(), bin: z.string().min(6).max(8).optional()}); export const fingerprint = z.string(); export const fingerprintExtended = z.string(); export const paymentStatusPaymentInstrumentCard = z.object({type: z.string(), nameOnCard: z.string().optional(), pan: z.string(), expiryDate: cardExpiryDate, cardMetadata: cardMetadata.optional(), fingerprint: fingerprint, fingerprintExtended: fingerprintExtended}); export const currencyCodeNumeric = z.string(); export const applePayDecryptedPaymentData = z.object({eciIndicator: z.number().int().optional()}); export const applePayDecryptedPayload = z.object({applicationPrimaryAccountNumber: z.string(), applicationExpirationDate: z.string(), currencyCode: currencyCodeNumeric, transactionAmount: z.number().int(), deviceManufacturerIdentifier: z.string(), paymentDataType: z.enum(["3DSecure", "EMV"]), paymentData: applePayDecryptedPaymentData, transactionId: z.string(), cardholderName: z.string().optional()}); export const applePayPaymentMethod = z.object({displayName: z.string().optional(), network: z.string().optional(), type: z.string().optional()}); export const paymentStatusPaymentInstrumentApplePay = z.object({type: z.string(), metadata: cardMetadata.optional(), expiryDate: cardExpiryDate.optional(), fingerprint: fingerprint.optional(), fingerprintExtended: fingerprintExtended.optional(), decryptedPayload: applePayDecryptedPayload.optional(), paymentMethod: applePayPaymentMethod.optional(), cardMetadata: cardMetadata.optional()}); export const googlePayDecryptedAssuranceDetails = z.object({accountVerified: z.boolean().optional(), cardholderAuthenticated: z.boolean().optional()}); export const googlePayDecryptedPaymentMethodDetails = z.object({pan: z.string().optional(), expirationMonth: z.number().int().optional(), expirationYear: z.number().int().optional(), authMethod: z.enum(["PAN_ONLY", "CRYPTOGRAM_3DS"]).optional(), eciIndicator: z.string().optional(), assuranceDetails: googlePayDecryptedAssuranceDetails.optional(), cardLastFour: z.string().optional()}); export const googlePayDecryptedPayload = z.object({gatewayMerchantId: z.string().optional(), messageExpiration: z.string().optional(), messageId: z.string().optional(), paymentMethod: z.literal("CARD").optional(), paymentMethodDetails: googlePayDecryptedPaymentMethodDetails.optional()}); export const paymentStatusPaymentInstrumentGooglePay = z.object({type: z.string(), metadata: cardMetadata.optional(), expiryDate: cardExpiryDate.optional(), fingerprint: fingerprint.optional(), fingerprintExtended: fingerprintExtended.optional(), decryptedPayload: googlePayDecryptedPayload.optional(), cardMetadata: cardMetadata.optional()}); export const clickToPayPayload = z.object({assuranceData: z.object({eci: z.string().optional()}).optional(), decryptedPayload: z.object({token: z.object({paymentToken: z.string().optional(), tokenExpirationMonth: z.string().optional(), tokenExpirationYear: z.string().optional(), paymentAccountReference: z.string().optional()}).optional(), billingAddress: z.object({name: z.string().optional(), line1: z.string().optional(), line2: z.string().optional(), line3: z.string().optional(), city: z.string().optional(), state: z.string().optional(), zip: z.string().optional(), countryCode: z.string().optional()}).optional(), consumerFullName: z.string().optional(), consumerFirstName: z.string().optional(), consumerLastName: z.string().optional(), dynamicData: z.array(z.object({dynamicDataValue: z.string().optional(), dynamicDataType: z.string().optional()})).optional()}).optional()}); export const paymentStatusPaymentInstrumentClickToPay = z.object({type: z.string(), metadata: cardMetadata.optional(), expiryDate: cardExpiryDate.optional(), fingerprint: fingerprint.optional(), fingerprintExtended: fingerprintExtended.optional(), payload: clickToPayPayload.optional()}); export const paymentInstrumentAccountBase = z.object({accountId: z.string().optional()}); export const paymentStatusPaymentInstrumentPayPal = z.object({type: z.string(), account: paymentInstrumentAccountBase.optional()}); export const paymentStatusPaymentInstrumentIdeal = z.object({type: z.string()}); export const paymentStatusPaymentInstrumentBancontact = z.object({type: z.string()}); export const paymentStatusPaymentInstrumentTrustly = z.object({type: z.string(), account: z.object({accountId: z.string(), bank: z.string().optional(), town: z.string().optional(), name: z.string().optional(), address: z.string().optional(), postcode: z.string().optional(), descriptor: z.string().optional(), lastDigits: z.string().optional(), clearingHouse: z.string().optional(), verified: z.boolean().optional()}).optional()}); export const paymentStatusPaymentInstrumentPix = z.object({type: z.string()}); export const paymentStatusPaymentInstrumentPspTokenInstrument = z.object({type: z.string(), token: z.string().optional(), customerId: z.string().optional()}); export const paymentStatusPaymentInstrumentAstroPayInstrument = z.object({type: z.string()}); export const paymentStatusPaymentInstrumentPaysafecard = z.object({type: z.string(), account: paymentInstrumentAccountBase.optional()}); export const paymentStatusPaymentInstrumentEasyPay = z.object({type: z.string()}); export const paymentStatusPaymentInstrumentEPay = z.object({type: z.string()}); export const paymentStatusPaymentInstrumentNeteller = z.object({type: z.string(), account: paymentInstrumentAccountBase.optional()}); export const paymentStatusPaymentInstrumentSkrill = z.object({type: z.string(), account: paymentInstrumentAccountBase.optional()}); export const paymentStatusPaymentInstrumentSkrillOneTap = z.object({type: z.string(), oneTapPaymentId: z.string()}); export const paymentStatusPaymentInstrumentRevolutPay = z.object({type: z.string()}); export const trueLayerAccountDetails = z.object({accountNumber: accountNumber.optional(), sortCode: sortCode.optional(), iban: iban.optional(), providerId: z.string().optional(), paymentSourceId: z.string().optional()}); export const trueLayerUserData = z.object({title: z.string().optional(), firstName: z.string().optional(), lastName: z.string().optional(), dateOfBirth: dateOfBirth.optional(), address: address.optional(), accountDetails: trueLayerAccountDetails.optional()}); export const paymentStatusPaymentInstrumentTrueLayer = z.object({type: z.string(), userData: trueLayerUserData.optional()}); export const paymentStatusPaymentInstrumentOneVoucher = z.object({type: z.string()}); export const paymentStatusPaymentInstrumentBank2Bank = z.object({type: z.string()}); export const paymentStatusPaymentInstrumentOttVoucher = z.object({type: z.string()}); export const paymentStatusPaymentInstrumentBluVoucher = z.object({type: z.string()}); export const paymentStatusPaymentInstrument = z.discriminatedUnion("type", [paymentStatusPaymentInstrumentCard, paymentStatusPaymentInstrumentApplePay, paymentStatusPaymentInstrumentGooglePay, paymentStatusPaymentInstrumentClickToPay, paymentStatusPaymentInstrumentPayPal, paymentStatusPaymentInstrumentIdeal, paymentStatusPaymentInstrumentBancontact, paymentStatusPaymentInstrumentTrustly, paymentStatusPaymentInstrumentPix, paymentStatusPaymentInstrumentPspTokenInstrument, paymentStatusPaymentInstrumentAstroPayInstrument, paymentStatusPaymentInstrumentPaysafecard, paymentStatusPaymentInstrumentEasyPay, paymentStatusPaymentInstrumentEPay, paymentStatusPaymentInstrumentNeteller, paymentStatusPaymentInstrumentSkrill, paymentStatusPaymentInstrumentSkrillOneTap, paymentStatusPaymentInstrumentRevolutPay, paymentStatusPaymentInstrumentTrueLayer, paymentStatusPaymentInstrumentOneVoucher, paymentStatusPaymentInstrumentBank2Bank, paymentStatusPaymentInstrumentOttVoucher, paymentStatusPaymentInstrumentBluVoucher]); export const refundStatus = z.enum(["APPROVED", "PENDING", "DECLINED", "UNKNOWN"]); export const amount = z.number().int().gte(1).lte(999999999999999); export const customerRefundCode = z.string().max(255); export const getRefundsResponse = z.object({paymentId: z.string(), merchantTransactionId: merchantTransactionId.optional(), customer: z.object({id: customerId}).optional(), code: z.string(), message: z.string(), psp: pspInfo.optional(), timestamp: z.string(), paymentInstrument: paymentStatusPaymentInstrument, status: refundStatus, amount: amount, customerRefundCode: customerRefundCode.optional()}); export const getRefundsResponseList = z.array(getRefundsResponse); 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 refund(s) from a payment * * GET /payments/{paymentId}/refunds */ export const getApiPaymentsPaymentIdRefunds = async (args: GetApiPaymentsPaymentIdRefundsArgs, options?: GetApiPaymentsPaymentIdRefundsOptions) => { const {baseUrl = "https://sandbox.comcarde.com/v1", fetch: fetchFn = fetch, ServerApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.merchantTransactionId != null) query.append("merchantTransactionId", String(args.merchantTransactionId)) if (ServerApiKey !== undefined) headers.set('authorization', `Bearer ${ServerApiKey}`) const url = `${baseUrl.replace(/\/+$/, '')}/payments/${encodeURIComponent(String(args.paymentId))}/refunds${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(getRefundsResponseList, await res.json()) };