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 } }