You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.3 KiB
151 lines
4.3 KiB
package pay |
|
|
|
import ( |
|
"errors" |
|
"server/call" |
|
"server/common" |
|
"server/db" |
|
"server/modules/pay/allpay" |
|
"server/modules/pay/base" |
|
"server/modules/pay/values" |
|
"server/pb" |
|
"server/util" |
|
"sync/atomic" |
|
"time" |
|
|
|
"github.com/gogo/protobuf/proto" |
|
"github.com/liangdas/mqant/log" |
|
) |
|
|
|
func Recharge(req *pb.InnerRechargeReq) (ret []byte, err error) { |
|
// 还原amount |
|
// req.Amount /= common.DecimalDigits |
|
payWay := values.PayWay(req.Channel) |
|
log.Debug("recharge req:%+v,channel:%+v", req, payWay) |
|
// 首先判断个卡 |
|
// if req.IsPersonalCard && values.IsPayChannelValid(int(values.IGeekPay), req.Amount) { |
|
// payWay = values.IGeekPay |
|
// } else { |
|
// payWay = values.ChoosePayWay(int(req.UID), int(req.Channel), req.Amount) |
|
// } |
|
var isReplace bool |
|
if req.Channel == 0 { |
|
var weightChannel uint32 |
|
for _, v := range call.GetConfigPayChannels() { |
|
if req.Amount*common.DecimalDigits <= v.PayUp && req.Amount*common.DecimalDigits >= v.PayDown && v.CurrencyType == common.CurrencyINR { |
|
weightChannel = uint32(v.ChannelID) |
|
break |
|
} |
|
} |
|
for _, v := range call.GetConfigPayChannels() { |
|
if req.Amount*common.DecimalDigits <= v.PayUp && req.Amount*common.DecimalDigits >= v.PayDown && v.CurrencyType == common.CurrencyINR { |
|
if !db.Redis().Lock(common.GetRedisKeyUserPay(v.ChannelID, int(req.UID), int(req.Amount)), 1*time.Minute) { |
|
continue |
|
} |
|
if weightChannel != uint32(v.ChannelID) { |
|
log.Debug("recharge, replace pay channel, %v:%v", req.UID, v.ChannelID) |
|
isReplace = true |
|
} |
|
weightChannel = uint32(v.ChannelID) |
|
break |
|
} |
|
} |
|
req.Channel = weightChannel |
|
} |
|
_ = isReplace |
|
if req.Channel == 0 { |
|
log.Error("get channel err, is 0") |
|
} |
|
payWay = values.PayWay(req.Channel) |
|
base := base.NewRechargeBase(req) |
|
allpay.NewSub(base, int(req.Channel)) |
|
start := time.Now() |
|
if base.Sub != nil { |
|
ret, err = base.Req() |
|
} else { |
|
ret, err = nil, errors.New("inner error") |
|
} |
|
|
|
// 充值返回时间过长 |
|
t := time.Since(start).Milliseconds() |
|
if t >= 8000 { |
|
log.Debug("longpay:%v,time:%v", payWay, t) |
|
db.ES().InsertToESGO(common.ESIndexLongPay, &common.ESLongPay{Channel: int(payWay), Time: start.Unix(), |
|
Cost: t, Date: start.Format("2006-01-02 15:04:05"), UID: int(req.UID), Amount: req.Amount}) |
|
} |
|
if err != nil { |
|
values.PayFail(payWay) |
|
} |
|
return |
|
} |
|
|
|
func Withdraw(req *pb.InnerWithdrawReq) ([]byte, error) { |
|
// 还原amount |
|
// req.Amount /= common.DecimalDigits |
|
var channel *common.ConfigWithdrawChannels |
|
if req.Channel >= 0 { |
|
channel = call.GetConfigWithdrawChannelsByID(int(req.Channel), common.CurrencyINR) |
|
} else { |
|
channel = call.GetConfigWithdrawChannelsBest(common.CurrencyINR) |
|
} |
|
log.Debug("withdraw req:%+v,channel:%+v", req, channel) |
|
if channel == nil || channel.WithdrawPer <= 0 { |
|
return nil, errors.New("inner error") |
|
} |
|
flag := new(int64) |
|
reqFin := make(chan struct{}, 1) |
|
cid := values.PayWay(channel.ChannelID) |
|
var ret []byte |
|
var err error |
|
base := base.NewWithdrawBase(req) |
|
util.Go(func() { |
|
allpay.NewSub(base, int(req.Channel)) |
|
if base.Sub != nil { |
|
ret, err = base.Req() |
|
} else { |
|
ret, err = nil, errors.New("inner error") |
|
} |
|
if atomic.CompareAndSwapInt64(flag, 0, 1) { |
|
reqFin <- struct{}{} |
|
} else { |
|
// 没抢到则在pay模块更新订单 |
|
time.AfterFunc(5*time.Second, func() { |
|
log.Debug("order:%v,err:%v", req.OrderID, err) |
|
or := &common.WithdrawOrder{OrderID: req.OrderID} |
|
if err != nil { |
|
db.Mysql().Get(or) |
|
log.Debug("order:%+v,err:%v", or) |
|
call.ReturnBackWithdraw(or, common.StatusROrderPay, common.StatusROrderFail) |
|
} else { |
|
data := &pb.InnerWithdrawResp{} |
|
proto.Unmarshal(ret, data) |
|
log.Debug("apipayid:%+v", data.APIOrderID) |
|
if data.APIOrderID != "" { |
|
db.Mysql().Update(or, map[string]interface{}{"apipayid": data.APIOrderID}) |
|
} |
|
} |
|
}) |
|
} |
|
}) |
|
select { |
|
case <-time.After(4 * time.Second): |
|
if atomic.CompareAndSwapInt64(flag, 0, 1) { |
|
data := &pb.InnerWithdrawResp{Channel: uint32(cid)} |
|
retData, _ := proto.Marshal(data) |
|
return retData, nil |
|
} else { |
|
<-reqFin |
|
if err != nil { |
|
data := &pb.InnerWithdrawResp{Channel: uint32(cid)} |
|
ret, _ = proto.Marshal(data) |
|
} |
|
return ret, err |
|
} |
|
case <-reqFin: |
|
if err != nil { |
|
data := &pb.InnerWithdrawResp{Channel: uint32(cid)} |
|
ret, _ = proto.Marshal(data) |
|
} |
|
return ret, err |
|
} |
|
}
|
|
|