package handlers // import ( // "Yimaru-Backend/internal/domain" // "github.com/gofiber/fiber/v2" // ) // // CreateCheckoutSessionHandler initializes a checkout session with Arifpay. // // // // @Summary Create Arifpay Checkout Session // // @Description Creates a payment session using Arifpay and returns a redirect URL. // // @Tags Arifpay // // @Accept json // // @Produce json // // @Param request body domain.CheckoutSessionClientRequest true "Checkout session request payload" // // @Success 200 {object} domain.Response // // @Failure 400 {object} domain.ErrorResponse // // @Failure 500 {object} domain.ErrorResponse // // @Router /api/v1/arifpay/checkout [post] // func (h *Handler) CreateCheckoutSessionHandler(c *fiber.Ctx) error { // userId, ok := c.Locals("user_id").(int64) // if !ok { // return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{ // Error: "missing user id", // Message: "Unauthorized", // }) // } // var req domain.CheckoutSessionClientRequest // if err := c.BodyParser(&req); err != nil { // return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Failed to process your request", // }) // } // data, err := h.arifpaySvc.CreateCheckoutSession(req, true, userId) // if err != nil { // return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Failed to process your request", // }) // } // return c.Status(fiber.StatusOK).JSON(domain.Response{ // Message: "Checkout session created successfully", // Data: data, // Success: true, // StatusCode: fiber.StatusOK, // }) // } // // CancelCheckoutSessionHandler cancels an existing Arifpay checkout session. // // // // @Summary Cancel Arifpay Checkout Session // // @Description Cancels a payment session using Arifpay before completion. // // @Tags Arifpay // // @Accept json // // @Produce json // // @Param sessionId path string true "Checkout session ID" // // @Success 200 {object} domain.Response // // @Failure 400 {object} domain.ErrorResponse // // @Failure 500 {object} domain.ErrorResponse // // @Router /api/v1/arifpay/checkout/cancel/{sessionId} [post] // func (h *Handler) CancelCheckoutSessionHandler(c *fiber.Ctx) error { // sessionID := c.Params("sessionId") // if sessionID == "" { // return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ // Error: "missing session ID", // Message: "Session ID is required", // }) // } // data, err := h.arifpaySvc.CancelCheckoutSession(c.Context(), sessionID) // if err != nil { // return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Failed to cancel checkout session", // }) // } // return c.Status(fiber.StatusOK).JSON(domain.Response{ // Message: "Checkout session canceled successfully", // Data: data, // Success: true, // StatusCode: fiber.StatusOK, // }) // } // // HandleWebhook processes Arifpay webhook notifications. // // // // @Summary Handle Arifpay C2B Webhook // // @Description Handles webhook notifications from Arifpay for C2B transfers and updates transfer + wallet status. // // @Tags Arifpay // // @Accept json // // @Produce json // // @Param request body domain.WebhookRequest true "Arifpay webhook payload" // // @Success 200 {object} domain.Response // // @Failure 400 {object} domain.ErrorResponse // // @Failure 500 {object} domain.ErrorResponse // // @Router /api/v1/arifpay/c2b-webhook [post] // func (h *Handler) HandleArifpayC2BWebhook(c *fiber.Ctx) error { // var req domain.WebhookRequest // if err := c.BodyParser(&req); err != nil { // return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Invalid webhook payload", // }) // } // // 🚨 Decide how to get userId: // // If you get it from auth context/middleware, extract it here. // // For now, let's assume userId comes from your auth claims: // // userId, ok := c.Locals("user_id").(int64) // // if !ok { // // return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{ // // Error: "missing user id", // // Message: "Unauthorized", // // }) // // } // err := h.arifpaySvc.ProcessWebhook(c.Context(), req, true) // if err != nil { // return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Failed to process webhook", // }) // } // return c.Status(fiber.StatusOK).JSON(domain.Response{ // Message: "Webhook processed successfully", // Success: true, // StatusCode: fiber.StatusOK, // }) // } // // HandleWebhook processes Arifpay webhook notifications. // // // // @Summary Handle Arifpay B2C Webhook // // @Description Handles webhook notifications from Arifpay for B2C transfers and updates transfer + wallet status. // // @Tags Arifpay // // @Accept json // // @Produce json // // @Param request body domain.WebhookRequest true "Arifpay webhook payload" // // @Success 200 {object} domain.Response // // @Failure 400 {object} domain.ErrorResponse // // @Failure 500 {object} domain.ErrorResponse // // @Router /api/v1/arifpay/b2c-webhook [post] // func (h *Handler) HandleArifpayB2CWebhook(c *fiber.Ctx) error { // var req domain.WebhookRequest // if err := c.BodyParser(&req); err != nil { // return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Invalid webhook payload", // }) // } // // 🚨 Decide how to get userId: // // If you get it from auth context/middleware, extract it here. // // For now, let's assume userId comes from your auth claims: // // userId, ok := c.Locals("user_id").(int64) // // if !ok { // // return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{ // // Error: "missing user id", // // Message: "Unauthorized", // // }) // // } // err := h.arifpaySvc.ProcessWebhook(c.Context(), req, false) // if err != nil { // return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Failed to process webhook", // }) // } // return c.Status(fiber.StatusOK).JSON(domain.Response{ // Message: "Webhook processed successfully", // Success: true, // StatusCode: fiber.StatusOK, // }) // } // // ArifpayVerifyByTransactionIDHandler godoc // // @Summary Verify Arifpay Transaction // // @Description Verifies a transaction using transaction ID and payment type // // @Tags Arifpay // // @Accept json // // @Produce json // // @Param request body domain.ArifpayVerifyByTransactionIDRequest true "Transaction verification payload" // // @Success 200 {object} domain.Response // // @Failure 400 {object} domain.ErrorResponse // // @Failure 502 {object} domain.ErrorResponse // // @Router /api/v1/arifpay/transaction-id/verify-transaction [post] // func (h *Handler) ArifpayVerifyByTransactionIDHandler(c *fiber.Ctx) error { // var req domain.ArifpayVerifyByTransactionIDRequest // if err := c.BodyParser(&req); err != nil { // return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Failed to parse request body", // }) // } // resp, err := h.arifpaySvc.VerifyTransactionByTransactionID(c.Context(), req) // if err != nil { // return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Failed to verify transaction", // }) // } // return c.Status(fiber.StatusOK).JSON(domain.Response{ // Message: "Transaction verified successfully", // Data: resp, // Success: true, // StatusCode: fiber.StatusOK, // }) // } // // ArifpayVerifyBySessionIDHandler godoc // // @Summary Verify Arifpay Transaction by Session ID // // @Description Verifies an Arifpay transaction using a session ID // // @Tags Arifpay // // @Accept json // // @Produce json // // @Param session_id query string true "Arifpay Session ID" // // @Success 200 {object} domain.Response // // @Failure 400 {object} domain.ErrorResponse // // @Failure 502 {object} domain.ErrorResponse // // @Router /api/v1/arifpay/session-id/verify-transaction/{session_id} [get] // func (h *Handler) ArifpayVerifyBySessionIDHandler(c *fiber.Ctx) error { // sessionID := c.Query("session_id") // if sessionID == "" { // return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ // Error: "missing session_id", // Message: "session_id query parameter is required", // }) // } // resp, err := h.arifpaySvc.VerifyTransactionBySessionID(c.Context(), sessionID) // if err != nil { // return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ // Error: err.Error(), // Message: "Failed to verify transaction", // }) // } // return c.Status(fiber.StatusOK).JSON(domain.Response{ // Message: "Transaction verified successfully", // Data: resp, // Success: true, // StatusCode: fiber.StatusOK, // }) // } // // ExecuteTransfer handles B2C transfers via Telebirr, CBE, or MPESA. // // // // @Summary Execute B2C Transfer // // @Description Initiates a B2C transfer using Telebirr, CBE, or MPESA depending on the "type" query parameter // // @Tags Arifpay // // @Accept json // // @Produce json // // @Param type query string true "Transfer type (telebirr, cbe, mpesa)" // // @Param request body domain.CheckoutSessionClientRequest true "Transfer request payload" // // @Success 200 {object} map[string]string "message: transfer executed successfully" // // @Failure 400 {object} map[string]string "error: invalid request or unsupported transfer type" // // @Failure 500 {object} map[string]string "error: internal server error" // // @Router /api/v1/arifpay/b2c/transfer [post] // func (h *Handler) ExecuteArifpayB2CTransfer(c *fiber.Ctx) error { // transferType := c.Query("type") // if transferType == "" { // return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ // Message: "Failed to process your withdrawal request", // Error: "missing query parameter: type (telebirr, cbe, mpesa)", // }) // } // userId, ok := c.Locals("user_id").(int64) // if !ok { // return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{ // Error: "missing user id", // Message: "Unauthorized", // }) // } // var req domain.CheckoutSessionClientRequest // if err := c.BodyParser(&req); err != nil { // return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ // Message: "Failed to process your withdrawal request", // Error: "invalid request body", // }) // } // var err error // switch transferType { // case "telebirr": // err = h.arifpaySvc.ExecuteTelebirrB2CTransfer(c.Context(), req, userId) // case "cbe": // err = h.arifpaySvc.ExecuteCBEB2CTransfer(c.Context(), req, userId) // case "mpesa": // err = h.arifpaySvc.ExecuteMPesaB2CTransfer(c.Context(), req, userId) // default: // return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ // Message: "Failed to process your withdrawal request", // Error: "unsupported transfer type, must be one of: telebirr, cbe, mpesa", // }) // } // if err != nil { // return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{ // Message: "Failed to process your withdrawal request", // Error: err.Error(), // }) // } // return c.Status(fiber.StatusOK).JSON(domain.Response{ // Message: "Withdrawal process initiated successfully", // Success: true, // StatusCode: fiber.StatusOK, // }) // } // // GetPaymentMethodsHandler returns the list of all Arifpay payment methods // // // // @Summary List Arifpay Payment Methods // // @Description Returns all payment method IDs and names for Arifpay // // @Tags Arifpay // // @Produce json // // @Success 200 {object} []domain.ARIFPAYPaymentMethod // // @Router /api/v1/arifpay/payment-methods [get] // func (h *Handler) GetArifpayPaymentMethodsHandler(c *fiber.Ctx) error { // methods := h.arifpaySvc.GetPaymentMethodsMapping() // return c.Status(fiber.StatusOK).JSON(domain.Response{ // Success: true, // Message: "Arifpay payment methods fetched successfully", // Data: methods, // StatusCode: fiber.StatusOK, // }) // }