package handlers import ( "errors" "net/http" apperrors "veza-backend-api/internal/errors" "veza-backend-api/internal/services" "github.com/gin-gonic/gin" "go.uber.org/zap" ) // KYCHandler handles seller identity verification endpoints (v0.13.5 TASK-MKT-001) type KYCHandler struct { kycService *services.KYCService logger *zap.Logger } // NewKYCHandler creates a new KYC handler func NewKYCHandler(kycService *services.KYCService, logger *zap.Logger) *KYCHandler { return &KYCHandler{ kycService: kycService, logger: logger, } } // CreateVerificationRequest is the request body for starting KYC type CreateVerificationRequest struct { ReturnURL string `json:"return_url"` } // StartVerification creates a Stripe Identity verification session func (h *KYCHandler) StartVerification(c *gin.Context) { if h.kycService == nil { RespondWithAppError(c, apperrors.NewServiceUnavailableError("KYC verification is not available")) return } userID, ok := GetUserIDUUID(c) if !ok { return } var req CreateVerificationRequest _ = c.ShouldBindJSON(&req) returnURL := req.ReturnURL if returnURL == "" { returnURL = c.Request.URL.Scheme + "://" + c.Request.Host + "/sell?kyc=complete" } session, err := h.kycService.CreateVerificationSession(c.Request.Context(), userID, returnURL) if err != nil { if errors.Is(err, services.ErrKYCAlreadyDone) { RespondSuccess(c, http.StatusOK, gin.H{"status": "verified", "message": "Already verified"}) return } if errors.Is(err, services.ErrKYCNotAvailable) { RespondWithAppError(c, apperrors.NewServiceUnavailableError("KYC verification is not available")) return } if errors.Is(err, services.ErrNoStripeAccount) { RespondWithAppError(c, apperrors.NewValidationError("Complete Stripe Connect onboarding first")) return } h.logger.Error("StartVerification failed", zap.Error(err), zap.String("user_id", userID.String())) RespondWithAppError(c, apperrors.NewInternalErrorWrap("Failed to start verification", err)) return } RespondSuccess(c, http.StatusCreated, session) } // GetVerificationStatus returns the current KYC status for a seller func (h *KYCHandler) GetVerificationStatus(c *gin.Context) { if h.kycService == nil { RespondSuccess(c, http.StatusOK, gin.H{"status": "not_available"}) return } userID, ok := GetUserIDUUID(c) if !ok { return } status, err := h.kycService.GetVerificationStatus(c.Request.Context(), userID) if err != nil { if errors.Is(err, services.ErrKYCNotAvailable) { RespondSuccess(c, http.StatusOK, gin.H{"status": "not_available"}) return } h.logger.Error("GetVerificationStatus failed", zap.Error(err), zap.String("user_id", userID.String())) RespondWithAppError(c, apperrors.NewInternalErrorWrap("Failed to get verification status", err)) return } RespondSuccess(c, http.StatusOK, gin.H{"status": status}) }