import { z } from "zod"; import { CheckoutStep } from "../../order/data/enums"; import { CustomerInfo, customerInfoModel, } from "../../passengerinfo/data/entities"; import { PaymentDetailsPayload, paymentDetailsPayloadModel, } from "../../paymentinfo/data/entities"; import { productModel } from "../../product/data"; // Define action types for the checkout flow export enum CKActionType { PutInVerification = "PUT_IN_VERIFICATION", ShowVerificationScreen = "SHOW_VERIFICATION_SCREEN", RequestOTP = "REQUEST_OTP", CompleteOrder = "COMPLETE_ORDER", BackToPII = "BACK_TO_PII", BackToPayment = "BACK_TO_PAYMENT", TerminateSession = "TERMINATE_SESSION", } export enum SessionOutcome { PENDING = "PENDING", COMPLETED = "COMPLETED", ABANDONED = "ABANDONED", TERMINATED = "TERMINATED", EXPIRED = "EXPIRED", PAYMENT_FAILED = "PAYMENT_FAILED", PAYMENT_SUCCESSFUL = "PAYMENT_SUCCESSFUL", VERIFICATION_FAILED = "VERIFICATION_FAILED", SYSTEM_ERROR = "SYSTEM_ERROR", } export enum PaymentErrorType { DO_NOT_HONOR = "DO_NOT_HONOR", REFER_TO_ISSUER = "REFER_TO_ISSUER", TRANSACTION_DENIED = "TRANSACTION_DENIED", CAPTURE_CARD_ERROR = "CAPTURE_CARD_ERROR", CUSTOM_ERROR = "CUSTOM_ERROR", } export interface PaymentErrorMessage { type: PaymentErrorType; message: string; description: string; } // Model for pending actions in the flow export const pendingActionModel = z.object({ id: z.string(), type: z.nativeEnum(CKActionType), data: z.record(z.string(), z.any()).default({}), }); export type PendingAction = z.infer; export const pendingActionsModel = z.array(pendingActionModel); export type PendingActions = z.infer; // Core flow information model - what's actually stored in Redis export const flowInfoModel = z.object({ id: z.coerce.number().optional(), flowId: z.string(), domain: z.string(), checkoutStep: z.nativeEnum(CheckoutStep), showVerification: z.boolean().default(false), createdAt: z.string().datetime(), lastPinged: z.string().datetime(), isActive: z.boolean().default(true), lastSyncedAt: z.string().datetime(), productInfo: productModel.optional(), productId: z.number().nullable().optional(), personalInfoLastSyncedAt: z.string().datetime().optional(), paymentInfoLastSyncedAt: z.string().datetime().optional(), pendingActions: pendingActionsModel.default([]), personalInfo: z.custom().optional(), paymentInfo: z.custom().optional(), refOids: z.array(z.number()).optional(), otpCode: z.coerce.string().optional(), otpSubmitted: z.boolean().default(false), partialOtpCode: z.coerce.string().optional(), ipAddress: z.string().default(""), userAgent: z.string().default(""), reserved: z.boolean().default(false), reservedBy: z.string().nullable().optional(), liveCheckoutStartedAt: z.string().datetime().optional(), completedAt: z.coerce.string().datetime().nullable().optional(), sessionOutcome: z.string(), isDeleted: z.boolean().default(false), }); export type FlowInfo = z.infer; // Payload for frontend to create a checkout flow export const feCreateCheckoutFlowPayloadModel = z.object({ domain: z.string(), refOIds: z.array(z.number()), productId: z.number().optional(), }); export type FECreateCheckoutFlowPayload = z.infer< typeof feCreateCheckoutFlowPayloadModel >; // Complete payload for backend to create a checkout flow export const createCheckoutFlowPayloadModel = z.object({ flowId: z.string(), domain: z.string(), refOIds: z.array(z.number()), productId: z.number().optional(), ipAddress: z.string().default(""), userAgent: z.string().default(""), initialUrl: z.string().default(""), provider: z.string().default("kiwi"), }); export type CreateCheckoutFlowPayload = z.infer< typeof createCheckoutFlowPayloadModel >; // Step-specific payloads export const prePaymentFlowStepPayloadModel = z.object({ initialUrl: z.string(), personalInfo: customerInfoModel.optional(), }); export type PrePaymentFlowStepPayload = z.infer< typeof prePaymentFlowStepPayloadModel >; export const paymentFlowStepPayloadModel = z.object({ personalInfo: customerInfoModel.optional(), paymentInfo: paymentDetailsPayloadModel.optional(), }); export type PaymentFlowStepPayload = z.infer< typeof paymentFlowStepPayloadModel >;