Yimaru-BackEnd/internal/services/santimpay/service.go

93 lines
2.7 KiB
Go

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.NotifyUrl,
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
}