package mlpay2 import ( "encoding/json" "errors" "fmt" "net/http" "server/modules/pay/base" "server/modules/pay/values" "server/pb" "server/util" "strings" "github.com/gogo/protobuf/proto" "github.com/liangdas/mqant/log" "github.com/mitchellh/mapstructure" ) func NewSub(b *base.Base) { sub := &Sub{ Base: b, } b.HttpType = base.HttpTypeForm b.PostformType = base.PostformTypeQuery 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.CallbackReq = new(PayCallbackReq) b.CallbackResp.Msg = "0" } else if b.Opt == base.OPTWithdrawCB { b.CallbackReq = new(WithdrawCallbackReq) b.CallbackResp.Msg = "0" } 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 } else { return } b.Sub = sub } type Sub struct { Base *base.Base } func (s *Sub) PackHeader(header http.Header) { } 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) { log.Debug("resp:%v", s.Base.Resp) if s.Base.Opt == base.OPTPay { resp := s.Base.Resp.(*PayResp) if resp.Data == "" { return nil, errors.New("pay fail") } return &pb.InnerRechargeResp{URL: resp.Data, Channel: uint32(values.MLPay2)}, nil } else if s.Base.Opt == base.OPTWithdraw { resp := s.Base.Resp.(*WithdrawResp) if s.Base.Status == 0 && resp.Code != "0000" { return nil, errors.New("withdraw fail") } return &pb.InnerWithdrawResp{APIOrderID: resp.Data, Channel: uint32(values.MLPay2)}, nil } else if s.Base.Opt == base.OPTQueryWithdraw { resp := s.Base.Resp.(*QueryWithdrawResp) ret := &pb.InnerQueryWithdrawResp{Msg: resp.Msg} if resp.Code == "0001" && strings.Contains(resp.Msg, "is empty") { s.Base.QueryWithdrawResp.Status = base.QueryStatusFail return ret, nil } if resp.Code != "0000" { s.Base.QueryWithdrawResp.Status = base.QueryStatusUnknown return ret, nil } data := &QueryWithdrawData{} err := mapstructure.Decode(resp.Data, data) // err := json.Unmarshal([]byte(resp.Data), data) if err != nil { log.Error("err:%v", err) s.Base.QueryWithdrawResp.Status = base.QueryStatusUnknown return ret, nil } ret.OrderID = data.PartnerWithdrawNo s.Base.QueryWithdrawResp.OrderID = data.PartnerWithdrawNo s.Base.QueryWithdrawResp.APIOrderID = data.WithdrawNo s.Base.QueryWithdrawResp.Msg = resp.Msg if s.Base.Status != 0 { s.Base.QueryWithdrawResp.Status = base.QueryStatusUnknown } else { if data.Status == 2 { s.Base.QueryWithdrawResp.Status = base.QueryStatusOrderSuccess } else if data.Status == 3 { s.Base.QueryWithdrawResp.Status = base.QueryStatusFail } else { s.Base.QueryWithdrawResp.Status = base.QueryStatusSuccess } } return ret, nil } else if s.Base.Opt == base.OPTQueryPay { resp := s.Base.Resp.(*QueryPayResp) ret := &pb.InnerQueryWithdrawResp{Msg: resp.Message} if resp.Code != "0000" { s.Base.QueryPayResp.Status = base.QueryStatusUnknown return ret, nil } // data := resp.Data data := &QueryPayData{} err := mapstructure.Decode(resp.Data, data) // err := json.Unmarshal(resp.Data, data) if err != nil { log.Error("err:%v", err) s.Base.QueryPayResp.Status = base.QueryStatusUnknown return ret, nil } s.Base.QueryPayResp.APIOrderID = data.OrderNo s.Base.QueryPayResp.OrderID = data.PartnerOrderNo s.Base.QueryPayResp.Msg = resp.Message if s.Base.Status != 0 { s.Base.QueryPayResp.Status = base.QueryStatusUnknown } else { if data.Status == 2 { s.Base.QueryPayResp.Status = base.QueryStatusOrderSuccess } else if data.Status == 3 { s.Base.QueryPayResp.Status = base.QueryStatusFail } else { s.Base.QueryPayResp.Status = base.QueryStatusSuccess } } return ret, nil } return nil, errors.New("unknown opt") } func (s *Sub) PackPayReq() interface{} { r := s.Base.PayReq userDataStr, _ := json.Marshal(UserData{UserName: r.Name, UserEmail: r.Email, UserPhone: r.Phone}) send := &PayReq{ PartnerID: PartnerId, ApplicationID: ApplicationId, PayWay: 2, PartnerOrderNo: r.OrderID, Amount: r.Amount * 100, Currency: "INR", Name: r.Name, GameID: fmt.Sprintf("%d", r.UID), ClientIP: r.IP, NotifyURL: s.Base.GetPayCallbackURL(), Subject: "Shop", Body: "product", CallbackURL: values.GetFrontCallback(), Extra: string(userDataStr), Version: "1.0", } send.Sign = Sign(util.StructToMapJson(send), 0) return send } func (s *Sub) PackWithdrawReq() interface{} { r := s.Base.WithdrawReq send := &WithdrawReq{ PartnerID: fmt.Sprintf("%d", PartnerId), PartnerWithdrawNo: r.OrderID, Amount: r.Amount * 100, Currency: "INR", GameID: fmt.Sprintf("%d", r.UID), NotifyURL: s.Base.GetWithdrawCallbackURL(), AccountName: r.Name, AccountPhone: r.Phone, AccountEmail: r.Email, Version: "1.0", } //if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank { send.ReceiptMode = 1 send.AccountNumber = r.CardNo send.AccountExtra1 = r.PayCode send.AccountExtra2 = r.PayCode[:4] //} else if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeUPI { // send.ReceiptMode = 0 // send.AccountNumber = r.PayCode //} else { // return nil //} send.Sign = Sign(util.StructToMapJson(send), 1) return send } func (s *Sub) CheckSign(str string) bool { log.Debug("callback:%v", s.Base.CallbackReq) if s.Base.Opt == base.OPTPayCB { req := s.Base.CallbackReq.(*PayCallbackReq) signStr := values.GetSignStrFormURLEncode(s.Base.C, req, "sign") log.Debug("req:%v,pay signStr:%v", *req, signStr) s.Base.CallbackResp.OrderID = req.PartnerOrderNo s.Base.CallbackResp.APIOrderID = req.OrderNo s.Base.CallbackResp.Success = req.Status == 1 return checkSign(signStr, req.Sign, 0) } else if s.Base.Opt == base.OPTWithdrawCB { req := s.Base.CallbackReq.(*WithdrawCallbackReq) signStr := values.GetSignStrFormURLEncode(s.Base.C, req, "sign") log.Debug("req:%v,withdraw signStr:%v", *req, signStr) s.Base.CallbackResp.OrderID = req.PartnerWithdrawNo s.Base.CallbackResp.Success = req.Status == 1 return checkSign(signStr, req.Sign, 1) } return false } func (s *Sub) PackQueryWithdrawReq() interface{} { r := s.Base.QueryWithdrawReq send := &QueryWithdrawReq{ PartnerId: PartnerId, PartnerWithdrawNo: r.OrderID, Version: "1.0", } send.Sign = Sign(util.StructToMapJson(send), 1) return send } func (s *Sub) PackQueryPayReq() interface{} { r := s.Base.QueryPayReq send := &QueryPayReq{ PartnerID: int64(PartnerId), ApplicationID: fmt.Sprintf("%d", ApplicationId), PartnerOrderNo: r.OrderID, Version: "1.0", } send.Sign = Sign(util.StructToMapJson(send), 0) return send }