/cancel callback nil dereference fix
This commit is contained in:
parent
c5fe2b8297
commit
8aefd54562
|
|
@ -153,7 +153,7 @@ func main() {
|
|||
virtualGameSvc := virtualgameservice.New(vitualGameRepo, *walletSvc, store, cfg, logger)
|
||||
aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger)
|
||||
veliCLient := veli.NewClient(cfg, walletSvc)
|
||||
veliVirtualGameService := veli.New(veliCLient, walletSvc, cfg)
|
||||
veliVirtualGameService := veli.New(veliCLient, walletSvc, wallet.TransferStore(store), cfg)
|
||||
recommendationSvc := recommendation.NewService(recommendationRepo)
|
||||
chapaClient := chapa.NewClient(cfg.CHAPA_BASE_URL, cfg.CHAPA_SECRET_KEY)
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ type CancelRequest struct {
|
|||
CorrelationID string `json:"correlationId,omitempty"`
|
||||
ProviderID string `json:"providerId"`
|
||||
BrandID string `json:"brandId"`
|
||||
IsAdjustment bool `json:"isAdjustment,omitempty"`
|
||||
AdjustmentRefund *struct {
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
|
|
|
|||
|
|
@ -19,16 +19,18 @@ var (
|
|||
)
|
||||
|
||||
type service struct {
|
||||
client *Client
|
||||
walletSvc *wallet.Service
|
||||
cfg *config.Config
|
||||
client *Client
|
||||
walletSvc *wallet.Service
|
||||
transfetStore wallet.TransferStore
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
func New(client *Client, walletSvc *wallet.Service, cfg *config.Config) VeliVirtualGameService {
|
||||
func New(client *Client, walletSvc *wallet.Service, transferStore wallet.TransferStore, cfg *config.Config) VeliVirtualGameService {
|
||||
return &service{
|
||||
client: client,
|
||||
walletSvc: walletSvc,
|
||||
cfg: cfg,
|
||||
client: client,
|
||||
walletSvc: walletSvc,
|
||||
transfetStore: transferStore,
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -338,7 +340,7 @@ func (s *service) ProcessCancel(ctx context.Context, req domain.CancelRequest) (
|
|||
// --- 1. Validate PlayerID ---
|
||||
playerIDInt64, err := strconv.ParseInt(req.PlayerID, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid PlayerID %s", req.PlayerID)
|
||||
return nil, fmt.Errorf("invalid PlayerID %q", req.PlayerID)
|
||||
}
|
||||
|
||||
// --- 2. Get player wallets ---
|
||||
|
|
@ -358,18 +360,23 @@ func (s *service) ProcessCancel(ctx context.Context, req domain.CancelRequest) (
|
|||
bonusBalance = float64(playerWallets[1].Balance)
|
||||
}
|
||||
|
||||
// --- 3. Refund handling ---
|
||||
// --- 3. Determine refund amount based on IsAdjustment ---
|
||||
var refundAmount float64
|
||||
if req.AdjustmentRefund.Amount > 0 {
|
||||
if req.IsAdjustment {
|
||||
if req.AdjustmentRefund.Amount <= 0 {
|
||||
return nil, fmt.Errorf("missing adjustmentRefund for adjustment cancel")
|
||||
}
|
||||
refundAmount = req.AdjustmentRefund.Amount
|
||||
} else {
|
||||
// If cancelType = CANCEL_BET and no explicit adjustmentRefund,
|
||||
// we may need to look up the original bet transaction and refund that.
|
||||
// TODO: implement transaction lookup if required by your domain.
|
||||
return nil, fmt.Errorf("missing adjustmentRefund for CANCEL_BET")
|
||||
// Regular cancel: fetch original bet amount if needed
|
||||
originalTransfer, err := s.transfetStore.GetTransferByReference(ctx, req.RefTransactionID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get original bet for cancellation: %w", err)
|
||||
}
|
||||
refundAmount = float64(originalTransfer.Amount)
|
||||
}
|
||||
|
||||
// For now, we assume refund goes back fully to real wallet
|
||||
// --- 4. Refund to wallet ---
|
||||
usedReal := refundAmount
|
||||
usedBonus := 0.0
|
||||
|
||||
|
|
@ -392,7 +399,7 @@ func (s *service) ProcessCancel(ctx context.Context, req domain.CancelRequest) (
|
|||
return nil, fmt.Errorf("failed to refund wallet: %w", err)
|
||||
}
|
||||
|
||||
// --- 4. Reload balances after refund ---
|
||||
// --- 5. Reload balances after refund ---
|
||||
updatedWallets, err := s.walletSvc.GetWalletsByUser(ctx, playerIDInt64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to reload balances: %w", err)
|
||||
|
|
@ -405,11 +412,11 @@ func (s *service) ProcessCancel(ctx context.Context, req domain.CancelRequest) (
|
|||
bonusBalance = float64(updatedWallets[1].Balance)
|
||||
}
|
||||
|
||||
// --- 5. Build response ---
|
||||
// --- 6. Build response ---
|
||||
res := &domain.CancelResponse{
|
||||
WalletTransactionID: req.TransactionID,
|
||||
Real: domain.BalanceDetail{
|
||||
Currency: req.AdjustmentRefund.Currency,
|
||||
Currency: "ETB",
|
||||
Amount: realBalance,
|
||||
},
|
||||
UsedRealAmount: usedReal,
|
||||
|
|
@ -418,7 +425,7 @@ func (s *service) ProcessCancel(ctx context.Context, req domain.CancelRequest) (
|
|||
|
||||
if bonusBalance > 0 {
|
||||
res.Bonus = &domain.BalanceDetail{
|
||||
Currency: req.AdjustmentRefund.Currency,
|
||||
Currency: "ETB",
|
||||
Amount: bonusBalance,
|
||||
}
|
||||
}
|
||||
|
|
@ -426,6 +433,12 @@ func (s *service) ProcessCancel(ctx context.Context, req domain.CancelRequest) (
|
|||
return res, nil
|
||||
}
|
||||
|
||||
// Example helper to fetch original bet
|
||||
// func (s *service) getOriginalBet(ctx context.Context, transactionID string) (*domain.BetRecord, error) {
|
||||
// // TODO: implement actual lookup
|
||||
// return &domain.BetRecord{Amount: 50}, nil
|
||||
// }
|
||||
|
||||
func (s *service) GetGamingActivity(ctx context.Context, req domain.GamingActivityRequest) (*domain.GamingActivityResponse, error) {
|
||||
// --- Signature Params (flattened strings for signing) ---
|
||||
sigParams := map[string]any{
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ func (h *Handler) HandlePlayerInfo(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
func (h *Handler) HandleBet(c *fiber.Ctx) error {
|
||||
// Read the raw body to avoid parsing issues
|
||||
// Read the raw body
|
||||
body := c.Body()
|
||||
if len(body) == 0 {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
|
|
@ -119,26 +119,11 @@ func (h *Handler) HandleBet(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
|
||||
// Try to identify the provider based on the request structure
|
||||
provider, err := identifyBetProvider(body)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Unrecognized request format",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
switch provider {
|
||||
case "veli":
|
||||
var req domain.BetRequest
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Invalid Veli bet request",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
res, err := h.veliVirtualGameSvc.ProcessBet(c.Context(), req)
|
||||
// Try parsing as Veli bet request
|
||||
var veliReq domain.BetRequest
|
||||
if err := json.Unmarshal(body, &veliReq); err == nil && veliReq.SessionID != "" && veliReq.BrandID != "" {
|
||||
// Process as Veli
|
||||
res, err := h.veliVirtualGameSvc.ProcessBet(c.Context(), veliReq)
|
||||
if err != nil {
|
||||
if errors.Is(err, veli.ErrDuplicateTransaction) {
|
||||
return c.Status(fiber.StatusConflict).JSON(domain.ErrorResponse{
|
||||
|
|
@ -152,17 +137,13 @@ func (h *Handler) HandleBet(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
return c.JSON(res)
|
||||
}
|
||||
|
||||
case "popok":
|
||||
var req domain.PopOKBetRequest
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Invalid PopOK bet request",
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
resp, err := h.virtualGameSvc.ProcessBet(c.Context(), &req)
|
||||
// Try parsing as PopOK bet request
|
||||
var popokReq domain.PopOKBetRequest
|
||||
if err := json.Unmarshal(body, &popokReq); err == nil && popokReq.ExternalToken != "" {
|
||||
// Process as PopOK
|
||||
resp, err := h.virtualGameSvc.ProcessBet(c.Context(), &popokReq)
|
||||
if err != nil {
|
||||
code := fiber.StatusInternalServerError
|
||||
switch err.Error() {
|
||||
|
|
@ -177,13 +158,13 @@ func (h *Handler) HandleBet(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
return c.JSON(resp)
|
||||
|
||||
default:
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Unsupported provider",
|
||||
Error: "Request format doesn't match any supported provider",
|
||||
})
|
||||
}
|
||||
|
||||
// If neither works
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||
Message: "Unsupported provider",
|
||||
Error: "Request format doesn't match any supported provider",
|
||||
})
|
||||
}
|
||||
|
||||
// identifyProvider examines the request body to determine the provider
|
||||
|
|
@ -513,7 +494,7 @@ func (h *Handler) ListFavorites(c *fiber.Ctx) error {
|
|||
return c.Status(fiber.StatusOK).JSON(games)
|
||||
}
|
||||
|
||||
func identifyBetProvider(body []byte) (string, error) {
|
||||
func IdentifyBetProvider(body []byte) (string, error) {
|
||||
// Check for Veli signature fields
|
||||
var veliCheck struct {
|
||||
SessionID string `json:"sessionId"`
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user