Yimaru-BackEnd/internal/web_server/handlers/arifpay.go

343 lines
13 KiB
Go

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,
// })
// }