package antpay import ( "errors" "fmt" "net/http" "server/config" "server/modules/pay/base" "server/modules/pay/values" "server/pb" "server/util" "sort" "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 b.SignPassStr = []string{"sign", "name", "email", "phone"} } else if b.Opt == base.OPTWithdraw { b.Resp = new(WithdrawResp) if config.GetBase().Release { b.ReqURL = baseURL + withdrawURL } else { b.ReqURL = baseURL + testWithdrawURL } b.SignPassStr = []string{"sign", "msg", "notify_url"} } else if b.Opt == base.OPTPayCB { b.SignPassStr = []string{"sign", "pay_url"} b.CallbackResp.Msg = "SUCCESS" b.CallbackReq = new(PayCallbackReq) } else if b.Opt == base.OPTWithdrawCB { b.SignPassStr = []string{"sign", "pay_url"} 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) { } 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.Status == "3" || resp.PayURL == "" { return nil, errors.New("pay fail") } return &pb.InnerRechargeResp{APIOrderID: resp.TransID, URL: resp.PayURL, Channel: uint32(values.AntPay)}, nil } else if s.Base.Opt == base.OPTWithdraw { resp := s.Base.Resp.(*WithdrawResp) if s.Base.Status == 0 && resp.Status == "3" { return nil, errors.New("withdraw fail") } return &pb.InnerWithdrawResp{APIOrderID: fmt.Sprintf("%v", resp.TransID), Channel: uint32(values.AntPay), 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{APIOrderID: resp.Data.TransferId, OrderID: resp.Data.MchOrderNo} // s.Base.QueryWithdrawResp.OrderID = resp.Data.MchOrderNo // s.Base.QueryWithdrawResp.APIOrderID = resp.Data.TransferId // if s.Base.Status == 0 { // if resp.Code == 200 { // if resp.Data.State == 2 { // s.Base.QueryWithdrawResp.Status = base.QueryStatusOrderSuccess // } else if resp.Data.State == 1 { // s.Base.QueryWithdrawResp.Status = base.QueryStatusSuccess // } // } else { // if resp.Data.State == 3 { // 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{APIOrderID: resp.Data.PayOrderId, OrderID: resp.Data.MchOrderNo} // s.Base.QueryPayResp.OrderID = resp.Data.MchOrderNo // s.Base.QueryPayResp.APIOrderID = resp.Data.PayOrderId // if s.Base.Status == 0 { // if resp.Code == 2000 && 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{ MerchantID: mid, OrderNo: r.OrderID, Amount: r.Amount, NotifyURL: s.Base.GetPayCallbackURL(), ReturnURL: values.GetFrontCallback(), // Name: r.Name, // Email: r.Email, // Phone: r.Phone, } signStr := GetSignStr(send, s.Base.SignPassStr...) signStr = signStr + "&key=" + key send.Sign = util.CalculateMD5(util.CalculateMD5(signStr)) return send } func (s *Sub) PackWithdrawReq() interface{} { r := s.Base.WithdrawReq send := &WithdrawReq{ MerchantID: mid, OrderNo: r.OrderID, Amount: r.Amount, // BankNo: , // AccountType: , // AccountNo: , AccountName: r.Name, NotifyURL: s.Base.GetWithdrawCallbackURL(), } //if fmt.Sprintf("%d", r.PayType) == common.WithdrawTypeBank { send.BankNo = r.PayCode send.AccountType = "BANK" send.AccountNo = r.CardNo //} else { // return nil //} // signStr := GetSignStr(send, s.Base.SignPassStr...) // signStr = signStr + "&key=" + key // send.Sign = util.CalculateMD5(util.CalculateMD5(signStr)) send.Sign = util.CalculateMD5(s.Base.SignMD5(send)) return send } // func (s *Sub) PackQueryWithdrawReq() interface{} { // r := s.Base.QueryWithdrawReq // send := &QueryWithdrawReq{ // MchNo: mid, // AppId: appID, // MchOrderNo: r.OrderID, // } // send.Sign = s.Base.SignMD5(send) // return send // } // func (s *Sub) PackQueryPayReq() interface{} { // r := s.Base.QueryPayReq // send := &QueryPayReq{ // MchNo: mid, // AppId: appID, // MchOrderNo: r.OrderID, // } // 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 := "" if s.Base.Opt == base.OPTPayCB { req := s.Base.CallbackReq.(*PayCallbackReq) log.Debug("checkSign pay:%+v", *req) checkSign = req.Sign s.Base.CallbackResp.OrderID = req.OrderNo s.Base.CallbackResp.Success = req.Status == "2" mySign = util.CalculateMD5(s.Base.SignMD5(req)) } else if s.Base.Opt == base.OPTWithdrawCB { req := s.Base.CallbackReq.(*WithdrawCallbackReq) log.Debug("checkSign withdraw:%+v", *req) checkSign = req.Sign s.Base.CallbackResp.OrderID = req.OrderNo s.Base.CallbackResp.Success = req.Status == "2" s.Base.CallbackResp.APIOrderID = req.TransID s.Base.CallbackResp.FailMessage = req.Msg mySign = util.CalculateMD5(s.Base.SignMD5(req)) } // signStr := GetSignStr(s.Base.CallbackResp, s.Base.SignPassStr...) // signStr = signStr + "&key=" + key // mySign := util.CalculateMD5(util.CalculateMD5(signStr)) return mySign == checkSign } func GetSignStr(send interface{}, pass ...string) string { m := base.StructToMapJson(send) str := []string{} for i := range m { if i == "sign" { continue } shouldPass := false for _, v := range pass { if v == i { shouldPass = true break } } if shouldPass { continue } str = append(str, i) } sort.Strings(str) signStr := "" for i, v := range str { if v == "amount" { signStr += fmt.Sprintf("%v=%v.0", v, m[v]) } else { signStr += fmt.Sprintf("%v=%v", v, m[v]) } if i != len(str)-1 { signStr += "&" } } log.Debug("signStr:%s", signStr) return signStr }