package chapa import ( "bytes" "context" "encoding/json" "fmt" "io" "net/http" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" ) type ChapaClient interface { IssuePayment(ctx context.Context, payload domain.ChapaTransferPayload) (bool, error) InitPayment(ctx context.Context, req domain.InitPaymentRequest) (string, error) } type Client struct { BaseURL string SecretKey string HTTPClient *http.Client } func NewClient(baseURL, secretKey string) *Client { return &Client{ BaseURL: baseURL, SecretKey: secretKey, HTTPClient: http.DefaultClient, } } func (c *Client) IssuePayment(ctx context.Context, payload domain.ChapaTransferPayload) (bool, error) { payloadBytes, err := json.Marshal(payload) if err != nil { return false, fmt.Errorf("failed to serialize payload: %w", err) } req, err := http.NewRequestWithContext(ctx, "POST", c.BaseURL+"/transfers", bytes.NewBuffer(payloadBytes)) if err != nil { return false, fmt.Errorf("failed to create HTTP request: %w", err) } req.Header.Set("Authorization", "Bearer "+c.SecretKey) req.Header.Set("Content-Type", "application/json") resp, err := c.HTTPClient.Do(req) if err != nil { return false, fmt.Errorf("chapa HTTP request failed: %w", err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) if resp.StatusCode >= 200 && resp.StatusCode < 300 { return true, nil } return false, fmt.Errorf("chapa error: status %d, body: %s", resp.StatusCode, string(body)) } // service/chapa_service.go func (c *Client) InitPayment(ctx context.Context, req domain.InitPaymentRequest) (string, error) { payloadBytes, err := json.Marshal(req) if err != nil { return "", fmt.Errorf("failed to serialize payload: %w", err) } httpReq, err := http.NewRequestWithContext(ctx, "POST", c.BaseURL+"/transaction/initialize", bytes.NewBuffer(payloadBytes)) if err != nil { return "", fmt.Errorf("failed to create HTTP request: %w", err) } httpReq.Header.Set("Authorization", "Bearer "+c.SecretKey) httpReq.Header.Set("Content-Type", "application/json") resp, err := c.HTTPClient.Do(httpReq) if err != nil { return "", fmt.Errorf("chapa HTTP request failed: %w", err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) if resp.StatusCode < 200 || resp.StatusCode >= 300 { return "", fmt.Errorf("chapa error: status %d, body: %s", resp.StatusCode, string(body)) } var response struct { Data struct { CheckoutURL string `json:"checkout_url"` } `json:"data"` } if err := json.Unmarshal(body, &response); err != nil { return "", fmt.Errorf("failed to parse chapa response: %w", err) } return response.Data.CheckoutURL, nil }