139 lines
4.3 KiB
TypeScript
139 lines
4.3 KiB
TypeScript
import { z } from "zod";
|
|
import { CustomerInfoModel, customerInfoModel } from "../../customerinfo/data";
|
|
import { CheckoutStep } from "../../order/data/enums";
|
|
import {
|
|
PaymentInfoPayload,
|
|
paymentInfoPayloadModel,
|
|
} 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<typeof pendingActionModel>;
|
|
|
|
export const pendingActionsModel = z.array(pendingActionModel);
|
|
export type PendingActions = z.infer<typeof pendingActionsModel>;
|
|
|
|
// 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<CustomerInfoModel>().optional(),
|
|
paymentInfo: z.custom<PaymentInfoPayload>().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<typeof flowInfoModel>;
|
|
|
|
// 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: paymentInfoPayloadModel.optional(),
|
|
});
|
|
export type PaymentFlowStepPayload = z.infer<
|
|
typeof paymentFlowStepPayloadModel
|
|
>;
|