@@ -179,8 +179,8 @@ func (l *ActivateOrderLogic) NewPurchase(ctx context.Context, orderInfo *order.O
return err
}
// Handle referral reward in separate goroutine to avoid blocking
go l . handleReferralReward ( context . Background ( ) , userInfo , orderInfo )
// Handle commission in separate goroutine to avoid blocking
go l . handleCommission ( context . Background ( ) , userInfo , orderInfo )
// Clear cache
l . clearServerCache ( ctx , sub )
@@ -192,12 +192,12 @@ func (l *ActivateOrderLogic) NewPurchase(ctx context.Context, orderInfo *order.O
return nil
}
// getUserOrCreate retrieves an existing user or creates a new user based on order details
// getUserOrCreate retrieves an existing user or creates a new guest user based on order details
func ( l * ActivateOrderLogic ) getUserOrCreate ( ctx context . Context , orderInfo * order . Order ) ( * user . User , error ) {
if orderInfo . UserId != 0 {
return l . getExistingUser ( ctx , orderInfo . UserId )
}
return l . createUserFromTempOrder ( ctx , orderInfo )
return l . createGuestUser ( ctx , orderInfo )
}
// getExistingUser retrieves user information by user ID
@@ -213,9 +213,9 @@ func (l *ActivateOrderLogic) getExistingUser(ctx context.Context, userId int64)
return userInfo , nil
}
// createUserFromTempOrd er creates a new user account using temporary order information
// stored in Redis cache. All users created this way are formal users, not guests.
func ( l * ActivateOrderLogic ) createUserFromTempOrder ( ctx context . Context , orderInfo * order . Order ) ( * user . User , error ) {
// createGuestUs er creates a new user account for guest orders using temporary order information
// stored in Redis cache
func ( l * ActivateOrderLogic ) createGuestUser ( ctx context . Context , orderInfo * order . Order ) ( * user . User , error ) {
tempOrder , err := l . getTempOrderInfo ( ctx , orderInfo . OrderNo )
if err != nil {
return nil , err
@@ -223,6 +223,7 @@ func (l *ActivateOrderLogic) createUserFromTempOrder(ctx context.Context, orderI
userInfo := & user . User {
Password : tool . EncodePassWord ( tempOrder . Password ) ,
Algo : "default" ,
AuthMethods : [ ] user . AuthMethods {
{
AuthType : tempOrder . AuthType ,
@@ -253,7 +254,7 @@ func (l *ActivateOrderLogic) createUserFromTempOrder(ctx context.Context, orderI
// Handle referrer relationship
l . handleReferrer ( ctx , userInfo , tempOrder . InviteCode )
logger . WithContext ( ctx ) . Info ( "Create user success" ,
logger . WithContext ( ctx ) . Info ( "Create guest user success" ,
logger . Field ( "user_id" , userInfo . Id ) ,
logger . Field ( "identifier" , tempOrder . Identifier ) ,
logger . Field ( "auth_type" , tempOrder . AuthType ) ,
@@ -349,12 +350,10 @@ func (l *ActivateOrderLogic) createUserSubscription(ctx context.Context, orderIn
return userSub , nil
}
// handleReferralReward processes referral rewards for the referrer if applicable.
// handleCommission processes referral commission for the referrer if applicable.
// This runs asynchronously to avoid blocking the main order processing flow.
// If referral percentage > 0: commission reward
// If referral percentage = 0: gift days to both parties
func ( l * ActivateOrderLogic ) handleReferralReward ( ctx context . Context , userInfo * user . User , orderInfo * order . Order ) {
if ! l . shouldProcessReferralReward ( userInfo , orderInfo . IsNew ) {
func ( l * ActivateOrderLogic ) handleCommission ( ctx context . Context , userInfo * user . User , orderInfo * order . Order ) {
if ! l . shouldProcessCommission ( userInfo , orderInfo . IsNew ) {
return
}
@@ -374,25 +373,13 @@ func (l *ActivateOrderLogic) handleReferralReward(ctx context.Context, userInfo
referralPercentage = uint8 ( l . svc . Config . Invite . ReferralPercentage )
}
// Check if this is commission reward or gift days reward
if referralPercentage > 0 {
// Commission reward mode
l . processCommissionReward ( ctx , referer , orderInfo , referralPercentage )
} else {
// Gift days reward mode
l . processGiftDaysReward ( ctx , referer , userInfo , orderInfo )
}
}
// processCommissionReward handles commission-based rewards
func ( l * ActivateOrderLogic ) processCommissionReward ( ctx context . Context , referer * user . User , orderInfo * order . Order , percentage uint8 ) {
// Order commission calculation: (Order Amount - Order Fee) * Referral Percentage
amount := l . calculateCommission ( orderInfo . Amount - orderInfo . FeeAmount , percentage )
amount := l . calculateCommission ( orderInfo . Amount - orderInfo . FeeAmount , referralPercentage )
// Use transaction for commission updates
err := l . svc . DB . Transaction ( func ( tx * gorm . DB ) error {
err = l . svc . DB . Transaction ( func ( tx * gorm . DB ) error {
referer . Commission += amount
if err := l . svc . UserModel . Update ( ctx , referer , tx ) ; err != nil {
if err = l . svc . UserModel . Update ( ctx , referer , tx ) ; err != nil {
return err
}
@@ -434,73 +421,9 @@ func (l *ActivateOrderLogic) processCommissionReward(ctx context.Context, refere
}
}
// processGiftDaysReward handl es g ift days rewards for both parties
func ( l * ActivateOrderLogic ) processGiftDaysReward ( ctx context . Context , referer * user . User , referee * user . User , orderInfo * order . Order ) {
giftDays := l . svc . Config . Invite . GiftDays
if giftDays <= 0 {
giftDays = 3 // Default to 3 days
}
// Get the subscription info to determine the unit time
sub , err := l . getSubscribeInfo ( ctx , orderInfo . SubscribeId )
if err != nil {
logger . WithContext ( ctx ) . Error ( "Get subscribe info failed for gift days" ,
logger . Field ( "error" , err . Error ( ) ) ,
logger . Field ( "subscribe_id" , orderInfo . SubscribeId ) ,
)
return
}
// Grant gift days to both referer and referee
l . grantGiftDays ( ctx , referer , giftDays , sub . UnitTime , "referer" )
l . grantGiftDays ( ctx , referee , giftDays , sub . UnitTime , "referee" )
}
// grantGiftDays grants gift days to a user by extending their subscription
func ( l * ActivateOrderLogic ) grantGiftDays ( ctx context . Context , user * user . User , days int64 , unitTime string , role string ) {
// Find user's active subscription
userSub , err := l . svc . UserModel . FindActiveSubscribe ( ctx , user . Id )
if err != nil {
logger . WithContext ( ctx ) . Error ( "Find user active subscription failed for gift days" ,
logger . Field ( "error" , err . Error ( ) ) ,
logger . Field ( "user_id" , user . Id ) ,
logger . Field ( "role" , role ) ,
)
return
}
if userSub == nil {
logger . WithContext ( ctx ) . Info ( "User has no active subscription for gift days" ,
logger . Field ( "user_id" , user . Id ) ,
logger . Field ( "role" , role ) ,
)
return
}
// Extend subscription by gift days
userSub . ExpireTime = tool . AddTime ( "day" , days , userSub . ExpireTime )
err = l . svc . UserModel . UpdateSubscribe ( ctx , userSub )
if err != nil {
logger . WithContext ( ctx ) . Error ( "Update user subscription for gift days failed" ,
logger . Field ( "error" , err . Error ( ) ) ,
logger . Field ( "user_id" , user . Id ) ,
logger . Field ( "role" , role ) ,
)
return
}
logger . WithContext ( ctx ) . Info ( "Gift days granted successfully" ,
logger . Field ( "user_id" , user . Id ) ,
logger . Field ( "role" , role ) ,
logger . Field ( "days" , days ) ,
logger . Field ( "new_expire_time" , userSub . ExpireTime ) ,
)
}
// shouldProcessReferralReward determines if referral reward should be processed based on
// shouldProcessCommission determin es if commission should be processed based on
// referrer existence, commission settings, and order type
func ( l * ActivateOrderLogic ) shouldProcessReferralReward ( userInfo * user . User , isFirstPurchase bool ) bool {
func ( l * ActivateOrderLogic ) shouldProcessCommission ( userInfo * user . User , isFirstPurchase bool ) bool {
if userInfo == nil || userInfo . RefererId == 0 {
return false
}
@@ -582,8 +505,8 @@ func (l *ActivateOrderLogic) Renewal(ctx context.Context, orderInfo *order.Order
// Clear cache
l . clearServerCache ( ctx , sub )
// Handle referral reward
go l . handleReferralReward ( context . Background ( ) , userInfo , orderInfo )
// Handle commission
go l . handleCommission ( context . Background ( ) , userInfo , orderInfo )
// Send notifications
l . sendNotifications ( ctx , orderInfo , userInfo , sub , userSub , telegram . RenewalNotify )