package bfpay import ( "encoding/json" "errors" "fmt" "net/http" "server/common" "server/modules/pay/base" "server/modules/pay/values" "server/pb" "server/util" "strings" "time" "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 = false if b.Opt == 1 { b.Resp = new(PayResp) b.ReqURL = baseURL + payURL } else if b.Opt == 2 { b.Resp = new(WithdrawResp) b.ReqURL = baseURL + withdrawURL } else if b.Opt == 3 { b.SignPassStr = []string{"sign"} b.CallbackResp.Msg = "SUCCESS" b.CallbackReq = new(PayCallbackReq) } else if b.Opt == 4 { b.SignPassStr = []string{"sign", "msg"} b.CallbackResp.Msg = "SUCCESS" b.CallbackReq = new(WithdrawCallbackReq) } b.Sub = sub } type Sub struct { Base *base.Base } func (s *Sub) PackHeader(header http.Header) { // header.Set("mchtId", mid) // header.Set("version", "20") // if s.Base.Opt == 1 { // header.Set("biz", "bq102") // } else if s.Base.Opt == 2 { // header.Set("biz", "df104") // } } func (s *Sub) PackReq() interface{} { if s.Base.Opt == 1 { return s.PackPayReq() } return s.PackWithdrawReq() } func (s *Sub) GetResp() (proto.Message, error) { if s.Base.Opt == 1 { resp := s.Base.Resp.(*PayResp) if resp.Head.RespCode != "0000" || resp.Body.PayUrl == "" { return nil, errors.New("pay fail") } return &pb.InnerRechargeResp{APIOrderID: resp.Body.TradeId, URL: resp.Body.PayUrl, Channel: uint32(values.BFPay)}, nil } resp := s.Base.Resp.(*WithdrawResp) if s.Base.Status == 0 && resp.Head.RespCode != "0000" { return nil, errors.New("withdraw fail") } withdrawRespBody := &WithdrawRespBody{} err := Decode(resp.Body, withdrawRespBody) if err != nil { log.Error("err:%v", err) } return &pb.InnerWithdrawResp{APIOrderID: withdrawRespBody.TradeId, Channel: uint32(values.BFPay)}, nil } func (s *Sub) PackPayReq() interface{} { r := s.Base.PayReq send := &PayReq{ Head: Head{ MchtId: mid, Version: "20", Biz: "bq101", }, Body: Body{ OrderId: r.OrderID, OrderTime: time.Now().Format("20060102150405"), Amount: fmt.Sprintf("%d", r.Amount/1e6), CurrencyType: "BRL", Goods: "baxipix", NotifyUrl: values.GetPayCallback(values.BFPay), CallBackUrl: values.GetFrontCallback(), }, } send.Sign = s.Base.SignMD5(send.Body) return send } func (s *Sub) PackWithdrawReq() interface{} { r := s.Base.WithdrawReq if common.PayType(r.PayType) == common.PayTypeCPF { r.Number = strings.ReplaceAll(r.Number, "-", "") r.Number = strings.ReplaceAll(r.Number, ".", "") } send := &WithdrawReq{ Head: Head{ MchtId: mid, Version: "20", Biz: "df104", }, } amount := fmt.Sprintf("%d", r.Amount/1e6) withdrawReqBody := WithdrawBody{ BatchOrderNo: r.OrderID, TotalNum: 1, TotalAmount: amount, NotifyUrl: values.GetWithdrawCallback(values.BFPay), CurrencyType: "BRL", } detail := []Detail{{ Seq: "0", Amount: amount, AccType: "0", CertType: fmt.Sprintf("%d", r.PayType-1), CertId: r.Number, BankCardName: r.Name, }} withdrawReqBody.Detail = detail jsonStr, _ := json.Marshal(withdrawReqBody) encodeStr := string(jsonStr) log.Debug("encodeStr:%s", encodeStr) send.Body = Encode(encodeStr) return send } func (s *Sub) CheckSign(str string) bool { // signStr := values.GetSignStr(str, "sign") s.Base.CallbackResp.Msg = "success" if s.Base.Opt == 3 { req := s.Base.CallbackReq.(*PayCallbackReq) log.Debug("checkSign pay:%+v", *req) s.Base.CallbackResp.OrderID = req.Body.OrderId s.Base.CallbackResp.Success = req.Body.Status == "SUCCESS" return util.CalculateMD5(base.GetSignStr(req.Body)+"&key="+key) == req.Sign } req := s.Base.CallbackReq.(*WithdrawCallbackReq) log.Debug("checkSign withdraw:%+v", *req) if req.Head.RespCode != "0000" { return false } withdrawCallbackBody := &WithdrawCallbackBody{} err := Decode(req.Body, withdrawCallbackBody) if err != nil { log.Error("err:%v", err) return false } log.Debug("withdrawCallbackBody:%+v", withdrawCallbackBody) if len(withdrawCallbackBody.Detail) == 0 { return false } detail := withdrawCallbackBody.Detail[0] if detail.Status == "AUDIT_DOING" || detail.Status == "AUDIT_SUCCESS" || detail.Status == "COMMITTED" || detail.Status == "COMMITTED_SUCCESS" || detail.Status == "DOING" { return false } s.Base.CallbackResp.OrderID = withdrawCallbackBody.BatchOrderNo s.Base.CallbackResp.Success = detail.Status == "SUCCESS" s.Base.CallbackResp.APIOrderID = withdrawCallbackBody.TradeId s.Base.CallbackResp.FailMessage = req.Head.RespMsg return true }