Add Balance and Withdrawal
This commit is contained in:
@@ -25,6 +25,8 @@ type CryptoConfig interface {
|
||||
AccessTokenExpiresDate() time.Time
|
||||
AccessTokenResetPasswordSecret() string
|
||||
AccessTokenResetPasswordExpire() time.Time
|
||||
AccessTokenWithdrawSecret() string
|
||||
AccessTokenWithdrawExpire() time.Time
|
||||
}
|
||||
|
||||
type CryptoImpl struct {
|
||||
@@ -186,3 +188,54 @@ func (c *CryptoImpl) ValidateResetPassword(tokenString string) (int64, error) {
|
||||
|
||||
return claims.UserID, nil
|
||||
}
|
||||
|
||||
func (c *CryptoImpl) GenerateJWTWithdraw(req *entity.WalletWithdrawRequest) (string, error) {
|
||||
claims := &entity.JWTWithdrawClaims{
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
Subject: strconv.FormatInt(req.ID, 10),
|
||||
ExpiresAt: c.Config.AccessTokenWithdrawExpire().Unix(),
|
||||
IssuedAt: time.Now().Unix(),
|
||||
NotBefore: time.Now().Unix(),
|
||||
},
|
||||
PartnerID: req.PartnerID,
|
||||
Amount: req.Amount,
|
||||
Fee: req.Fee,
|
||||
Total: req.Total,
|
||||
}
|
||||
|
||||
token, err := jwt.
|
||||
NewWithClaims(jwt.SigningMethodHS256, claims).
|
||||
SignedString([]byte(c.Config.AccessTokenWithdrawSecret()))
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (c *CryptoImpl) ValidateJWTWithdraw(tokenString string) (*entity.WalletWithdrawRequest, error) {
|
||||
token, err := jwt.ParseWithClaims(tokenString, &entity.JWTWithdrawClaims{}, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return []byte(c.Config.AccessTokenWithdrawSecret()), nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
claims, ok := token.Claims.(*entity.JWTWithdrawClaims)
|
||||
if !ok || !token.Valid {
|
||||
return nil, fmt.Errorf("invalid token %v", token.Header["alg"])
|
||||
}
|
||||
|
||||
return &entity.WalletWithdrawRequest{
|
||||
ID: claims.ID,
|
||||
PartnerID: claims.PartnerID,
|
||||
Total: claims.Total,
|
||||
Amount: claims.Amount,
|
||||
Fee: claims.Fee,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -97,6 +97,8 @@ type Crypto interface {
|
||||
ValidateJWTOrder(tokenString string) (int64, int64, error)
|
||||
ValidateResetPassword(tokenString string) (int64, error)
|
||||
ParseAndValidateJWT(token string) (*entity.JWTAuthClaims, error)
|
||||
GenerateJWTWithdraw(req *entity.WalletWithdrawRequest) (string, error)
|
||||
ValidateJWTWithdraw(tokenString string) (*entity.WalletWithdrawRequest, error)
|
||||
}
|
||||
|
||||
type User interface {
|
||||
@@ -179,6 +181,7 @@ type WalletRepository interface {
|
||||
Create(ctx context.Context, tx *gorm.DB, wallet *entity.Wallet) (*entity.Wallet, error)
|
||||
Update(ctx context.Context, db *gorm.DB, wallet *entity.Wallet) (*entity.Wallet, error)
|
||||
GetByPartnerID(ctx context.Context, db *gorm.DB, partnerID int64) (*entity.Wallet, error)
|
||||
GetForUpdate(ctx context.Context, tx *gorm.DB, partnerID int64) (*entity.Wallet, error)
|
||||
}
|
||||
|
||||
type Midtrans interface {
|
||||
@@ -205,6 +208,6 @@ type License interface {
|
||||
}
|
||||
|
||||
type TransactionRepository interface {
|
||||
Create(ctx context.Context, transaction *entity.Transaction) (*entity.Transaction, error)
|
||||
Create(ctx context.Context, trx *gorm.DB, transaction *entity.Transaction) (*entity.Transaction, error)
|
||||
GetTransactionList(ctx mycontext.Context, req entity.TransactionSearch) ([]*entity.TransactionList, int, error)
|
||||
}
|
||||
|
||||
@@ -20,12 +20,20 @@ func NewTransactionRepository(db *gorm.DB) *TransactionRepository {
|
||||
}
|
||||
|
||||
// Create creates a new transaction in the database.
|
||||
func (r *TransactionRepository) Create(ctx context.Context, transaction *entity.Transaction) (*entity.Transaction, error) {
|
||||
if err := r.db.WithContext(ctx).Create(transaction).Error; err != nil {
|
||||
func (r *TransactionRepository) Create(ctx context.Context, trx *gorm.DB, transaction *entity.Transaction) (*entity.Transaction, error) {
|
||||
// Create the transaction record
|
||||
if err := trx.WithContext(ctx).Create(transaction).Error; err != nil {
|
||||
zap.L().Error("error when creating transaction", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return r.FindByID(ctx, transaction.ID)
|
||||
|
||||
// Retrieve the created transaction using the same transaction context
|
||||
var createdTransaction entity.Transaction
|
||||
if err := trx.WithContext(ctx).First(&createdTransaction, "id = ?", transaction.ID).Error; err != nil {
|
||||
zap.L().Error("error when fetching newly created transaction", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return &createdTransaction, nil
|
||||
}
|
||||
|
||||
// Update updates an existing transaction in the database.
|
||||
@@ -126,7 +134,7 @@ func (r *TransactionRepository) GetTransactionList(ctx mycontext.Context, req en
|
||||
var transactions []*entity.TransactionList
|
||||
var total int64
|
||||
|
||||
query := r.db.Table("transaction t").
|
||||
query := r.db.Table("transactions t").
|
||||
Select("t.id, t.transaction_type, t.status, t.created_at, s.name as site_name, p.name as partner_name, t.amount").
|
||||
Joins("left join sites s on t.site_id = s.id").
|
||||
Joins("left join partners p on t.partner_id = p.id").
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"context"
|
||||
"furtuna-be/internal/common/logger"
|
||||
"furtuna-be/internal/entity"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type WalletRepository struct {
|
||||
@@ -58,6 +58,22 @@ func (r *WalletRepository) GetByID(ctx context.Context, id int64) (*entity.Walle
|
||||
return wallet, nil
|
||||
}
|
||||
|
||||
func (r *WalletRepository) GetForUpdate(ctx context.Context, tx *gorm.DB, partnerID int64) (*entity.Wallet, error) {
|
||||
if tx == nil {
|
||||
tx = r.db
|
||||
}
|
||||
|
||||
query := tx.WithContext(ctx).Where("partner_id = ?", partnerID).
|
||||
Clauses(clause.Locking{Strength: "UPDATE"})
|
||||
|
||||
wallet := new(entity.Wallet)
|
||||
if err := query.First(wallet).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when finding balance by partner ID", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return wallet, nil
|
||||
}
|
||||
|
||||
func (r *WalletRepository) GetAll(ctx context.Context) ([]*entity.Wallet, error) {
|
||||
var wallets []*entity.Wallet
|
||||
if err := r.db.Find(&wallets).Error; err != nil {
|
||||
|
||||
Reference in New Issue
Block a user