File size: 5,059 Bytes
3e42e33
 
 
 
1a3a466
c96424b
3e42e33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a3a466
 
3e42e33
 
 
 
1a3a466
3e42e33
 
 
 
 
1a3a466
 
 
 
3e42e33
 
1a3a466
3e42e33
 
 
1a3a466
3e42e33
 
1a3a466
3e42e33
 
1a3a466
 
797987e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import logging
from typing import Optional
from datetime import datetime, timedelta
from fastapi import APIRouter, HTTPException, Query, Depends, status, Body
from app.models.merchant import MerchantRegister, GetOtpRequest
from app.services.merchant_services import generate_and_send_otp, get_otp_from_cache, verify_otp_and_save_merchant, validate_merchant


# Initialize router and logger
router = APIRouter(prefix="/merchant")
logger = logging.getLogger(__name__)



@router.post("/register")
async def register_customer(user: MerchantRegister = Body(...)):
    """
    API endpoint to register a new Merchant.

    Args:
        user (MerchantRegister): The details of the Merchant to register.

    Returns:
        dict: Confirmation message indicating email and SMS verification pending.
    """
    try:
        logger.info("Registering a new Merchant with Merchant name : %s, email: %s and mobile: %s", user.merchant_name, user.email, user.mobile)

        # Validate email and mobile format
        validation_result = await validate_merchant(user)
        if validation_result["status"] == "error":
            logger.error("Validation failed: %s", validation_result["errors"])
            raise HTTPException(status_code=400, detail=validation_result["errors"])       

        return user.dict()

    except HTTPException as e:
        logger.error("Failed to register merchant: %s", e.detail)
        raise e
    except Exception as e:
        logger.error("Unexpected error while registering merchant: %s", e)
        raise HTTPException(status_code=500, detail="Failed to register Merchant") from e
    
@router.post("/otp/verify")
async def customer_otp_verification(user: MerchantRegister = Body(...)):
    """
    API endpoint to validate OTPs and save the complete Merchant object.

    Args:
        user (MerchantRegister): The complete Merchant object including email, mobile, and OTPs.

    Returns:
        dict: Confirmation message indicating success or failure.
    """
    try:
        logger.info("Verifying OTPs and registering merchant with email: %s and mobile: %s", user.email, user.mobile)
         # Verify OTPs and save customer
        result = await verify_otp_and_save_merchant(user)
        if result["status"] == "error":
            raise HTTPException(status_code=400, detail=result["errors"])

        return {"message": "Merchant successfully registered and verified."}

    except HTTPException as e:
        logger.error("Failed to verify and register merchant: %s", e.detail)
        raise e
    except Exception as e:
        logger.error("Unexpected error while verifying and registering merchant: %s", e)
        raise HTTPException(status_code=500, detail="Failed to verify and register merchant") from e

@router.post("/otp/get")
async def get_otps(payload: GetOtpRequest):
    """
    API endpoint to retrieve the email or SMS OTP from Redis cache.

    Args:
        payload (GetOtpRequest): The request payload containing the identifier and type.

    Returns:
        dict: The OTP data if found, or an error message if not found.
    """
    try:
        logger.info("Retrieving OTP for identifier: %s, type: %s", payload.identifier, payload.type)

        # Construct the Redis key based on the type
        redis_key = f"otp:{payload.type}:{payload.identifier}"

        # Retrieve OTP from Redis
        otp_data = await get_otp_from_cache(redis_key)
        if not otp_data:
            raise HTTPException(status_code=404, detail="OTP not found or expired")

        return {"identifier": payload.identifier, "type": payload.type, "otp_data": otp_data}

    except HTTPException as e:
        logger.error("Failed to retrieve OTP for identifier %s, type %s: %s", payload.identifier, payload.type, e.detail)
        raise e
    except Exception as e:
        logger.error("Unexpected error while retrieving OTP for identifier %s, type %s: %s", payload.identifier, payload.type, e)
        raise HTTPException(status_code=500, detail="Failed to retrieve OTP") from e

@router.post("/otp/regenerate")
async def regenerate_otp(user: MerchantRegister = Body(...)):
    """
    API endpoint to regenerate an OTP for a given email, mobile number, or both.

    Args:
        user (MerchantRegister): The Merchant object containing email and mobile details.

    Returns:
        dict: Confirmation message indicating the OTP has been regenerated.
    """
    try:
        logger.info("Regenerating OTP for Merchant with email: %s and mobile: %s", user.email, user.mobile)

        # Regenerate OTP for email & mobile
        if user.email and user.mobile:
            await generate_and_send_otp(user.email, user.mobile)       

        return {"message": "OTP successfully regenerated for email and/or mobile.", "email": user.email, "mobile": user.mobile}

    except Exception as e:
        logger.error("Failed to regenerate OTP for Merchant with email: %s and mobile: %s. Error: %s", user.email, user.mobile, e)
        raise HTTPException(status_code=500, detail="Failed to regenerate OTP") from e