import {z} from 'zod' export type Donation = {amount?: number | undefined, organizationId?: string | undefined}; export type Delivery = {street?: string | undefined, postalBox?: string | undefined, postalCode?: string | undefined, city?: string | undefined, state?: string | undefined, countryCode?: string | undefined, name?: string | undefined, recipientName?: string | undefined, recipientEmail?: string | undefined, recipientPhone?: string | undefined}; export type Buyer = {extCustomerId?: string | undefined, email?: string | undefined, phone?: string | undefined, firstName?: string | undefined, lastName?: string | undefined, nin?: string | undefined, language?: string | undefined, birthDate?: unknown | undefined, delivery?: Delivery | undefined}; export type ShippingMethods = Array<{country: string, price: number, name: string}>; export type Products = Array<{name: string, unitPrice: string, quantity: string, virtual?: boolean | undefined}>; export type ShoppingCarts = Array<{extCustomerId: string, amount: number, fee?: string | undefined, shippingMethods?: ShippingMethods | undefined, products: Products}>; export type ClickToPayVisa = {srcCorrelationId: string}; export type ClickToPayMastercard = {srcCorrelationId: string, srcDigitalCardId: string}; export type ClickToPay = {visa: ClickToPayVisa} | {mastercard: ClickToPayMastercard}; export type CardPlainData = {number?: string | undefined, expirationMonth?: string | undefined, expirationYear?: string | undefined, cvv?: string | undefined, firstTransactionId?: string | undefined, schemeTransactionId?: string | undefined}; export type SpecificData = Array<{name?: string | undefined, value?: string | undefined}>; export type BlikData = {aliasLabelProposal?: string | undefined, registerTokenValue?: string | undefined, register?: boolean | undefined, appKey?: string | undefined, recommendedAuthLevel?: ('NO_CONFIRMATION' | 'REQUIRED_CONFIRMATION') | undefined, countryCode?: ('PL' | 'SK') | undefined, recurring?: ({type: 'O', initializationDate?: unknown | undefined, expirationDate?: unknown | undefined, authorizeDespiteRecurringNotSupported?: boolean | undefined}) | undefined}; export type ThreeDsData = {status3Ds: 'Y' | 'A', status3DsDescription?: string | undefined, xid?: string | undefined, dsTransactionId: string, eciCode: unknown, cavv?: string | undefined, tavv?: string | undefined}; export type PayMethod = {type: 'PBL' | 'CARD_TOKEN' | 'PAYMENT_WALL' | 'BLIK_AUTHORIZATION_CODE' | 'BLIK_TOKEN' | 'TRANSPARENT', value: string, clickToPay?: ClickToPay | undefined, authorizationCode?: string | undefined, authorizationType?: ('PRE_AUTHORIZATION' | 'AUTHORIZATION') | undefined, card?: CardPlainData | undefined, specificData?: SpecificData | undefined, amount?: string | undefined, blikData?: BlikData | undefined, threeDsData?: ThreeDsData | undefined, sourcePaymentFlow?: ('APPLE_PAY' | 'CARDS' | 'MDES' | 'GOOGLE_PAY' | 'VISA_MOBILE' | 'VTS') | undefined, cardInstallments?: ({provider?: string | undefined, number?: number | undefined}) | undefined}; export type PayMethods = {payMethod?: PayMethod | undefined}; export type McpData = {mcpCurrency: string, mcpAmount: string, mcpRate: string, mcpFxTableId: string, mcpPartnerId: string}; export type Exemption = {value: 'LOW_RISK' | 'LOW_VALUE', rejectionHandling: 'PERFORM_AUTHENTICATION' | 'DECLINE', riskScore?: string | undefined}; export type Browser = {acceptHeaders: string, requestIP: string, screenWidth: string, javaEnabled: boolean, timezoneOffset: string, screenHeight: string, userAgent: string, colorDepth: string, language: string}; export type SdkEphemPubKey = {y?: string | undefined, x?: string | undefined, kty?: string | undefined, crv?: string | undefined}; export type Sdk = {sdkReferenceNumber: string, sdkMaxTimeout: string, sdkAppID: string, sdkEncData: string, sdkTransID: string, sdkEphemPubKey: SdkEphemPubKey}; export type MerchantFunds = {amount: string, currencyCode: string}; export type MerchantRiskIndicator = {orderType?: ('PURCHASE' | 'ACC_FUNDING' | 'LOAN') | undefined, shipIndicator?: ('BILLING_ADDRESS' | 'VERIFIED_ADDRESS' | 'OTHER_ADDRESS' | 'SHIP_TO_STORE' | 'DIGITAL_GOODS' | 'TICKETS' | 'NOT_SHIPPED') | undefined, preOrdered?: boolean | undefined, preOrderedDate?: unknown | undefined, deliveryTimeFrame?: ('ELECTRONIC' | 'SAME_DAY' | 'OVERNIGHT' | 'TWO_OR_MORE_DAYS') | undefined, reordered?: boolean | undefined, merchantFunds?: MerchantFunds | undefined}; export type Recurring = {frequency?: string | undefined, expiry?: unknown | undefined}; export type AccountInformation = {createDate?: unknown | undefined, suspiciousActivity?: boolean | undefined, deliveryAddressFirstUsedDate?: unknown | undefined, deliveryAdressUsageIndicator?: ('THIS_TRANSACTION' | 'LESS_THAN_30_DAYS' | '30_TO_60_DAYS' | 'MORE_THAN_60_DAYS') | undefined, pastOrdersYear?: number | undefined, pastOrdersDay?: number | undefined, purchasesLastSixMonths?: number | undefined, changeDate?: unknown | undefined, changeIndicator?: ('THIS_TRANSACTION' | 'LESS_THAN_30_DAYS' | '30_TO_60_DAYS' | 'MORE_THAN_60_DAYS') | undefined, passwordChanged?: unknown | undefined, passwordChangeIndicator?: ('NO_CHANGE' | 'THIS_TRANSACTION' | 'LESS_THAN_30_DAYS' | '30_TO_60_DAYS' | 'MORE_THAN_60_DAYS') | undefined, nameToRecipientMatch?: boolean | undefined, addCardAttemptsDay?: string | undefined, authMethod?: ('GUEST' | 'LOGIN' | 'FEDERATED_ID' | 'THIRD_PARTY' | 'ISSUER' | 'FIDO') | undefined, authDateTime?: unknown | undefined, cardAddedDate?: unknown | undefined, cardAddedIndicator?: ('GUEST' | 'THIS_TRANSACTION' | 'LESS_THAN_30_DAYS' | '30_TO_60_DAYS' | 'MORE_THAN_60_DAYS') | undefined}; export type BillingAddress = {street?: string | undefined, postalCode?: string | undefined, city?: string | undefined, state?: string | undefined, countryCode?: string | undefined}; export type Cardholder = {name?: string | undefined, accountInformation?: AccountInformation | undefined, billingAddress?: BillingAddress | undefined}; export type ThreeDsAuthentication = {challengeRequested?: ('YES' | 'NO' | 'MANDATE') | undefined, exemption?: Exemption | undefined, browser?: Browser | undefined, sdk?: Sdk | undefined, merchantRiskIndicator?: MerchantRiskIndicator | undefined, recurring?: Recurring | undefined, cardholder?: Cardholder | undefined}; export type RiskData = {browser: Browser}; export type Address = {pointId?: string | undefined, street?: string | undefined, streetNo?: string | undefined, flatNo?: string | undefined, postalCode?: string | undefined, city?: string | undefined, countryCode?: string | undefined}; export type ShippingMethod = {type?: ('COURIER' | 'COLLECTION_POINT_PICKUP' | 'PARCEL_LOCKER' | 'STORE_PICKUP') | undefined, price?: string | undefined, address?: Address | undefined}; export type ShoppingCart = Array<{shippingMethod?: ShippingMethod | undefined, products?: (Array<{name?: string | undefined, unitPrice?: string | undefined, quantity?: string | undefined, virtual?: boolean | undefined, listingDate?: unknown | undefined}>) | undefined, extCustomerId?: string | undefined}>; export type Credit = {shoppingCarts?: ShoppingCart | undefined, applicant?: ({email?: string | undefined, phone?: string | undefined, firstName?: string | undefined, lastName?: string | undefined, language?: string | undefined, nin?: string | undefined, address?: ({street?: string | undefined, streetNo?: string | undefined, flatNo?: string | undefined, postalCode?: string | undefined, city?: string | undefined, countryCode?: string | undefined}) | undefined, additionalInfo?: ({hasSuccessfullyFinishedOrderInShop?: string | undefined}) | undefined}) | undefined, klarnaAttachment?: ({content_type?: string | undefined, body?: string | undefined}) | undefined}; export type Submerchant = {id?: string | undefined}; export type With = 'authorization' | 'buyer' | 'capture' | 'fees' | 'payMethod' | 'mcp'; export type Settings = {cardInstallmentsOptions?: {[key: string]: Array} | undefined, syncProcessing?: boolean | undefined, enrichNotificationWith?: Array | undefined}; export type CreateApiApiV21OrdersArgs = {'Content-Type': string, Authorization: string, body: {continueUrl?: unknown | undefined, notifyUrl?: unknown | undefined, customerIp: string, merchantPosId: string, description: string, additionalDescription?: string | undefined, visibleDescription?: string | undefined, statementDescription?: string | undefined, extOrderId?: string | undefined, currencyCode: string, totalAmount: string, validityTime?: string | undefined, cardOnFile?: ('FIRST' | 'STANDARD_CARDHOLDER' | 'STANDARD_MERCHANT') | undefined, recurring?: ('FIRST' | 'STANDARD') | undefined, donation?: Donation | undefined, buyer?: Buyer | undefined, shoppingCarts?: ShoppingCarts | undefined, products: Products, payMethods?: PayMethods | undefined, mcpData?: McpData | undefined, threeDsAuthentication?: ThreeDsAuthentication | undefined, riskData?: RiskData | undefined, credit?: Credit | undefined, submerchant?: Submerchant | undefined, settings?: Settings | undefined, deviceFingerprint?: string | undefined}}; export type CreateApiApiV21OrdersOptions = {baseUrl?: string | undefined, Bearer?: string | undefined, fetch?: typeof fetch | undefined}; export const createApiApiV21OrdersResponse = z.union([z.object({status: z.object({statusCode: z.string().optional()}).optional(), orderId: z.string().optional(), extOrderId: z.string().optional()}), z.object({status: z.object({statusCode: z.string().optional(), severity: z.string().optional()}).optional(), orderId: z.string().optional(), extOrderId: z.string().optional(), qrCode: z.string().optional()}), z.object({status: z.object({statusCode: z.string().optional()}).optional(), orderId: z.string().optional(), extOrderId: z.string().optional(), authorization: z.object({amount: z.string().optional(), status: z.enum(["AUTHORIZED", "SOFT_DECLINED", "REJECTED", "PENDING"]).optional(), currencyCode: z.string().optional(), responseCode: z.string().optional(), responseCodeDescription: z.string().optional(), validUntil: z.string().optional(), card: z.object({maskedNumber: z.string().optional(), scheme: z.string().optional(), issuerName: z.string().optional(), countryCode: z.string().optional(), classification: z.string().optional(), profile: 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 }; /** * Create an Order * * POST /api/v2_1/orders */ export const createApiApiV21Orders = async (args: CreateApiApiV21OrdersArgs, options?: CreateApiApiV21OrdersOptions) => { const {baseUrl = "https://secure.payu.com", fetch: fetchFn = fetch, Bearer} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args['Content-Type'] != null) headers.set("Content-Type", String(args['Content-Type'])) if (args.Authorization != null) headers.set("Authorization", String(args.Authorization)) if (Bearer !== undefined) headers.set('authorization', `Bearer ${Bearer}`) const url = `${baseUrl.replace(/\/+$/, '')}/api/v2_1/orders${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(createApiApiV21OrdersResponse, await res.json()) };