from pydantic import BaseModel, Field from typing import Optional, List from decimal import Decimal from datetime import datetime class BaseResponse(BaseModel): code: int message: str payload: Optional[dict] = None ### Constants class PaymentMethod: CASH = "cash" MPESA = "mpesa" LIPA_NUMBER = "lipa_number" CREDIT_CARD = "credit_card" CHOICES = [CASH, MPESA, LIPA_NUMBER, CREDIT_CARD] class PaymentStatus: ADDED_TO_BALANCE = "Added to balance" PURCHASED_PLAN = "Purchased plan" PENDING = "PENDING" class CreatePaymentRequest(BaseModel): user_id: Optional[str] = Field( None, description="ID of the user making the payment" ) plan_id: Optional[str] = Field( None, description="ID of the plan associated with the payment" ) amount: Decimal = Field(..., description="Payment amount") payment_method: str = Field( ..., description="Method of payment", example=PaymentMethod.CASH ) transaction_id: Optional[str] = Field( None, description="Unique transaction ID (for methods like Lipa Number)" ) class UpdatePaymentStatusRequest(BaseModel): status: str = Field( ..., description="Status of the payment (e.g., pending, completed, failed)" ) class PaymentResponse(BaseModel): id: str user_id: Optional[str] plan_id: Optional[str] amount: Decimal payment_method: str status: str transaction_id: Optional[str] created_time: datetime updated_time: datetime class Config: from_attributes = True class PaymentListResponse(BaseModel): payments: List[PaymentResponse] total_count: int class Config: from_attributes = True class UpdatePaymentUserRequest(BaseModel): user_id: str = Field( ..., description="ID of the user to link or update for this payment" )