more chapa fix
This commit is contained in:
parent
aef5c4410d
commit
b4609cdd5b
10
cmd/main.go
10
cmd/main.go
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/chapa"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notfication"
|
||||
|
|
@ -107,6 +108,13 @@ func main() {
|
|||
logger,
|
||||
)
|
||||
recommendationSvc := recommendation.NewService(recommendationRepo)
|
||||
chapaSvc := chapa.NewService(
|
||||
transaction.TransactionStore(store),
|
||||
wallet.WalletStore(store),
|
||||
user.UserStore(store),
|
||||
referalSvc,
|
||||
store,
|
||||
)
|
||||
|
||||
httpserver.StartDataFetchingCrons(eventSvc, oddsSvc, resultSvc)
|
||||
httpserver.StartTicketCrons(*ticketSvc)
|
||||
|
|
@ -115,7 +123,7 @@ func main() {
|
|||
JwtAccessKey: cfg.JwtKey,
|
||||
JwtAccessExpiry: cfg.AccessExpiry,
|
||||
}, userSvc,
|
||||
ticketSvc, betSvc, walletSvc, transactionSvc, branchSvc, companySvc, notificationSvc, oddsSvc, eventSvc, referalSvc, virtualGameSvc, aleaService, veliService, recommendationSvc, resultSvc, cfg)
|
||||
ticketSvc, betSvc, chapaSvc, walletSvc, transactionSvc, branchSvc, companySvc, notificationSvc, oddsSvc, eventSvc, referalSvc, virtualGameSvc, aleaService, veliService, recommendationSvc, resultSvc, cfg)
|
||||
logger.Info("Starting server", "port", cfg.Port)
|
||||
|
||||
if err := app.Run(); err != nil {
|
||||
|
|
|
|||
|
|
@ -289,3 +289,8 @@ func (c *Config) loadEnv() error {
|
|||
c.Bet365Token = betToken
|
||||
return nil
|
||||
}
|
||||
|
||||
type ChapaConfig struct {
|
||||
ChapaPaymentType string `mapstructure:"chapa_payment_type"`
|
||||
ChapaTransferType string `mapstructure:"chapa_transfer_type"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
|
|
@ -39,3 +40,12 @@ func OpenDB(url string) (*pgxpool.Pool, func(), error) {
|
|||
conn.Close()
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Store) BeginTx(ctx context.Context) (*dbgen.Queries, pgx.Tx, error) {
|
||||
tx, err := s.conn.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
q := s.queries.WithTx(tx)
|
||||
return q, tx, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,5 @@ import (
|
|||
|
||||
type ChapaPort interface {
|
||||
HandleChapaTransferWebhook(ctx context.Context, req domain.ChapaWebHookTransfer) error
|
||||
HandleChapaPaymentWebhook(ctx context.Context, req domain.ChapaWebHookPayment) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import (
|
|||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
||||
referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/transaction"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
|
@ -15,36 +17,55 @@ import (
|
|||
type Service struct {
|
||||
transactionStore transaction.TransactionStore
|
||||
walletStore wallet.WalletStore
|
||||
userStore user.UserStore
|
||||
referralStore referralservice.ReferralStore
|
||||
store *repository.Store
|
||||
}
|
||||
|
||||
func NewService(
|
||||
txStore transaction.TransactionStore,
|
||||
walletStore wallet.WalletStore,
|
||||
userStore user.UserStore,
|
||||
referralStore referralservice.ReferralStore,
|
||||
store *repository.Store,
|
||||
) *Service {
|
||||
return &Service{
|
||||
transactionStore: txStore,
|
||||
walletStore: walletStore,
|
||||
userStore: userStore,
|
||||
referralStore: referralStore,
|
||||
store: store,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) HandleChapaTransferWebhook(ctx context.Context, req domain.ChapaWebHookTransfer) error {
|
||||
tx, err := s.store.Begin(ctx)
|
||||
_, tx, err := s.store.BeginTx(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
// 1. Fetch transaction
|
||||
// Use your services normally (they don’t use the transaction, unless you wire `q`)
|
||||
referenceID, err := strconv.ParseInt(req.Reference, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid reference ID: %w", err)
|
||||
}
|
||||
|
||||
txn, err := s.transactionStore.GetTransactionByID(ctx, referenceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if txn.Verified {
|
||||
return nil // already processed
|
||||
return nil
|
||||
}
|
||||
|
||||
// 2. Compare amount
|
||||
webhookAmount, _ := decimal.NewFromString(req.Amount)
|
||||
storedAmount, _ := decimal.NewFromString(txn.Amount.String())
|
||||
if !webhookAmount.Equal(storedAmount) {
|
||||
return fmt.Errorf("amount mismatch")
|
||||
}
|
||||
|
||||
// 3. Update transaction
|
||||
txn.Verified = true
|
||||
|
||||
if err := s.transactionStore.UpdateTransactionVerified(ctx, txn.ID, txn.Verified, txn.ApprovedBy.Value, txn.ApproverName.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -53,7 +74,7 @@ func (s *Service) HandleChapaTransferWebhook(ctx context.Context, req domain.Cha
|
|||
}
|
||||
|
||||
func (s *Service) HandleChapaPaymentWebhook(ctx context.Context, req domain.ChapaWebHookPayment) error {
|
||||
tx, err := s.store.Begin(ctx)
|
||||
_, tx, err := s.store.BeginTx(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -78,11 +99,8 @@ func (s *Service) HandleChapaPaymentWebhook(ctx context.Context, req domain.Chap
|
|||
return nil // already processed
|
||||
}
|
||||
|
||||
// 3. Amount validation
|
||||
webhookAmount, _ := decimal.NewFromString(req.Amount)
|
||||
storedAmount := txn.Amount // assuming it's domain.Currency (decimal.Decimal alias)
|
||||
|
||||
if webhookAmount.LessThan(storedAmount) {
|
||||
webhookAmount, _ := strconv.ParseFloat(req.Amount, 32)
|
||||
if webhookAmount < float64(txn.Amount) {
|
||||
return fmt.Errorf("webhook amount is less than expected")
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +111,7 @@ func (s *Service) HandleChapaPaymentWebhook(ctx context.Context, req domain.Chap
|
|||
}
|
||||
|
||||
// 5. Update wallet balance
|
||||
newBalance := wallet.Balance.Add(storedAmount)
|
||||
newBalance := wallet.Balance + txn.Amount
|
||||
if err := s.walletStore.UpdateBalance(ctx, wallet.ID, newBalance); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -103,23 +121,14 @@ func (s *Service) HandleChapaPaymentWebhook(ctx context.Context, req domain.Chap
|
|||
return err
|
||||
}
|
||||
|
||||
// 7. Check & generate referral code
|
||||
hasCode, err := s.userStore.HasReferralCode(ctx, wallet.UserID)
|
||||
// 7. Check & Create Referral
|
||||
stats, err := s.referralStore.GetReferralStats(ctx, string(wallet.UserID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !hasCode {
|
||||
code := misc.GenerateReferralCode(req.FirstName)
|
||||
|
||||
if err := s.userStore.SetReferralCode(ctx, wallet.UserID, code); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.referralStore.CreateReferralCode(ctx, domain.ReferralCode{
|
||||
Code: code,
|
||||
Amount: config.ReferralRewardBase,
|
||||
}); err != nil {
|
||||
if stats == nil {
|
||||
if err := s.referralStore.CreateReferral(ctx, wallet.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/chapa"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
|
||||
|
|
@ -44,6 +45,7 @@ type App struct {
|
|||
userSvc *user.Service
|
||||
betSvc *bet.Service
|
||||
virtualGameSvc virtualgameservice.VirtualGameService
|
||||
chapaSvc *chapa.Service
|
||||
walletSvc *wallet.Service
|
||||
transactionSvc *transaction.Service
|
||||
ticketSvc *ticket.Service
|
||||
|
|
@ -65,6 +67,7 @@ func NewApp(
|
|||
userSvc *user.Service,
|
||||
ticketSvc *ticket.Service,
|
||||
betSvc *bet.Service,
|
||||
chapaSvc *chapa.Service,
|
||||
walletSvc *wallet.Service,
|
||||
transactionSvc *transaction.Service,
|
||||
branchSvc *branch.Service,
|
||||
|
|
@ -104,6 +107,7 @@ func NewApp(
|
|||
userSvc: userSvc,
|
||||
ticketSvc: ticketSvc,
|
||||
betSvc: betSvc,
|
||||
chapaSvc: chapaSvc,
|
||||
walletSvc: walletSvc,
|
||||
transactionSvc: transactionSvc,
|
||||
branchSvc: branchSvc,
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ func (h *Handler) VerifyChapaPayment(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
switch txType.Type {
|
||||
case config.ChapaTransferType:
|
||||
case config.ChapaConfig.ChapaTransferType:
|
||||
var payload domain.ChapaWebHookTransfer
|
||||
if err := c.BodyParser(&payload); err != nil {
|
||||
return domain.UnProcessableEntityResponse(c)
|
||||
|
|
@ -315,7 +315,7 @@ func (h *Handler) VerifyChapaPayment(c *fiber.Ctx) error {
|
|||
StatusCode: fiber.StatusOK,
|
||||
})
|
||||
|
||||
case config.ChapaPaymentType:
|
||||
case config.ChapaConfig.ChapaPaymentType:
|
||||
var payload domain.ChapaWebHookPayment
|
||||
if err := c.BodyParser(&payload); err != nil {
|
||||
return domain.UnProcessableEntityResponse(c)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ func (a *App) initAppRoutes() {
|
|||
a.logger,
|
||||
a.NotidicationStore,
|
||||
a.validator,
|
||||
a.chapaSvc,
|
||||
a.walletSvc,
|
||||
a.referralSvc,
|
||||
a.virtualGameSvc,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user