diff --git a/docs/docs.go b/docs/docs.go index a34cfd4..a057097 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -2085,6 +2085,49 @@ const docTemplate = `{ } } }, + "/api/v1/chapa/balances": { + "get": { + "description": "Retrieve Chapa account balance, optionally filtered by currency code (e.g., ETB, USD)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Chapa" + ], + "summary": "Get Chapa account balance", + "parameters": [ + { + "type": "string", + "description": "Currency code (optional)", + "name": "currency_code", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/chapa/banks": { "get": { "description": "Get list of banks supported by Chapa", @@ -2209,6 +2252,50 @@ const docTemplate = `{ } } }, + "/api/v1/chapa/payments/receipt/{chapa_ref}": { + "get": { + "description": "Retrieve the Chapa payment receipt URL using the reference ID", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Chapa" + ], + "summary": "Get Chapa Payment Receipt URL", + "parameters": [ + { + "type": "string", + "description": "Chapa Reference ID", + "name": "chapa_ref", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/chapa/payments/webhook/verify": { "post": { "description": "Handles payment notifications from Chapa", @@ -2319,6 +2406,87 @@ const docTemplate = `{ } } }, + "/api/v1/chapa/swap": { + "post": { + "description": "Perform a USD to ETB currency swap using Chapa's API", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Chapa" + ], + "summary": "Initiate a currency swap", + "parameters": [ + { + "description": "Swap Request Payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/domain.SwapRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, + "/api/v1/chapa/transfers": { + "get": { + "description": "Retrieve all transfer records from Chapa", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Chapa" + ], + "summary": "Get all Chapa transfers", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/company": { "get": { "description": "Gets all companies", @@ -9837,7 +10005,7 @@ const docTemplate = `{ "type": "string" }, "round_id": { - "type": "integer" + "type": "string" }, "session_id": { "type": "string" @@ -12934,6 +13102,20 @@ const docTemplate = `{ } } }, + "domain.SwapRequest": { + "type": "object", + "properties": { + "amount": { + "type": "number" + }, + "from": { + "type": "string" + }, + "to": { + "type": "string" + } + } + }, "domain.TelebirrPaymentCallbackPayload": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index c59c2e1..46c389a 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -2077,6 +2077,49 @@ } } }, + "/api/v1/chapa/balances": { + "get": { + "description": "Retrieve Chapa account balance, optionally filtered by currency code (e.g., ETB, USD)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Chapa" + ], + "summary": "Get Chapa account balance", + "parameters": [ + { + "type": "string", + "description": "Currency code (optional)", + "name": "currency_code", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/chapa/banks": { "get": { "description": "Get list of banks supported by Chapa", @@ -2201,6 +2244,50 @@ } } }, + "/api/v1/chapa/payments/receipt/{chapa_ref}": { + "get": { + "description": "Retrieve the Chapa payment receipt URL using the reference ID", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Chapa" + ], + "summary": "Get Chapa Payment Receipt URL", + "parameters": [ + { + "type": "string", + "description": "Chapa Reference ID", + "name": "chapa_ref", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/chapa/payments/webhook/verify": { "post": { "description": "Handles payment notifications from Chapa", @@ -2311,6 +2398,87 @@ } } }, + "/api/v1/chapa/swap": { + "post": { + "description": "Perform a USD to ETB currency swap using Chapa's API", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Chapa" + ], + "summary": "Initiate a currency swap", + "parameters": [ + { + "description": "Swap Request Payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/domain.SwapRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, + "/api/v1/chapa/transfers": { + "get": { + "description": "Retrieve all transfer records from Chapa", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Chapa" + ], + "summary": "Get all Chapa transfers", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/company": { "get": { "description": "Gets all companies", @@ -9829,7 +9997,7 @@ "type": "string" }, "round_id": { - "type": "integer" + "type": "string" }, "session_id": { "type": "string" @@ -12926,6 +13094,20 @@ } } }, + "domain.SwapRequest": { + "type": "object", + "properties": { + "amount": { + "type": "number" + }, + "from": { + "type": "string" + }, + "to": { + "type": "string" + } + } + }, "domain.TelebirrPaymentCallbackPayload": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index c6c6fce..db66f08 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -75,7 +75,7 @@ definitions: player_id: type: string round_id: - type: integer + type: string session_id: type: string timestamp: @@ -2191,6 +2191,15 @@ definitions: example: SportsBook type: string type: object + domain.SwapRequest: + properties: + amount: + type: number + from: + type: string + to: + type: string + type: object domain.TelebirrPaymentCallbackPayload: properties: appid: @@ -5509,6 +5518,35 @@ paths: summary: Update cashier tags: - cashier + /api/v1/chapa/balances: + get: + consumes: + - application/json + description: Retrieve Chapa account balance, optionally filtered by currency + code (e.g., ETB, USD) + parameters: + - description: Currency code (optional) + in: query + name: currency_code + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/domain.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: Get Chapa account balance + tags: + - Chapa /api/v1/chapa/banks: get: consumes: @@ -5589,6 +5627,35 @@ paths: summary: Verify a payment manually tags: - Chapa + /api/v1/chapa/payments/receipt/{chapa_ref}: + get: + consumes: + - application/json + description: Retrieve the Chapa payment receipt URL using the reference ID + parameters: + - description: Chapa Reference ID + in: path + name: chapa_ref + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/domain.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: Get Chapa Payment Receipt URL + tags: + - Chapa /api/v1/chapa/payments/webhook/verify: post: consumes: @@ -5661,6 +5728,59 @@ paths: summary: Initiate a withdrawal tags: - Chapa + /api/v1/chapa/swap: + post: + consumes: + - application/json + description: Perform a USD to ETB currency swap using Chapa's API + parameters: + - description: Swap Request Payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/domain.SwapRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/domain.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: Initiate a currency swap + tags: + - Chapa + /api/v1/chapa/transfers: + get: + consumes: + - application/json + description: Retrieve all transfer records from Chapa + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/domain.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: Get all Chapa transfers + tags: + - Chapa /api/v1/company: get: consumes: diff --git a/internal/domain/atlas.go b/internal/domain/atlas.go index 66f8cb7..bf3fa47 100644 --- a/internal/domain/atlas.go +++ b/internal/domain/atlas.go @@ -46,7 +46,7 @@ type AtlasBetResponse struct { type AtlasBetWinRequest struct { Game string `json:"game"` CasinoID string `json:"casino_id"` - RoundID int64 `json:"round_id"` + RoundID string `json:"round_id"` PlayerID string `json:"player_id"` SessionID string `json:"session_id"` BetAmount float64 `json:"betAmount"` diff --git a/internal/domain/chapa.go b/internal/domain/chapa.go index d1451cd..bf6b683 100644 --- a/internal/domain/chapa.go +++ b/internal/domain/chapa.go @@ -196,3 +196,28 @@ type ChapaWebHookPayment struct { } `json:"customization"` Meta string `json:"meta"` } + +type Balance struct { + Currency string `json:"currency"` + AvailableBalance float64 `json:"available_balance"` + LedgerBalance float64 `json:"ledger_balance"` +} + +type SwapRequest struct { + From string `json:"from"` + To string `json:"to"` + Amount float64 `json:"amount"` +} + +type SwapResponse struct { + Status string `json:"status"` + RefID string `json:"ref_id"` + FromCurrency string `json:"from_currency"` + ToCurrency string `json:"to_currency"` + Amount float64 `json:"amount"` + ExchangedAmount float64 `json:"exchanged_amount"` + Charge float64 `json:"charge"` + Rate float64 `json:"rate"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} diff --git a/internal/services/chapa/port.go b/internal/services/chapa/port.go index 78ae033..862e3c4 100644 --- a/internal/services/chapa/port.go +++ b/internal/services/chapa/port.go @@ -16,10 +16,13 @@ import ( type ChapaStore interface { InitializePayment(request domain.ChapaDepositRequest) (domain.ChapaDepositResponse, error) - // VerifyPayment(reference string) (domain.ChapaDepositVerification, error) ManualVerifTransaction(ctx context.Context, txRef string) (*domain.ChapaVerificationResponse, error) FetchSupportedBanks(ctx context.Context) ([]domain.Bank, error) CreateWithdrawal(userID string, amount float64, accountNumber, bankCode string) (*domain.ChapaWithdrawal, error) HandleVerifyDepositWebhook(ctx context.Context, transfer domain.ChapaWebHookTransfer) error HandleVerifyWithdrawWebhook(ctx context.Context, payment domain.ChapaWebHookPayment) error + GetPaymentReceiptURL(ctx context.Context, chapaRef string) (string, error) + GetAllTransfers(ctx context.Context) ([]domain.Transfer, error) + GetAccountBalance(ctx context.Context, currencyCode string) ([]domain.Balance, error) + InitiateSwap(ctx context.Context, amount float64, from, to string) (*domain.SwapResponse, error) } diff --git a/internal/services/chapa/service.go b/internal/services/chapa/service.go index 5822cb7..03cba51 100644 --- a/internal/services/chapa/service.go +++ b/internal/services/chapa/service.go @@ -1,9 +1,13 @@ package chapa import ( + "bytes" "context" + "encoding/json" "errors" "fmt" + "io" + "net/http" "strconv" "strings" @@ -63,7 +67,7 @@ func (s *Service) InitiateDeposit(ctx context.Context, userID int64, amount doma return "", fmt.Errorf("failed to get sender wallets: %w", err) } for _, wallet := range senderWallets { - if wallet.IsWithdraw { + if wallet.IsTransferable { senderWallet = wallet break } @@ -364,3 +368,138 @@ func (s *Service) HandleVerifyWithdrawWebhook(ctx context.Context, payment domai return nil } + +func (s *Service) GetPaymentReceiptURL(ctx context.Context, chapaRef string) (string, error) { + if chapaRef == "" { + return "", fmt.Errorf("chapa reference ID is required") + } + + receiptURL := fmt.Sprintf("https://chapa.link/payment-receipt/%s", chapaRef) + return receiptURL, nil +} + +func (s *Service) GetAllTransfers(ctx context.Context) ([]domain.Transfer, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.chapa.co/v1/transfers", nil) + if err != nil { + return nil, fmt.Errorf("failed to create request: %w", err) + } + + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", s.cfg.CHAPA_SECRET_KEY)) + + resp, err := s.chapaClient.httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to fetch transfers: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + bodyBytes, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("unexpected status %d: %s", resp.StatusCode, string(bodyBytes)) + } + + var result struct { + Status string `json:"status"` + Message string `json:"message"` + Data []domain.Transfer `json:"data"` + } + + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + return nil, fmt.Errorf("failed to decode response: %w", err) + } + + return result.Data, nil +} + +func (s *Service) GetAccountBalance(ctx context.Context, currencyCode string) ([]domain.Balance, error) { + baseURL := "https://api.chapa.co/v1/balances" + if currencyCode != "" { + baseURL = fmt.Sprintf("%s/%s", baseURL, strings.ToLower(currencyCode)) + } + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, baseURL, nil) + if err != nil { + return nil, fmt.Errorf("failed to create balance request: %w", err) + } + + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", s.cfg.CHAPA_SECRET_KEY)) + + resp, err := s.chapaClient.httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to execute balance request: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + bodyBytes, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("unexpected status %d: %s", resp.StatusCode, string(bodyBytes)) + } + + var result struct { + Status string `json:"status"` + Message string `json:"message"` + Data []domain.Balance `json:"data"` + } + + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + return nil, fmt.Errorf("failed to decode balance response: %w", err) + } + + return result.Data, nil +} + +func (s *Service) InitiateSwap(ctx context.Context, amount float64, from, to string) (*domain.SwapResponse, error) { + if amount < 1 { + return nil, fmt.Errorf("amount must be at least 1 USD") + } + if strings.ToUpper(from) != "USD" || strings.ToUpper(to) != "ETB" { + return nil, fmt.Errorf("only USD to ETB swap is supported") + } + + payload := domain.SwapRequest{ + Amount: amount, + From: strings.ToUpper(from), + To: strings.ToUpper(to), + } + + // payload := map[string]any{ + // "amount": amount, + // "from": strings.ToUpper(from), + // "to": strings.ToUpper(to), + // } + + body, err := json.Marshal(payload) + if err != nil { + return nil, fmt.Errorf("failed to encode swap payload: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://api.chapa.co/v1/swap", bytes.NewBuffer(body)) + if err != nil { + return nil, fmt.Errorf("failed to create swap request: %w", err) + } + + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", s.cfg.CHAPA_SECRET_KEY)) + req.Header.Set("Content-Type", "application/json") + + resp, err := s.chapaClient.httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to execute swap request: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { + bodyBytes, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("unexpected status %d: %s", resp.StatusCode, string(bodyBytes)) + } + + var result struct { + Message string `json:"message"` + Status string `json:"status"` + Data domain.SwapResponse `json:"data"` + } + + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + return nil, fmt.Errorf("failed to decode swap response: %w", err) + } + + return &result.Data, nil +} diff --git a/internal/services/virtualGame/service.go b/internal/services/virtualGame/service.go index 46ddb66..435e03b 100644 --- a/internal/services/virtualGame/service.go +++ b/internal/services/virtualGame/service.go @@ -657,10 +657,6 @@ func (s *service) verifySignature(callback *domain.PopOKCallback) bool { return expected == callback.Signature } -// func (s *service) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) { -// return s.repo.GetGameCounts(ctx, filter) -// } - func (s *service) ListGames(ctx context.Context, currency string) ([]domain.PopOKGame, error) { now := time.Now().Format("02-01-2006 15:04:05") // dd-mm-yyyy hh:mm:ss diff --git a/internal/web_server/handlers/chapa.go b/internal/web_server/handlers/chapa.go index 9a2a7c2..f260bc5 100644 --- a/internal/web_server/handlers/chapa.go +++ b/internal/web_server/handlers/chapa.go @@ -263,3 +263,132 @@ func (h *Handler) InitiateWithdrawal(c *fiber.Ctx) error { Data: withdrawal, }) } + +// GetPaymentReceipt godoc +// @Summary Get Chapa Payment Receipt URL +// @Description Retrieve the Chapa payment receipt URL using the reference ID +// @Tags Chapa +// @Accept json +// @Produce json +// @Param chapa_ref path string true "Chapa Reference ID" +// @Success 200 {object} domain.Response +// @Failure 400 {object} domain.ErrorResponse +// @Failure 500 {object} domain.ErrorResponse +// @Router /api/v1/chapa/payments/receipt/{chapa_ref} [get] +func (h *Handler) GetPaymentReceipt(c *fiber.Ctx) error { + chapaRef := c.Params("chapa_ref") + if chapaRef == "" { + return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ + Message: "Failed to get Chapa payment receipt", + Error: "Chapa reference ID is required", + }) + } + + receiptURL, err := h.chapaSvc.GetPaymentReceiptURL(c.Context(), chapaRef) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{ + Message: "Failed to get Chapa payment receipt", + Error: err.Error(), + }) + } + + return c.Status(fiber.StatusOK).JSON(domain.Response{ + Message: "Payment receipt URL generated successfully", + Data: receiptURL, + StatusCode: 200, + Success: true, + }) +} + +// GetAllTransfers godoc +// @Summary Get all Chapa transfers +// @Description Retrieve all transfer records from Chapa +// @Tags Chapa +// @Accept json +// @Produce json +// @Success 200 {object} domain.Response +// @Failure 400 {object} domain.ErrorResponse +// @Failure 500 {object} domain.ErrorResponse +// @Router /api/v1/chapa/transfers [get] +func (h *Handler) GetAllTransfers(c *fiber.Ctx) error { + transfers, err := h.chapaSvc.GetAllTransfers(c.Context()) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{ + Message: "Failed to fetch Chapa transfers", + Error: err.Error(), + }) + } + + return c.Status(fiber.StatusOK).JSON(domain.Response{ + Message: "Chapa transfers retrieved successfully", + Data: transfers, + StatusCode: fiber.StatusOK, + Success: true, + }) +} + +// GetAccountBalance godoc +// @Summary Get Chapa account balance +// @Description Retrieve Chapa account balance, optionally filtered by currency code (e.g., ETB, USD) +// @Tags Chapa +// @Accept json +// @Produce json +// @Param currency_code query string false "Currency code (optional)" +// @Success 200 {object} domain.Response +// @Failure 400 {object} domain.ErrorResponse +// @Failure 500 {object} domain.ErrorResponse +// @Router /api/v1/chapa/balances [get] +func (h *Handler) GetAccountBalance(c *fiber.Ctx) error { + currencyCode := c.Query("currency_code", "") + + balances, err := h.chapaSvc.GetAccountBalance(c.Context(), currencyCode) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{ + Message: "Failed to fetch Chapa account balance", + Error: err.Error(), + }) + } + + return c.Status(fiber.StatusOK).JSON(domain.Response{ + Message: "Chapa account balance retrieved successfully", + Data: balances, + StatusCode: fiber.StatusOK, + Success: true, + }) +} + +// InitiateSwap godoc +// @Summary Initiate a currency swap +// @Description Perform a USD to ETB currency swap using Chapa's API +// @Tags Chapa +// @Accept json +// @Produce json +// @Param payload body domain.SwapRequest true "Swap Request Payload" +// @Success 200 {object} domain.Response +// @Failure 400 {object} domain.ErrorResponse +// @Failure 500 {object} domain.ErrorResponse +// @Router /api/v1/chapa/swap [post] +func (h *Handler) InitiateSwap(c *fiber.Ctx) error { + var req domain.SwapRequest + if err := c.BodyParser(&req); err != nil { + return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ + Message: "Invalid request payload", + Error: err.Error(), + }) + } + + swapResult, err := h.chapaSvc.InitiateSwap(c.Context(), req.Amount, req.From, req.To) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{ + Message: "Failed to initiate currency swap", + Error: err.Error(), + }) + } + + return c.Status(fiber.StatusOK).JSON(domain.Response{ + Message: "Currency swap initiated successfully", + Data: swapResult, + StatusCode: fiber.StatusOK, + Success: true, + }) +} diff --git a/internal/web_server/routes.go b/internal/web_server/routes.go index aabc03f..c1e8146 100644 --- a/internal/web_server/routes.go +++ b/internal/web_server/routes.go @@ -383,6 +383,10 @@ func (a *App) initAppRoutes() { groupV1.Post("/chapa/payments/deposit", a.authMiddleware, h.InitiateDeposit) groupV1.Post("/chapa/payments/withdraw", a.authMiddleware, h.InitiateWithdrawal) groupV1.Get("/chapa/banks", h.GetSupportedBanks) + groupV1.Get("/chapa/payments/receipt/:chapa_ref", h.GetPaymentReceipt) + groupV1.Get("/chapa/transfers", h.GetAllTransfers) + groupV1.Get("/chapa/balance", h.GetAccountBalance) + groupV1.Post("/chapa/init-swap", h.InitiateSwap) // Currencies groupV1.Get("/currencies", h.GetSupportedCurrencies)