import {z} from 'zod' export type GetApiPaymentsPaymentIdStatusArgs = {paymentId: string, include?: Array<'issuerResponse'> | undefined}; export type GetApiPaymentsPaymentIdStatusOptions = {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 relationshipIdentifier = z.object({id: z.string(), type: 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 cardExpiryDate = z.string(); export const fingerprint = z.string(); export const fingerprintExtended = z.string(); export const paymentResponseCard = z.object({type: z.string(), metadata: cardMetadata.optional(), expiryDate: cardExpiryDate.optional(), fingerprint: fingerprint.optional(), fingerprintExtended: fingerprintExtended.optional()}); export const paymentResponseTokenized = z.object({type: z.string(), metadata: cardMetadata.optional(), expiryDate: cardExpiryDate.optional(), fingerprint: fingerprint.optional(), fingerprintExtended: fingerprintExtended.optional()}); 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 paymentResponseApplePay = z.object({type: z.string(), metadata: cardMetadata.optional(), expiryDate: cardExpiryDate.optional(), fingerprint: fingerprint.optional(), fingerprintExtended: fingerprintExtended.optional(), decryptedPayload: applePayDecryptedPayload.optional(), paymentMethod: applePayPaymentMethod.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 paymentResponseGooglePay = z.object({type: z.string(), metadata: cardMetadata.optional(), expiryDate: cardExpiryDate.optional(), fingerprint: fingerprint.optional(), fingerprintExtended: fingerprintExtended.optional(), decryptedPayload: googlePayDecryptedPayload.optional()}); export const issuerResponse = z.object({issuerPaymentMethod: z.string().optional(), issuerCardType: z.string().optional(), merchantAdviceCode: z.string().optional(), type: z.string().optional(), issuerResponse: z.object({issuerPaymentMethod: z.string().optional(), issuerCardType: z.string().optional(), merchantAdviceCode: z.string().optional()}).optional()}); export const paymentResponseIssuerResponse = z.object({type: z.string(), issuerResponse: issuerResponse.optional()}); export const paymentResponsePaymentInstrument = z.discriminatedUnion("type", [paymentResponseCard, paymentResponseTokenized, paymentResponseApplePay, paymentResponseGooglePay, paymentResponseIssuerResponse]); export const includedRelationshipsItemPaymentInstrument = z.object({attributes: paymentResponsePaymentInstrument.optional(), id: z.string(), type: z.string()}); export const includedRelationshipsItemIssuerResponse = z.object({attributes: issuerResponse.optional(), id: z.string(), type: z.string()}); export const includedRelationshipsItem = z.discriminatedUnion("type", [includedRelationshipsItemPaymentInstrument, includedRelationshipsItemIssuerResponse]); 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 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 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 paymentStatus = z.enum(["AUTHORIZED", "AUTHORIZATION_DECLINED", "AUTHORIZATION_PENDING", "CAPTURED", "CAPTURE_FAILED", "CAPTURE_PENDING", "EXPIRED", "REJECTED", "VOIDED", "VOID_PENDING", "VOID_FAILED", "BLOCKED", "UNKNOWN"]); export const comcardeCode = z.object({code: z.string().optional(), description: z.string().optional()}); export const kountRiskAssessment = z.object({score: z.number().optional(), decision: z.enum(["APPROVED", "DECLINED", "UNAVAILABLE", "REVIEW"]), reasonCode: z.string().optional(), transactionId: z.string().optional(), tags: z.array(z.string()).nullable().optional()}); export const rawResponse = z.object({httpStatusCode: z.number().int().optional(), body: z.string().optional()}); export const merchantRiskAssessment = z.object({decision: z.enum(["APPROVED", "DECLINED", "UNAVAILABLE", "HELD"]), code: z.string().optional(), message: z.string().optional(), retryable: z.boolean().optional(), transactionId: z.string().optional(), rawResponse: rawResponse.optional()}); export const riskAssessments = z.object({kount: kountRiskAssessment.optional(), merchant: merchantRiskAssessment.optional()}); export const cashierId = z.string(); export const customMetadata = z.record(z.string(), z.string().max(200)); export const paymentRails = z.enum(["EFTPOS", "VISA", "MASTERCARD"]); export const customerIdentifiers = z.object({customerId: customerId.optional()}); export const keyIdentifierId = z.string(); export const keyIdentifierValue = z.string(); export const googlePay3DSCryptogramKeyIdentifiers = z.object({type: z.string(), dpan: z.object({id: keyIdentifierId.optional(), value: keyIdentifierValue.optional()})}); export const googlePayPanOnlyKeyIdentifiers = z.object({type: z.string()}); export const revolutPayKeyIdentifiers = z.object({type: z.string(), fingerprint: z.object({id: keyIdentifierId.optional(), value: keyIdentifierValue.optional()})}); export const payPalKeyIdentifiers = z.object({type: z.string(), accountId: z.object({id: keyIdentifierId.optional(), value: keyIdentifierValue.optional()})}); export const genericKeyIdentifiers = z.object({type: z.string(), keyIdentifier: z.object({id: keyIdentifierId.optional(), value: keyIdentifierValue.optional()})}); export const paymentInstrumentIdentifiers = z.discriminatedUnion("type", [googlePay3DSCryptogramKeyIdentifiers, googlePayPanOnlyKeyIdentifiers, revolutPayKeyIdentifiers, payPalKeyIdentifiers, genericKeyIdentifiers]); export const keyIdentifiers = z.object({customerIdentifiers: customerIdentifiers.optional(), paymentInstrumentIdentifiers: paymentInstrumentIdentifiers.optional()}); export const avsResult = z.object({code: z.enum(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q"]).optional(), message: z.string().optional()}); export const cvvResult = z.object({code: z.enum(["M", "N", "S", "P", "C", "U", "X", "Z"]).optional()}); export const amountIncludingZero = z.number().int().gte(0).lte(999999999999999); export const currencyCode = z.string(); export const eci = z.string().min(2).max(2); export const scaDetails = z.object({eci: eci.optional()}); export const authenticationRequested = z.object({threeDSecureRequired: z.boolean().optional(), challengeRequested: z.boolean().optional(), automaticallyStepUp: z.boolean().optional()}); export const authenticationResult = z.object({enrollmentStatus: z.enum(["ENROLLED", "NOT_ENROLLED", "UNKNOWN"]).optional(), transStatus: z.enum(["Y", "N", "U", "A", "C", "D", "R", "I", "S"]).optional(), flow: z.enum(["FRICTIONLESS", "CHALLENGE"]).optional(), version: z.string().optional(), eci: eci.optional()}); export const authentication = z.object({requested: authenticationRequested.optional(), result: authenticationResult.optional()}); export const authorizationCode = z.string(); export const blockingRule = z.object({name: z.string()}); export const processedAsAft = z.enum(["YES", "NO", "UNKNOWN"]); export const paymentStatusResponse = 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(), relationships: z.record(z.string(), z.object({data: relationshipIdentifier.optional()})).optional(), included: z.array(includedRelationshipsItem).optional(), paymentInstrument: paymentStatusPaymentInstrument, status: paymentStatus, reference: z.string(), comcardeCode: comcardeCode.optional(), riskAssessments: riskAssessments.optional(), cashierId: cashierId.optional(), customMetadata: customMetadata.optional(), paymentRails: paymentRails.optional(), keyIdentifiers: keyIdentifiers.optional(), avsResult: avsResult.optional(), cvvResult: cvvResult.optional(), amount: amountIncludingZero, currencyCode: currencyCode, scaDetails: scaDetails.optional(), authentication: authentication.optional(), authorizationCode: authorizationCode.optional(), blockingRule: blockingRule.optional(), processedAsAft: processedAsAft.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 the status of a payment * * GET /payments/{paymentId}/status */ export const getApiPaymentsPaymentIdStatus = async (args: GetApiPaymentsPaymentIdStatusArgs, options?: GetApiPaymentsPaymentIdStatusOptions) => { 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.include != null) query.append("include", args.include.join(',')) if (ServerApiKey !== undefined) headers.set('authorization', `Bearer ${ServerApiKey}`) const url = `${baseUrl.replace(/\/+$/, '')}/payments/${encodeURIComponent(String(args.paymentId))}/status${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(paymentStatusResponse, await res.json()) };