|
|
|
|
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)), 2*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
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
} else if isReplace {
|
|
|
|
|
values.PaySuccess(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
|
|
|
|
|
}
|
|
|
|
|
}
|