package santimpay import ( "bytes" "context" "encoding/json" "fmt" "net/http" "github.com/SamuelTariku/FortuneBet-Backend/internal/config" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet" "github.com/google/uuid" ) // type SantimPayService interface { // GeneratePaymentURL(input domain.GeneratePaymentURLInput) (map[string]string, error) // } type SantimPayService struct { client SantimPayClient cfg *config.Config transferStore wallet.TransferStore } func NewSantimPayService(client SantimPayClient, cfg *config.Config, transferStore wallet.TransferStore) *SantimPayService { return &SantimPayService{ client: client, cfg: cfg, transferStore: transferStore, } } func (s *SantimPayService) GeneratePaymentURL(input domain.GeneratePaymentURLInput) (map[string]string, error) { paymentID := uuid.NewString() token, err := s.client.GenerateSignedToken(input.Amount, input.Reason) if err != nil { return nil, fmt.Errorf("token generation failed: %w", err) } payload := domain.InitiatePaymentPayload{ ID: paymentID, Amount: input.Amount, Reason: input.Reason, MerchantID: s.cfg.SANTIMPAY.MerchantID, SignedToken: token, SuccessRedirectURL: s.cfg.ARIFPAY.SuccessUrl, FailureRedirectURL: s.cfg.ARIFPAY.ErrorUrl, NotifyURL: s.cfg.ARIFPAY.B2CNotifyUrl, CancelRedirectURL: s.cfg.ARIFPAY.CancelUrl, PhoneNumber: input.PhoneNumber, } jsonData, err := json.Marshal(payload) if err != nil { return nil, fmt.Errorf("failed to marshal payload: %w", err) } resp, err := http.Post(s.cfg.SANTIMPAY.BaseURL+"/initiate-payment", "application/json", bytes.NewBuffer(jsonData)) if err != nil { return nil, fmt.Errorf("failed to send HTTP request: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("non-200 status code received: %d", resp.StatusCode) } var responseBody map[string]string if err := json.NewDecoder(resp.Body).Decode(&responseBody); err != nil { return nil, fmt.Errorf("failed to decode response: %w", err) } // Save transfer transfer := domain.CreateTransfer{ Amount: domain.Currency(input.Amount), Verified: false, Type: domain.DEPOSIT, ReferenceNumber: paymentID, Status: string(domain.PaymentStatusPending), } if _, err := s.transferStore.CreateTransfer(context.Background(), transfer); err != nil { return nil, fmt.Errorf("failed to create transfer: %w", err) } // Optionally check transaction status in a goroutine go s.client.CheckTransactionStatus(paymentID) return responseBody, nil }