package superpay import ( "encoding/base64" "errors" "fmt" "math/rand" "net/http" "server/config" "server/modules/pay/base" "server/modules/pay/values" "server/pb" "server/util" "strings" "github.com/gogo/protobuf/proto" "github.com/liangdas/mqant/log" ) func NewSub(b *base.Base) { sub := &Sub{ Base: b, } b.SignKey = key b.HttpType = base.HttpTypeJson b.ShouldSignUpper = true if b.Opt == base.OPTPay { b.Resp = new(PayResp) b.ReqURL = baseURL + payURL } else if b.Opt == base.OPTWithdraw { b.Resp = new(WithdrawResp) b.ReqURL = baseURL + withdrawURL } else if b.Opt == base.OPTPayCB { b.HttpType = base.HttpTypeForm b.SignPassStr = []string{"sign"} b.CallbackResp.Msg = "success" b.CallbackReq = new(PayCallbackReq) } else if b.Opt == base.OPTWithdrawCB { b.HttpType = base.HttpTypeForm b.SignPassStr = []string{"sign"} b.CallbackResp.Msg = "success" b.CallbackReq = new(WithdrawCallbackReq) } else if b.Opt == base.OPTQueryWithdraw { b.Resp = new(QueryWithdrawResp) b.ReqURL = baseURL + queryWithdrawURL } else if b.Opt == base.OPTQueryPay { b.Resp = new(QueryPayResp) b.ReqURL = baseURL + queryPayURL } b.Sub = sub } type Sub struct { Base *base.Base } func (s *Sub) PackHeader(header http.Header) { if iToken == "" { s.GetItoken() } header.Set("iToken", iToken) } func (s *Sub) PackReq() interface{} { if s.Base.Opt == base.OPTPay { return s.PackPayReq() } else if s.Base.Opt == base.OPTWithdraw { return s.PackWithdrawReq() } else if s.Base.Opt == base.OPTQueryWithdraw { return s.PackQueryWithdrawReq() } else if s.Base.Opt == base.OPTQueryPay { return s.PackQueryPayReq() } return nil } func (s *Sub) GetResp() (proto.Message, error) { if s.Base.Opt == 1 { resp := s.Base.Resp.(*PayResp) if resp.Code != 0 || resp.Data.PayData == "" { s.GetItoken() return nil, errors.New("pay fail") } return &pb.InnerRechargeResp{APIOrderID: resp.Data.PayOrderID, URL: resp.Data.PayData, Channel: uint32(values.SuperPay)}, nil } else if s.Base.Opt == base.OPTWithdraw { resp := s.Base.Resp.(*WithdrawResp) if s.Base.Status == 0 && resp.Code != 0 { s.GetItoken() return nil, errors.New("withdraw fail") } return &pb.InnerWithdrawResp{APIOrderID: resp.Data.TransferID, Channel: uint32(values.SuperPay), Status: uint32(s.Base.Status)}, nil } else if s.Base.Opt == base.OPTQueryWithdraw { resp := s.Base.Resp.(*QueryWithdrawResp) log.Debug("QueryWithdrawResp:%+v", resp) ret := &pb.InnerQueryWithdrawResp{OrderID: resp.Data.MchOrderNo} s.Base.QueryWithdrawResp.OrderID = resp.Data.MchOrderNo if s.Base.Status == 0 { if resp.Code == 0 { if resp.Data.State == 2 { s.Base.QueryWithdrawResp.Status = base.QueryStatusOrderSuccess } else if resp.Data.State == 0 || resp.Data.State == 1 { s.Base.QueryWithdrawResp.Status = base.QueryStatusSuccess } } else { if resp.Data.State == 3 || resp.Data.State == 4 { s.Base.QueryWithdrawResp.Status = base.QueryStatusFail } } } if s.Base.QueryWithdrawResp.Status == 0 { s.Base.QueryWithdrawResp.Status = base.QueryStatusUnknown } return ret, nil } else if s.Base.Opt == base.OPTQueryPay { resp := s.Base.Resp.(*QueryPayResp) log.Debug("QueryPayResp:%+v", resp) ret := &pb.InnerQueryWithdrawResp{OrderID: resp.Data.MchOrderNo} s.Base.QueryPayResp.OrderID = resp.Data.MchOrderNo if s.Base.Status == 0 { if resp.Code == 0 && resp.Data.State == 2 { s.Base.QueryPayResp.Status = base.QueryStatusOrderSuccess } } if s.Base.QueryPayResp.Status == 0 { s.Base.QueryPayResp.Status = base.QueryStatusUnknown } return ret, nil } return nil, fmt.Errorf("unknow opt") } func (s *Sub) PackPayReq() interface{} { r := s.Base.PayReq send := &PayReq{ Amount: fmt.Sprintf("%d", r.Amount), AppID: appID, Subject: "shop", Body: "shopbuy", ChannelExtra: ChannelExtra{ Realname: r.Name, UserMobile: r.Phone, UserEmail: r.Email, UserIP: r.IP, }, Currency: "INR", DivisionMode: "0", MchNo: mid, MchOrderNo: r.OrderID, NotifyURL: s.Base.GetPayCallbackURL(), ReturnURL: values.GetFrontCallback(), } code := config.GetConfig().Pay.SuperPay.PayCode if len(code) == 0 { return nil } send.WayCode = code[rand.Intn(len(code))] // send.Sign = s.Base.SignMD5(send) return send } func (s *Sub) PackWithdrawReq() interface{} { r := s.Base.WithdrawReq send := &WithdrawReq{ AccountName: r.Name, // AccountNo: , Amount: fmt.Sprintf("%d", r.Amount), AppID: appID, ChannelExtra: WithdrawReqChannelExtra{ Email: r.Email, Mobile: r.Phone, }, Currency: "INR", // EntryType: , // EXTParam: , // IfCode: , MchNo: mid, MchOrderNo: r.OrderID, NotifyURL: s.Base.GetWithdrawCallbackURL(), TransferDesc: "shopwithdraw", } code := config.GetConfig().Pay.SuperPay.WithdrawCode if len(code) == 0 { return nil } send.IfCode = code[rand.Intn(len(code))] //if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank { send.EntryType = BankCard send.AccountNo = r.CardNo send.ChannelExtra.Ifsc = r.PayCode //} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI { // send.EntryType = IndiaUpiUtr // send.AccountNo = r.PayCode // send.ChannelExtra.Upi = r.PayCode //} else { // return nil //} // send.Sign = s.Base.SignMD5(send) return send } func (s *Sub) PackQueryWithdrawReq() interface{} { // r := s.Base.QueryWithdrawReq send := &QueryWithdrawReq{} // send.Sign = s.Base.SignMD5(send) return send } func (s *Sub) PackQueryPayReq() interface{} { // r := s.Base.QueryPayReq send := &QueryPayReq{} // send.Sign = s.Base.SignMD5(send) return send } func (s *Sub) CheckSign(str string) bool { str += "&key=" + key checkSign := "" // s.Base.CallbackResp.Msg = "success" mySign := strings.ToUpper(util.CalculateMD5(str)) if s.Base.Opt == base.OPTPayCB { req := s.Base.CallbackReq.(*PayCallbackReq) log.Debug("checkSign pay:%+v", *req) if req.State == "0" || req.State == "1" { return false } checkSign = req.Sign s.Base.CallbackResp.OrderID = req.MchOrderNo s.Base.CallbackResp.Success = req.State == "2" // mySign = s.Base.SignMD5(req) } else if s.Base.Opt == base.OPTWithdrawCB { req := s.Base.CallbackReq.(*WithdrawCallbackReq) log.Debug("checkSign withdraw:%+v", *req) if req.State == 0 || req.State == 1 { return false } checkSign = req.Sign s.Base.CallbackResp.OrderID = req.MchOrderNo s.Base.CallbackResp.Success = req.State == 2 s.Base.CallbackResp.FailMessage = req.ErrMsg // mySign = s.Base.SignMD5(req) } pass := mySign == checkSign if !pass { log.Debug("final sign str:%s,sign:%s", str, mySign) } return pass } func (s *Sub) GetItoken() { send := &TokenReq{ Ia: base64.StdEncoding.EncodeToString([]byte(config.GetConfig().Pay.SuperPay.Account)), IP: base64.StdEncoding.EncodeToString([]byte(config.GetConfig().Pay.SuperPay.Password)), } ret := &TokenResp{} util.HttpPost(baseURL+tokenURL, send, ret, nil) fmt.Println("ret:", ret) iToken = ret.Data["iToken"] }