package handlers import ( "bytes" "encoding/json" "fmt" "io" "net/http" // "github.com/SamuelTariku/FortuneBet-Backend/internal/config" "github.com/gofiber/fiber/v2" ) var ( ChapaSecret string ChapaBaseURL string ) type InitPaymentRequest struct { Amount string `json:"amount"` Currency string `json:"currency"` Email string `json:"email"` FirstName string `json:"first_name"` LastName string `json:"last_name"` TxRef string `json:"tx_ref"` CallbackURL string `json:"callback_url"` ReturnURL string `json:"return_url"` } type TransferRequest struct { AccountNumber string `json:"account_number"` BankCode string `json:"bank_code"` Amount string `json:"amount"` Currency string `json:"currency"` Reference string `json:"reference"` Reason string `json:"reason"` RecipientName string `json:"recipient_name"` } func (h *Handler) GetBanks(c *fiber.Ctx) error { httpReq, err := http.NewRequest("GET", h.Cfg.CHAPA_BASE_URL+"/banks", nil) // log.Printf("\n\nbase url is: %v\n\n", h.Cfg.CHAPA_BASE_URL) if err != nil { return c.Status(500).JSON(fiber.Map{"error": "Failed to create request", "details": err.Error()}) } httpReq.Header.Set("Authorization", "Bearer "+h.Cfg.CHAPA_SECRET_KEY) resp, err := http.DefaultClient.Do(httpReq) if err != nil { return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch banks", "details": err.Error()}) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return c.Status(500).JSON(fiber.Map{"error": "Failed to read response", "details": err.Error()}) } return c.Status(resp.StatusCode).Send(body) } func (h *Handler) InitializePayment(c *fiber.Ctx) error { var req InitPaymentRequest if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid request body", "details": err.Error(), }) } payload, err := json.Marshal(req) if err != nil { return c.Status(500).JSON(fiber.Map{ "error": "Failed to serialize request", "details": err.Error(), }) } httpReq, err := http.NewRequest("POST", h.Cfg.CHAPA_BASE_URL+"/transaction/initialize", bytes.NewBuffer(payload)) if err != nil { return c.Status(500).JSON(fiber.Map{ "error": "Failed to create request", "details": err.Error(), }) } httpReq.Header.Set("Authorization", "Bearer "+h.Cfg.CHAPA_SECRET_KEY) httpReq.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(httpReq) if err != nil { return c.Status(500).JSON(fiber.Map{ "error": "Failed to initialize payment", "details": err.Error(), }) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return c.Status(500).JSON(fiber.Map{ "error": "Failed to read response", "details": err.Error(), }) } return c.Status(resp.StatusCode).Send(body) } func (h *Handler) VerifyTransaction(c *fiber.Ctx) error { txRef := c.Params("tx_ref") if txRef == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Missing transaction reference", }) } url := fmt.Sprintf("%s/transaction/verify/%s", h.Cfg.CHAPA_BASE_URL, txRef) httpReq, err := http.NewRequest("GET", url, nil) if err != nil { return c.Status(500).JSON(fiber.Map{ "error": "Failed to create request", "details": err.Error(), }) } httpReq.Header.Set("Authorization", "Bearer "+h.Cfg.CHAPA_SECRET_KEY) resp, err := http.DefaultClient.Do(httpReq) if err != nil { return c.Status(500).JSON(fiber.Map{ "error": "Failed to verify transaction", "details": err.Error(), }) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return c.Status(500).JSON(fiber.Map{ "error": "Failed to read response", "details": err.Error(), }) } return c.Status(resp.StatusCode).Send(body) } func (h *Handler) ReceiveWebhook(c *fiber.Ctx) error { var payload map[string]interface{} if err := c.BodyParser(&payload); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid webhook data", "details": err.Error(), }) } h.logger.Info("Chapa webhook received", "payload", payload) // Optional: you can verify tx_ref here again if needed return c.SendStatus(fiber.StatusOK) } func (h *Handler) CreateTransfer(c *fiber.Ctx) error { var req TransferRequest if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid request", "details": err.Error(), }) } payload, err := json.Marshal(req) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to serialize request", "details": err.Error(), }) } httpReq, err := http.NewRequest("POST", h.Cfg.CHAPA_BASE_URL+"/transfers", bytes.NewBuffer(payload)) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to create HTTP request", "details": err.Error(), }) } httpReq.Header.Set("Authorization", "Bearer "+h.Cfg.CHAPA_SECRET_KEY) httpReq.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(httpReq) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Transfer request failed", "details": err.Error(), }) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to read response", "details": err.Error(), }) } return c.Status(resp.StatusCode).Send(body) } func (h *Handler) VerifyTransfer(c *fiber.Ctx) error { transferRef := c.Params("transfer_ref") if transferRef == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Missing transfer reference in URL", }) } url := fmt.Sprintf("%s/transfers/%s", h.Cfg.CHAPA_BASE_URL, transferRef) httpReq, err := http.NewRequest("GET", url, nil) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to create HTTP request", "details": err.Error(), }) } httpReq.Header.Set("Authorization", "Bearer "+h.Cfg.CHAPA_SECRET_KEY) resp, err := http.DefaultClient.Do(httpReq) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Verification request failed", "details": err.Error(), }) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to read response body", "details": err.Error(), }) } return c.Status(resp.StatusCode).Send(body) }