|
|
|
|
package handler
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"server/call"
|
|
|
|
|
"server/common"
|
|
|
|
|
"server/config"
|
|
|
|
|
"server/db"
|
|
|
|
|
"server/modules/web/app"
|
|
|
|
|
"server/modules/web/values"
|
|
|
|
|
"server/pb"
|
|
|
|
|
"server/util"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"github.com/liangdas/mqant/log"
|
|
|
|
|
"github.com/mitchellh/mapstructure"
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func WithdrawInfo(c *gin.Context) {
|
|
|
|
|
a := app.NewApp(c)
|
|
|
|
|
defer func() {
|
|
|
|
|
a.Response()
|
|
|
|
|
}()
|
|
|
|
|
info := new(common.RechargeInfo)
|
|
|
|
|
info.UID = a.UID
|
|
|
|
|
if err := db.Mysql().Get(info); err != nil && err != gorm.ErrRecordNotFound {
|
|
|
|
|
log.Error("err:%v", err)
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
resp := values.WithDrawInfoResp{Tips: call.GetConfigPlatform().WithdrawTips}
|
|
|
|
|
|
|
|
|
|
if util.IsSameDayTimeStamp(time.Now().Unix(), info.LastWithdraw) {
|
|
|
|
|
resp.WithDrawCount = info.WithdrawCount
|
|
|
|
|
} else {
|
|
|
|
|
resp.WithDrawCount = 0
|
|
|
|
|
}
|
|
|
|
|
con := call.GetVipCon(a.UID)
|
|
|
|
|
if con != nil {
|
|
|
|
|
resp.TotalWithdrawCount = con.WithdrawCount
|
|
|
|
|
}
|
|
|
|
|
resp.Fees = append(resp.Fees, con.Fee, con.UFee)
|
|
|
|
|
resp.Channels = call.GetConfigWithdrawChannels()
|
|
|
|
|
list := call.GetConfigWithdrawProduct()
|
|
|
|
|
for _, v := range list {
|
|
|
|
|
if v.IfSell == 2 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
one := *v
|
|
|
|
|
if v.Type == common.CurrencyUSDT {
|
|
|
|
|
for _, j := range resp.Channels {
|
|
|
|
|
if j.CurrencyType == common.CurrencyUSDT {
|
|
|
|
|
if j.PayDown <= v.Amount && j.PayUp >= v.Amount {
|
|
|
|
|
one.Channels = append(one.Channels, j.ChannelID)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
resp.List = append(resp.List, one)
|
|
|
|
|
} else if v.Type == common.CurrencyINR {
|
|
|
|
|
for _, j := range resp.Channels {
|
|
|
|
|
if j.CurrencyType == common.CurrencyINR {
|
|
|
|
|
if j.PayDown <= v.Amount && j.PayUp >= v.Amount {
|
|
|
|
|
one.Channels = append(one.Channels, j.ChannelID)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
resp.List = append(resp.List, one)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for i := common.CurrencyTypeZero + 1; i < common.CurrencyAll; i++ {
|
|
|
|
|
// bet := call.GetPlayerProfileByCurrency(a.UID, i).TotalBet
|
|
|
|
|
info := call.GetPlayerRechargeInfoByCurrency(a.UID, i)
|
|
|
|
|
canWithdraw := call.GetUserCurrency(a.UID, i)
|
|
|
|
|
if canWithdraw < 0 || info.TotalRecharge == 0 {
|
|
|
|
|
canWithdraw = 0
|
|
|
|
|
}
|
|
|
|
|
resp.Bets = append(resp.Bets, canWithdraw)
|
|
|
|
|
}
|
|
|
|
|
resp.NeedBet = call.GetUserNeedBet(a.UID)
|
|
|
|
|
a.Data = resp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func WithdrawHistory(c *gin.Context) {
|
|
|
|
|
a := app.NewApp(c)
|
|
|
|
|
defer func() {
|
|
|
|
|
a.Response()
|
|
|
|
|
}()
|
|
|
|
|
req := new(values.WithdrawHistoryReq)
|
|
|
|
|
if !a.S(req) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if req.Num > 100 {
|
|
|
|
|
req.Num = 100
|
|
|
|
|
}
|
|
|
|
|
// log.Debug("withdraw history req:%+v", *req)
|
|
|
|
|
ret := []common.WithdrawOrder{}
|
|
|
|
|
var count int64
|
|
|
|
|
var err error
|
|
|
|
|
count, err = db.Mysql().QueryListW(req.Page, req.Num, "create_time desc",
|
|
|
|
|
&common.WithdrawOrder{UID: a.UID}, &ret, "uid = ? and event = ?",
|
|
|
|
|
a.UID, common.CurrencyEventWithDraw)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Error("err:%v", err)
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
for i, v := range ret {
|
|
|
|
|
if v.Status == common.StatusROrderCreate || v.Status == common.StatusROrderWaitting {
|
|
|
|
|
ret[i].Status = common.StatusROrderPay
|
|
|
|
|
} else if v.Status == common.StatusROrderRefuse {
|
|
|
|
|
ret[i].Status = common.StatusROrderFail
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
resp := values.WithdrawHistoryResp{
|
|
|
|
|
Count: count,
|
|
|
|
|
List: ret,
|
|
|
|
|
}
|
|
|
|
|
a.Data = resp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func PlayerWithdrawBlock(c *gin.Context) {
|
|
|
|
|
a := app.NewApp(c)
|
|
|
|
|
resp := &values.WithdrawResp{}
|
|
|
|
|
defer func() {
|
|
|
|
|
a.Data = resp
|
|
|
|
|
log.Debug("player %v PlayerWithdraw code:%v", a.UID, a.Code)
|
|
|
|
|
a.Response()
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
req := new(values.WithdrawBlockReq)
|
|
|
|
|
if !a.S(req) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if req.CurrencyType != common.CurrencyUSDT {
|
|
|
|
|
a.Code = values.CodeParam
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
uid := a.UID
|
|
|
|
|
log.Debug("player %v withdrawblock %+v", uid, *req)
|
|
|
|
|
req.Amount = common.RoundCurrency(req.CurrencyType, req.Amount)
|
|
|
|
|
|
|
|
|
|
// 退出条件限制
|
|
|
|
|
if !a.CheckWithdrawCondition(req.Amount, req.CurrencyType) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
has := call.GetUserCurrency(a.UID, req.CurrencyType)
|
|
|
|
|
need := req.Amount
|
|
|
|
|
con := call.GetVipCon(uid)
|
|
|
|
|
if con != nil && con.UFee > 0 {
|
|
|
|
|
need += con.UFee
|
|
|
|
|
}
|
|
|
|
|
if has < need {
|
|
|
|
|
log.Error("err not enough cash:%v,%v", has, need)
|
|
|
|
|
a.Code = values.CodeWithdrawNotEnough
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 拉取玩家退出信息
|
|
|
|
|
re := call.GetRechargeInfo(a.UID)
|
|
|
|
|
now := time.Now().Unix()
|
|
|
|
|
if re.ID == 0 {
|
|
|
|
|
re.LastWithdraw = now
|
|
|
|
|
if err := db.Mysql().Create(re); err != nil {
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
u := map[string]interface{}{"last_withdraw": now}
|
|
|
|
|
if !util.IsSameDayTimeStamp(now, re.LastWithdraw) {
|
|
|
|
|
u["withdraw_count"] = 0
|
|
|
|
|
u["day_withdraw"] = 0
|
|
|
|
|
}
|
|
|
|
|
rows, err := db.Mysql().UpdateRes(&common.RechargeInfo{UID: uid, LastWithdraw: re.LastWithdraw}, u)
|
|
|
|
|
if err != nil || rows == 0 {
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
orderID := "USDT" + util.NewOrderID(uid)
|
|
|
|
|
// 第一步,先扣钱
|
|
|
|
|
err := call.MineCurrencyProReal(&common.UpdateCurrency{
|
|
|
|
|
CurrencyBalance: &common.CurrencyBalance{
|
|
|
|
|
UID: a.UID,
|
|
|
|
|
Event: common.CurrencyEventWithDraw,
|
|
|
|
|
Type: common.CurrencyUSDT,
|
|
|
|
|
Value: -need,
|
|
|
|
|
Exs1: orderID,
|
|
|
|
|
ChannelID: a.Channel,
|
|
|
|
|
},
|
|
|
|
|
}).Err
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Error("player %v mines cash err:%v", uid, err)
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 直接发起退出
|
|
|
|
|
shouldAuto := call.CanAutoWithdraw(uid, re.TotalRecharge, re.TotalWithdraw+re.TotalWithdrawing+need)
|
|
|
|
|
// 第二步,创建订单
|
|
|
|
|
orderStatus := common.StatusROrderCreate
|
|
|
|
|
if shouldAuto {
|
|
|
|
|
orderStatus = common.StatusROrderWaitting
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order := &common.WithdrawOrder{
|
|
|
|
|
UID: uid,
|
|
|
|
|
OrderID: orderID,
|
|
|
|
|
APIPayID: "",
|
|
|
|
|
// ProductID: one.ID,
|
|
|
|
|
CreateTime: time.Now().Unix(),
|
|
|
|
|
Amount: req.Amount,
|
|
|
|
|
WithdrawCash: need,
|
|
|
|
|
Status: uint8(orderStatus),
|
|
|
|
|
PaySource: common.PaySourceBlockPay,
|
|
|
|
|
CurrencyType: req.CurrencyType,
|
|
|
|
|
Event: int(common.CurrencyEventWithDraw),
|
|
|
|
|
PayAccount: req.Address,
|
|
|
|
|
ChannelID: a.Channel,
|
|
|
|
|
}
|
|
|
|
|
if err := db.Mysql().Create(order); err != nil {
|
|
|
|
|
log.Error("player %v create WithdrawBlock order fail err:%v", uid, err)
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u := map[string]interface{}{}
|
|
|
|
|
u["withdraw_count"] = gorm.Expr("withdraw_count + ?", 1)
|
|
|
|
|
db.Mysql().Update(&common.RechargeInfo{UID: uid}, u)
|
|
|
|
|
call.UpdatePlayerRechargeInfoCurrency(uid, req.CurrencyType, map[string]interface{}{"total_withdrawing": gorm.Expr("total_withdrawing + ?", need)})
|
|
|
|
|
// 直接发起退出
|
|
|
|
|
// util.Go(func() {
|
|
|
|
|
// call.SendWithdrawMail(uid, call.MailWithdrawType2)
|
|
|
|
|
// })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func PlayerWithdrawCheck(c *gin.Context) {
|
|
|
|
|
a := app.NewApp(c)
|
|
|
|
|
defer func() {
|
|
|
|
|
log.Debug("player %v PlayerWithdrawCheck code:%v,msg:%v", a.UID, a.Code, a.Msg)
|
|
|
|
|
a.Response()
|
|
|
|
|
}()
|
|
|
|
|
req := new(values.WithdrawCheckReq)
|
|
|
|
|
if !a.S(req) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
a.CheckWithdrawCondition(req.Amount, common.CurrencyINR)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func PlayerWithdraw(c *gin.Context) {
|
|
|
|
|
a := app.NewApp(c)
|
|
|
|
|
resp := &values.WithdrawResp{}
|
|
|
|
|
a.Data = resp
|
|
|
|
|
defer func() {
|
|
|
|
|
log.Debug("player %v PlayerWithdraw code:%v", a.UID, a.Code)
|
|
|
|
|
a.Response()
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
req := new(values.WithdrawReq)
|
|
|
|
|
if !a.S(req) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if req.CurrencyType != common.CurrencyINR {
|
|
|
|
|
log.Error("invalid type:%v", req.CurrencyType)
|
|
|
|
|
req.CurrencyType = common.CurrencyINR
|
|
|
|
|
}
|
|
|
|
|
uid := a.UID
|
|
|
|
|
log.Debug("player %v withdraw %+v", uid, *req)
|
|
|
|
|
req.Amount = common.RoundCurrency(req.CurrencyType, req.Amount)
|
|
|
|
|
|
|
|
|
|
// 退出条件限制
|
|
|
|
|
if !a.CheckWithdrawCondition(req.Amount, req.CurrencyType) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ip := a.GetRemoteIP()
|
|
|
|
|
payInfo, code := NewWithdraw(req, uid, ip, a.UUID)
|
|
|
|
|
if code != values.CodeOK {
|
|
|
|
|
a.Code = code
|
|
|
|
|
a.Msg = payInfo
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(payInfo) > 500 {
|
|
|
|
|
a.Code = values.CodeParam
|
|
|
|
|
a.Msg = "Withdrawal information too long."
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
user := new(common.PlayerDBInfo)
|
|
|
|
|
user.Id = uid
|
|
|
|
|
if err := db.Mysql().Get(user); err != nil {
|
|
|
|
|
log.Error("err:%v", err)
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
need := req.Amount
|
|
|
|
|
has := call.GetUserCurrency(a.UID, req.CurrencyType)
|
|
|
|
|
if need > has {
|
|
|
|
|
log.Error("err not enough cash:%v,%v", has, need)
|
|
|
|
|
a.Code = values.CodeWithdrawNotEnough
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
re := call.GetRechargeInfo(a.UID)
|
|
|
|
|
now := time.Now().Unix()
|
|
|
|
|
if re.ID == 0 {
|
|
|
|
|
re.LastWithdraw = now
|
|
|
|
|
if err := db.Mysql().Create(re); err != nil {
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
u := map[string]interface{}{"last_withdraw": now}
|
|
|
|
|
if !util.IsSameDayTimeStamp(now, re.LastWithdraw) {
|
|
|
|
|
u["withdraw_count"] = 0
|
|
|
|
|
u["day_withdraw"] = 0
|
|
|
|
|
}
|
|
|
|
|
rows, err := db.Mysql().UpdateRes(&common.RechargeInfo{UID: uid, LastWithdraw: re.LastWithdraw}, u)
|
|
|
|
|
if err != nil || rows == 0 {
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
orderID := util.NewOrderID(uid)
|
|
|
|
|
// 第一步,先扣钱
|
|
|
|
|
pro := call.MineCurrencyProReal(&common.UpdateCurrency{
|
|
|
|
|
CurrencyBalance: &common.CurrencyBalance{
|
|
|
|
|
UID: uid,
|
|
|
|
|
Value: -need,
|
|
|
|
|
Event: common.CurrencyEventWithDraw,
|
|
|
|
|
Type: req.CurrencyType,
|
|
|
|
|
Exs1: orderID,
|
|
|
|
|
ChannelID: a.Channel,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
if pro.Err != nil {
|
|
|
|
|
log.Error("err:%v", pro.Err)
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
con := call.GetVipCon(uid)
|
|
|
|
|
realAmount := need // 实际打款
|
|
|
|
|
if con != nil && con.Fee > 0 {
|
|
|
|
|
realAmount = common.RoundCurrency(req.CurrencyType, (1000-int64(con.Fee))*realAmount/1000) - 600 // 固定税费
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var shouldAuto = false
|
|
|
|
|
// 在总赠送比配置比例小时才判断个人
|
|
|
|
|
if call.GetTotalRechargePer(realAmount) < config.GetConfig().Web.TotalWithdrawPer {
|
|
|
|
|
// 直接发起退出
|
|
|
|
|
shouldAuto = call.CanAutoWithdraw(uid, re.TotalRecharge, re.TotalWithdraw+re.TotalWithdrawing+realAmount)
|
|
|
|
|
}
|
|
|
|
|
// 第二步,创建订单
|
|
|
|
|
withdrawChannel := -1
|
|
|
|
|
if req.ChannelID != nil {
|
|
|
|
|
withdrawChannel = *req.ChannelID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
orderStatus := common.StatusROrderCreate
|
|
|
|
|
if shouldAuto {
|
|
|
|
|
orderStatus = common.StatusROrderWaitting
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order := &common.WithdrawOrder{
|
|
|
|
|
UID: uid,
|
|
|
|
|
OrderID: orderID,
|
|
|
|
|
APIPayID: "",
|
|
|
|
|
// ProductID: one.ID,
|
|
|
|
|
CreateTime: time.Now().Unix(),
|
|
|
|
|
Amount: realAmount,
|
|
|
|
|
WithdrawCash: need,
|
|
|
|
|
Status: uint8(orderStatus),
|
|
|
|
|
PaySource: common.PaySourceModulePay,
|
|
|
|
|
Event: int(common.CurrencyEventWithDraw),
|
|
|
|
|
CurrencyType: req.CurrencyType,
|
|
|
|
|
PayAccount: payInfo,
|
|
|
|
|
ChannelID: a.Channel,
|
|
|
|
|
UPI: withdrawChannel,
|
|
|
|
|
}
|
|
|
|
|
if err := db.Mysql().Create(order); err != nil {
|
|
|
|
|
log.Error("player %v create withdraw order fail err:%v", uid, err)
|
|
|
|
|
a.Code = values.CodeRetry
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
resp.Balance = pro.Balance
|
|
|
|
|
resp.WithdrawBalance = has - need
|
|
|
|
|
u := map[string]interface{}{}
|
|
|
|
|
u["withdrawing_cash"] = gorm.Expr("withdrawing_cash + ?", need)
|
|
|
|
|
u["withdraw_count"] = gorm.Expr("withdraw_count + ?", 1)
|
|
|
|
|
u["total_withdrawing"] = gorm.Expr("total_withdrawing + ?", realAmount)
|
|
|
|
|
u["day_withdraw"] = gorm.Expr("day_withdraw + ?", realAmount)
|
|
|
|
|
db.Mysql().Update(&common.RechargeInfo{UID: uid}, u)
|
|
|
|
|
// call.UpdatePlayerRechargeInfoCurrency(uid, req.CurrencyType, map[string]interface{}{"total_withdrawing": gorm.Expr("total_withdrawing + ?", need)})
|
|
|
|
|
// 直接发起退出
|
|
|
|
|
// util.Go(func() {
|
|
|
|
|
// call.SendWithdrawMail(uid, call.MailWithdrawType2)
|
|
|
|
|
// })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回值在code不为0的时候,代表错误msg
|
|
|
|
|
func NewWithdraw(req *values.WithdrawReq, uid int, ip string, uuid string) (string, int) {
|
|
|
|
|
one := common.WithdrawCommon{}
|
|
|
|
|
err := mapstructure.Decode(req.PayAccount, &one)
|
|
|
|
|
if err != nil || one.BankCode == "" {
|
|
|
|
|
log.Error("NewWithdrawImp err:%v,one:%+v", err, one)
|
|
|
|
|
return "", values.CodeParam
|
|
|
|
|
}
|
|
|
|
|
one.PayType = common.PayTypeBank
|
|
|
|
|
if one.PayType == common.PayTypeUPI {
|
|
|
|
|
return "The UPI channel is closed, please use the bank channel to withdraw cash.", values.CodeParam
|
|
|
|
|
}
|
|
|
|
|
if !one.PayType.Isvalid() {
|
|
|
|
|
log.Error("NewWithdrawImp err:%v,one:%+v", err, one)
|
|
|
|
|
return "", values.CodeParam
|
|
|
|
|
}
|
|
|
|
|
one.DeviceNo = uuid
|
|
|
|
|
one.AccountName = strings.TrimSpace(one.AccountName)
|
|
|
|
|
one.BankCardNo = strings.TrimSpace(one.BankCardNo)
|
|
|
|
|
one.BankCode = strings.TrimSpace(one.BankCode)
|
|
|
|
|
one.IP = ip
|
|
|
|
|
if one.PayType == common.PayTypeBank && len(one.BankCode) != 11 {
|
|
|
|
|
return "The IFSC Code shall be 11 digital letters.", values.CodeParam
|
|
|
|
|
}
|
|
|
|
|
if one.PayType == common.PayTypeBank && one.BankCardNo == "" && one.AccountName == "" && one.Email == "" {
|
|
|
|
|
log.Error("NewWithdrawImp 银行卡支付,银行卡号不能为空 one:%+v", one)
|
|
|
|
|
return "The Bank Card No should not be empty.", values.CodeParam
|
|
|
|
|
}
|
|
|
|
|
user, _ := call.GetUserXInfo(uid, "mobile")
|
|
|
|
|
if user.Mobile == "" {
|
|
|
|
|
return "", values.CodeParam
|
|
|
|
|
}
|
|
|
|
|
_ = mapstructure.Decode(req.PayAccount, &one)
|
|
|
|
|
if one.Mobile == "" {
|
|
|
|
|
one.Mobile = user.Mobile
|
|
|
|
|
}
|
|
|
|
|
// 判断是否是拉黑用户,拉黑用户不让代付
|
|
|
|
|
blackData := &common.BlackList{Phone: one.Mobile, PayAccount: one.BankCardNo, Email: one.Email, Name: one.AccountName}
|
|
|
|
|
if one.PayType == common.PayTypeUPI {
|
|
|
|
|
blackData.PayAccount = one.BankCode
|
|
|
|
|
}
|
|
|
|
|
if call.BlackListAndKick(uid, blackData) {
|
|
|
|
|
return "", values.CodeRetry
|
|
|
|
|
}
|
|
|
|
|
// 如果是银行那卡代付,验证ifsc
|
|
|
|
|
if one.PayType == common.PayTypeBank {
|
|
|
|
|
if !call.CheckIFSC(one.BankCode) {
|
|
|
|
|
return "The IFSC Code is invalid.", values.CodeParam
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询该银行卡是否已经绑定其他账号
|
|
|
|
|
pi := &common.PayInfo{UID: uid}
|
|
|
|
|
_ = db.Mysql().Get(pi)
|
|
|
|
|
if one.PayType == common.PayTypeBank {
|
|
|
|
|
if pi.BankCardNo != one.BankCardNo {
|
|
|
|
|
sql := fmt.Sprintf("bank_card_no = '%v'", one.BankCardNo)
|
|
|
|
|
if db.Mysql().Count(&common.PayInfo{}, sql) >= int64(config.GetConfig().Web.MaxBankCardCount) {
|
|
|
|
|
return "", values.CodeBankCardNoLimit
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if one.PayType == common.PayTypeUPI { // UPI
|
|
|
|
|
if pi.BankCode != one.BankCode {
|
|
|
|
|
sql := fmt.Sprintf("bank_code = '%v'", one.BankCode)
|
|
|
|
|
if db.Mysql().Count(&common.PayInfo{}, sql) >= int64(config.GetConfig().Web.MaxBankCardCount) {
|
|
|
|
|
return "", values.CodeBankCardNoLimit
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
info := &common.PayInfo{
|
|
|
|
|
UID: uid,
|
|
|
|
|
DeviceNo: one.DeviceNo,
|
|
|
|
|
// Device: one.Device,
|
|
|
|
|
PhoneModel: one.Model,
|
|
|
|
|
OperatorOs: one.OperatorOs,
|
|
|
|
|
AccountName: one.AccountName,
|
|
|
|
|
Mobile: one.Mobile,
|
|
|
|
|
Email: one.Email,
|
|
|
|
|
BankCardNo: one.BankCardNo,
|
|
|
|
|
PayType: one.PayType,
|
|
|
|
|
BankCode: one.BankCode,
|
|
|
|
|
// Address: one.Address,
|
|
|
|
|
}
|
|
|
|
|
if _, err := db.Mysql().Upsert(fmt.Sprintf("uid = %v", uid), info); err != nil {
|
|
|
|
|
return "", values.CodeParam
|
|
|
|
|
}
|
|
|
|
|
ret, err := json.Marshal(one)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Error("err:%v", err)
|
|
|
|
|
return "", values.CodeParam
|
|
|
|
|
}
|
|
|
|
|
return string(ret), values.CodeOK
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewWithdrawImp(order *common.WithdrawOrder) *WithdrawImp {
|
|
|
|
|
base := new(WithdrawImp)
|
|
|
|
|
// uid := order.UID
|
|
|
|
|
cid := order.ChannelID
|
|
|
|
|
base.Channel = call.GetChannelByID(cid)
|
|
|
|
|
if base.Channel == nil {
|
|
|
|
|
log.Error("invalid cid:%v", cid)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
base.order = order
|
|
|
|
|
one := new(PayWithdraw)
|
|
|
|
|
base.SubWithdraw = one
|
|
|
|
|
one.base = base
|
|
|
|
|
return base
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WithdrawImp 发起退出对象
|
|
|
|
|
type WithdrawImp struct {
|
|
|
|
|
order *common.WithdrawOrder
|
|
|
|
|
// tx *gorm.DB
|
|
|
|
|
SubWithdraw WithdrawInter
|
|
|
|
|
Channel *common.Channel
|
|
|
|
|
PayChannel int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w *WithdrawImp) BaseWithdraw() error {
|
|
|
|
|
var err error
|
|
|
|
|
// uid := w.order.UID
|
|
|
|
|
defer func() {
|
|
|
|
|
if err != nil {
|
|
|
|
|
call.ReturnBackWithdraw(w.order, common.StatusROrderPay, common.StatusROrderFail, w.PayChannel)
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
res := db.Mysql().C().Model(w.order).Where("status = ?", common.StatusROrderCreate).Updates(map[string]interface{}{"status": common.StatusROrderPay})
|
|
|
|
|
if res.Error != nil {
|
|
|
|
|
// w.tx.Rollback()
|
|
|
|
|
log.Error("sub withdraw err:%v", err)
|
|
|
|
|
return res.Error
|
|
|
|
|
}
|
|
|
|
|
if res.RowsAffected == 0 {
|
|
|
|
|
// w.tx.Rollback()
|
|
|
|
|
log.Error("sub withdraw err:%v", err)
|
|
|
|
|
return errors.New("invalid order")
|
|
|
|
|
}
|
|
|
|
|
err = w.SubWithdraw.Withdraw()
|
|
|
|
|
if err != nil {
|
|
|
|
|
// w.tx.Rollback()
|
|
|
|
|
log.Error("sub withdraw err:%v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
// err = w.tx.Commit().Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// log.Error("commit BaseWithdraw err:%v", err)
|
|
|
|
|
// return err
|
|
|
|
|
// }
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w *WithdrawImp) AutoWithdraw() error {
|
|
|
|
|
err := w.SubWithdraw.AutoWithdraw()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type WithdrawInter interface {
|
|
|
|
|
Withdraw() error
|
|
|
|
|
AutoWithdraw() error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PayWithdraw pay模块退出
|
|
|
|
|
type PayWithdraw struct {
|
|
|
|
|
base *WithdrawImp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *PayWithdraw) Withdraw() error {
|
|
|
|
|
order := p.base.order
|
|
|
|
|
req := &pb.InnerWithdrawReq{
|
|
|
|
|
OrderID: order.OrderID,
|
|
|
|
|
Amount: order.Amount,
|
|
|
|
|
UID: uint32(order.UID),
|
|
|
|
|
Channel: int64(order.UPI),
|
|
|
|
|
PaySource: uint32(order.PaySource),
|
|
|
|
|
}
|
|
|
|
|
if req.PaySource == common.PaySourceModulePay {
|
|
|
|
|
send := new(common.WithdrawCommon)
|
|
|
|
|
err := json.Unmarshal([]byte(order.PayAccount), &send)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Error("withdraw unmarshal err %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
req.Phone = send.Mobile
|
|
|
|
|
req.Name = send.Name
|
|
|
|
|
req.Email = send.Email
|
|
|
|
|
req.PayType = int64(send.PayType)
|
|
|
|
|
req.PayCode = send.BankCode
|
|
|
|
|
req.CardNo = send.BankCardNo
|
|
|
|
|
req.Name = send.AccountName
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
ret, err := call.Withdraw(req)
|
|
|
|
|
if ret != nil {
|
|
|
|
|
p.base.PayChannel = int(ret.Channel)
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Error("err:%v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
or := &common.WithdrawOrder{
|
|
|
|
|
Status: common.StatusROrderPay, APIPayID: ret.APIOrderID,
|
|
|
|
|
PaySource: common.PaySourceModulePay}
|
|
|
|
|
or.ID = order.ID
|
|
|
|
|
res := db.Mysql().C().Model(order).Updates(or)
|
|
|
|
|
err = res.Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Error("update order err:%v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if res.RowsAffected == 0 {
|
|
|
|
|
log.Error("update order fail orderid:%v", order.ID)
|
|
|
|
|
return errors.New("update order fail")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *PayWithdraw) AutoWithdraw() error {
|
|
|
|
|
order := p.base.order
|
|
|
|
|
req := &pb.InnerWithdrawReq{
|
|
|
|
|
OrderID: order.OrderID,
|
|
|
|
|
Amount: order.Amount,
|
|
|
|
|
UID: uint32(order.UID),
|
|
|
|
|
Channel: int64(order.UPI),
|
|
|
|
|
PaySource: uint32(order.PaySource),
|
|
|
|
|
}
|
|
|
|
|
if req.PaySource == common.PaySourceModulePay {
|
|
|
|
|
send := new(common.WithdrawCommon)
|
|
|
|
|
err := json.Unmarshal([]byte(order.PayAccount), &send)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Error("withdraw unmarshal err %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
req.Phone = send.Mobile
|
|
|
|
|
req.Name = send.Name
|
|
|
|
|
req.Email = send.Email
|
|
|
|
|
req.PayType = int64(send.PayType)
|
|
|
|
|
req.BankName = send.BankName
|
|
|
|
|
req.CardNo = send.BankCode
|
|
|
|
|
// req.Address = send.Address
|
|
|
|
|
// req.Number = send.Number
|
|
|
|
|
} else {
|
|
|
|
|
req.Address = order.PayAccount
|
|
|
|
|
}
|
|
|
|
|
ret, err := call.Withdraw(req)
|
|
|
|
|
if ret != nil {
|
|
|
|
|
p.base.PayChannel = int(ret.Channel)
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
p.base.order.APIPayID = ret.APIOrderID
|
|
|
|
|
p.base.order.Status = common.StatusROrderPay
|
|
|
|
|
p.base.order.PayChannel = int(ret.Channel)
|
|
|
|
|
return nil
|
|
|
|
|
}
|