印度包网
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.

153 lines
4.3 KiB

1 year ago
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
1 year ago
if req.Channel == 0 {
var weightChannel uint32
1 year ago
for _, v := range call.GetConfigPayChannels() {
2 months ago
if req.Amount*common.DecimalDigits <= v.PayUp && req.Amount*common.DecimalDigits >= v.PayDown && v.CurrencyType == common.CurrencyINR {
weightChannel = uint32(v.ChannelID)
1 year ago
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
1 year ago
}
2 months ago
if req.Channel == 0 {
log.Error("get channel err, is 0")
}
payWay = values.PayWay(req.Channel)
1 year ago
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)
1 year ago
}
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)
1 year ago
} else {
channel = call.GetConfigWithdrawChannelsBest(common.CurrencyINR)
1 year ago
}
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
}
}