package rchgutil import ( "encoding/json" "errors" "fmt" "net/http" "strconv" "time" "91porn-server/app/appg" "91porn-server/common/httputil" "91porn-server/common/log" ) var asc = config{ MercID: "10005", AppSecret: "176486f9d7c14189717fb88f12d6626a", ExeUrl: "http://106.55.92.30:8081/api/pay", NotifyUrl: "/3rd/defray/callback/rchg/asen", } // ASen 充值订单请求体 type ASen struct { MercID string `json:"merchant_no" sign:"1"` //商户编号 TradeNo string `json:"out_order_no" sign:"1"` //商户订单号 Money string `json:"amount" sign:"1"` // 支付金额:元 Type string `json:"pay_type" sign:"1"` // 订单充值类型 NotifyURL string `json:"notify_url" sign:"1"` // 回调地址 Sign string `json:"sign"` // 签名 PayMethod string `json:"-"` } type ASenMsgData struct { MercID string `json:"merchant_no"` //商户编号 OID string `json:"order_no"` TradeNo string `json:"out_order_no"` //商户订单号 Money string `json:"amount"` PayWay string `json:"pay_type"` PayUrl string `json:"pay_url"` } type ASenMsg struct { Code int `json:"code" sign:"1"` //交易返回码,返回SUCCESS 表示交易成功(不代表最终结果), Data interface{} `json:"data"` Msg string `json:"msg"` //签名 } // RYRes 回调函数参数model type ASenBack struct { OID string `json:"order_no" form:"order_no" sign:"1"` //订单号 MercID string `json:"merchant_no" form:"merchant_no" sign:"1" ` //商户编号 TradeNo string `json:"out_order_no" form:"out_order_no" sign:"1"` //商户订单号 PayMoney string `json:"amount" form:"amount" sign:"1"` //订单到账实际金额 Type string `json:"pay_type" form:"pay_type" sign:"1"` // 订单充值类型 Status string `json:"code" form:"code" sign:"1"` //交易结果 1(成功) Sign string `json:"sign" form:"sign" ` //签名 } // ToPay 支付发起 func (this *ASen) ToPay() (res RchgMsg, err error) { var errlog string this.Fill() msg := ASenMsg{} code, err := httputil.DefaultClientPostJsonWithResp(&msg, this.GetURL(), this.GetHeader(), this.GetBody()) if err != nil { errlog = fmt.Sprintf("asen ToPay requset fail \nerror:%+v\n\ndata:%+v;", err, this) log.Error(errlog) err = errors.New(errlog) return } if code != http.StatusOK { errlog = fmt.Sprintf("asen ToPay response status exception;\nstatus %+v;", code) log.Error(errlog) err = errors.New(errlog) return } if msg.Code != 1 { errlog = fmt.Sprintf("asen ToPay be rejected;\n msg:%+v:", msg) err = errors.New(errlog) log.Error(errlog) return } var data ASenMsgData bytes, err := json.Marshal(msg.Data) if err != nil { errlog = fmt.Sprintf("asen payUrl urlDecode fail \nerror:%+v;", err) log.Error(errlog) err = errors.New(errlog) return } if err = json.Unmarshal(bytes, &data); err != nil { errlog = fmt.Sprintf("asen payUrl urlDecode fail \nerror:%+v;", err) log.Error(errlog) err = errors.New(errlog) return } res.PayUrl = data.PayUrl res.OID = data.OID res.Mode = "sdk" return } // ASenCallBack 阿森结构回调函数 func (this *ASenBack) Notify() (RchgBack, error) { now := time.Now() r := RchgBack{} if this.Sign != this.ToSign() { err := errors.New("check sign fail") log.Error(fmt.Sprintf("ASen callback sign verify fail error:%+v:", err)) return r, err } r.Code = 200 if this.Status != "1" { r.Code = 400 } fPayMoney, err := strconv.ParseFloat(this.PayMoney, 64) if err != nil { log.Error(fmt.Sprintf("ASen callback sign verify fail error:%+v:", err)) return r, err } r.PayMoney = int64(fPayMoney * 100) r.PaymentAt = now r.TransNo = this.TradeNo r.OID = this.OID return r, nil } func (this *ASenBack) Success() string { return "success" } // Fill 补全配置信息和签名信息 func (this *ASen) Fill() { this.Type = this.PayMethod this.PayMethod = "" this.MercID = this.GetMercID() this.NotifyURL = this.GetCallBackURL() this.Sign = this.sign() } // sign 签名 func (this *ASen) sign() string { buf := fixedSignStrAdd(*this) buf.WriteString(asc.AppSecret) log.Info(fmt.Sprintf("--------------%s", buf.String())) return md5Sign(buf.String()) } // sign 签名 func (this *ASenBack) ToSign() string { buf := fixedSignStrAdd(*this) buf.WriteString(asc.AppSecret) return md5Sign(buf.String()) } // GetBody 获取请求body func (this *ASen) GetBody() interface{} { m := make(map[string]string) jsonStr, err := json.Marshal(this) if err != nil { log.Info(fmt.Sprintf("ASen GetBody json.Marshal is fail error:%+v/data:%+v", err, this)) } sstr := string(jsonStr) log.Info(fmt.Sprintf("==================%+v", sstr)) _ = json.Unmarshal(jsonStr, &m) return m } // GetHeader 获取请求头信息 func (g *ASen) GetHeader() map[string]string { return map[string]string{"Content-Type": "application/x-www-form-urlencoded"} } // GetURL 获取请求地址 func (*ASen) GetURL() string { return asc.ExeUrl } // GetCallBackURL 获取回掉函数 func (*ASen) GetCallBackURL() string { return appg.Conf.URL.LocalWebUrl + asc.NotifyUrl } // GetMercID 获取商户编号 func (*ASen) GetMercID() string { return asc.MercID }