import {z} from 'zod' export type PaymentId = string; export type GetApiV2PaymentsPaymentIdArgs = {payment_id: PaymentId}; export type GetApiV2PaymentsPaymentIdOptions = {baseUrl?: string | undefined, OAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const paymentId = z.string().min(30).max(50); export const paymentStatus = z.enum(["initiated", "action_required", "submitted", "authorized", "captured", "declined", "failed", "partially_refunded", "refunded"]); export const paymentReason = z.object({code: z.string(), description: z.string()}); export const reference = z.string().min(1).max(50); export const createdAt = z.string().min(24).max(24); export const updatedAt = z.string().min(24).max(24); export const estimatedUpdateBefore = z.string().min(25).max(25); export const amountMinor = z.number().int(); export const currency = z.string().min(3).max(3); export const paymentCheckoutDescription = z.string().min(1).max(250); export const statementDescriptorResponse = z.string().min(1).max(140); export const checkoutId = z.string().min(30).max(50); export const paymentMethodType = z.enum(["card", "sepa_direct_debit"]); export const paymentMethodDisplayHint = z.string().min(1).max(50); export const cardDynamicDescriptor = z.string().min(1).max(18); export const cardScheme = z.enum(["visa", "mastercard"]); export const cardPaymentMethodDetails = z.object({type: paymentMethodType, display_hint: paymentMethodDisplayHint, dynamic_descriptor: cardDynamicDescriptor, card: z.object({scheme: cardScheme, holder_name: z.string().min(1).max(26), first_digits: z.string().min(4).max(6), last_digits: z.string().min(4).max(4), expiry_month: z.number().int().gte(1).lte(12), expiry_year: z.number().int().gte(2021), kind: z.enum(["credit", "debit"]).optional(), segment: z.enum(["consumer", "corporate"]).optional()})}); export const sddRemittanceInfo = z.string().min(1).max(140); export const sddPaymentMethodDetails = z.object({type: paymentMethodType, display_hint: paymentMethodDisplayHint, remittance_info: sddRemittanceInfo, bank_account: z.object({type: z.enum(["business", "consumer"]), number: z.object({type: z.literal("iban"), value: z.string().min(15).max(33)})})}); export const paymentMethodDetails = z.discriminatedUnion("type", [cardPaymentMethodDetails, sddPaymentMethodDetails]); export const splitsType = z.literal("per_transaction"); export const splitsAccountType = z.enum(["platform", "seller", "other"]); export const accountId = z.string().min(30).max(50); export const accountVersion = z.string().min(1).max(50); export const accountLegalName = z.string().min(1).max(250); export const splitAmountMinor = z.number().int(); export const splitFixedAmount = z.object({type: z.enum(["fixed", "percentage", "remaining"]), amount: splitAmountMinor}); export const splitPercentageAmountCalculated = z.object({type: z.enum(["fixed", "percentage", "remaining"]), percentage: z.number().gte(0).lte(100).multipleOf(0.1), amount: splitAmountMinor}); export const splitRemainingAmountCalculated = z.object({type: z.enum(["fixed", "percentage", "remaining"]), amount: splitAmountMinor}); export const processingFeeAmount = z.number().int(); export const processingFeeCalculating = z.object({percentage: z.number().gte(0).lte(100).multipleOf(0.1), amount: processingFeeAmount.optional()}); export const paymentAuthentication = z.object({type: z.literal("3ds"), status: z.enum(["succeeded", "failed"]), result: z.object({code: z.enum(["Y", "A", "N", "U", "R"]).min(1).max(1), eci: z.enum(["05", "06", "07", "01", "02", "03"]).min(2).max(2)}).optional()}); export const standingInstructionId = z.string().min(30).max(50); export const standingInstructionStatus = z.enum(["new", "active"]); export const standingInstructionTerms = z.object({type: z.enum(["recurring", "unscheduled"])}); export const standingInstructionDetails = z.object({id: standingInstructionId.optional(), status: standingInstructionStatus, terms: standingInstructionTerms, first: z.object({type: z.literal("payment"), id: z.string().min(30).max(50)})}); export const refundId = z.string().min(30).max(50); export const refundStatus = z.enum(["initiated", "completed", "declined", "failed"]); export const refundReason = z.object({code: z.string(), description: z.string()}); export const refundType = z.enum(["full", "partial"]); export const refundOrigin = z.object({type: z.string()}); export const paymentRefunds = z.array(z.object({id: refundId, status: refundStatus, reason: refundReason.optional(), type: refundType, reference: reference, created_at: createdAt, updated_at: updatedAt, amount: amountMinor, origin: refundOrigin})); export const paymentTotals = z.object({net: z.number().int(), captured: z.number().int(), refunded: z.number().int(), refundable: z.number().int(), processing_fees: z.number().int(), accounts: z.array(z.object({type: z.enum(["seller", "platform"]), id: accountId, version: accountVersion, legal_name: accountLegalName, net: z.number().int(), captured: z.number().int(), refunded: z.number().int(), refundable: z.number().int(), processing_fees: z.number().int()}))}); export const getPaymentResponse = z.object({id: paymentId, status: paymentStatus, reason: paymentReason.optional(), reference: reference, created_at: createdAt, updated_at: updatedAt, estimated_update_before: estimatedUpdateBefore.optional(), amount: amountMinor, currency: currency, description: paymentCheckoutDescription.optional(), statement_descriptor: statementDescriptorResponse.optional(), origin: z.union([z.object({type: z.string()}), z.object({type: z.string(), id: checkoutId})]), method: paymentMethodDetails, splits: z.object({type: splitsType, accounts: z.array(z.object({type: splitsAccountType, id: accountId, version: accountVersion, legal_name: accountLegalName, split: z.discriminatedUnion("type", [splitFixedAmount, splitPercentageAmountCalculated, splitRemainingAmountCalculated]), processing_fee: processingFeeCalculating}))}), authentication: paymentAuthentication.optional(), standing_instruction: standingInstructionDetails.optional(), refunds: paymentRefunds, totals: paymentTotals}); 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 a payment * * GET /v2/payments/{payment_id} * * Also accepts auth: OAuth */ export const getApiV2PaymentsPaymentId = async (args: GetApiV2PaymentsPaymentIdArgs, options?: GetApiV2PaymentsPaymentIdOptions) => { const {baseUrl = "https://api.getpaid.io", fetch: fetchFn = fetch, OAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (OAuth !== undefined) headers.set('authorization', `Bearer ${OAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/v2/payments/${encodeURIComponent(String(args.payment_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(getPaymentResponse, await res.json()) };