264 lines
7.6 KiB
Go
264 lines
7.6 KiB
Go
package rchgutil
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"reflect"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"91porn-server/app/appg"
|
|
"91porn-server/common"
|
|
"91porn-server/common/httputil"
|
|
"91porn-server/common/log"
|
|
"91porn-server/web/webg"
|
|
)
|
|
|
|
var dc = config{
|
|
MercID: "191228889",
|
|
AppSecret: "buptpyxrn8agj1pivx3bl90mu91rx6ih",
|
|
ExeUrl: "https://api.parado.vip/Pay_Index.html",
|
|
QueryUrl: "https://api.parado.vip/Pay_Trade_query.html",
|
|
NotifyUrl: "/3rd/defray/callback/dx",
|
|
CallbackURL: "/refuse",
|
|
}
|
|
|
|
// DXZhiFu 充值订单请求体
|
|
type DXZhiFu struct {
|
|
MercID string `json:"pay_memberid" sign:"1"` //商户编号
|
|
TradeNo string `json:"pay_orderid" sign:"1"` //商户订单号
|
|
Time string `json:"pay_applydate" sign:"1"` //提交时间2016-12-26 18:18:18
|
|
Type string `json:"pay_bankcode" sign:"1"` // 产品编码
|
|
NotifyURL string `json:"pay_notifyurl" sign:"1"` // 回调地址
|
|
CallbackUrl string `json:"pay_callbackurl" sign:"1"` //支付成功后的跳转地址
|
|
Money string `json:"pay_amount" sign:"1"` // 充值⾦额
|
|
Format string `json:"format"`
|
|
PayIP string `json:"pay_ip"`
|
|
ProductName string `json:"pay_productname"` // 商品信息
|
|
Sign string `json:"pay_md5sign" ` // 签名
|
|
PayMethod string //付款方式 扫码|h5
|
|
}
|
|
|
|
// DXZhiFuRes 回调函数参数model
|
|
type DXZhiFuRes struct {
|
|
MercID string `json:"memberid" form:"memberid" sign:"1"` //商户编号
|
|
TradeNo string `json:"orderid" form:"orderid" sign:"1"` //商户订单号
|
|
PayMoney string `json:"amount" form:"amount" sign:"1"` //订单到账实际金额
|
|
OID string `json:"transaction_id" form:"transaction_id" sign:"1"` //支付平台订单号
|
|
DateTime string `json:"datetime" form:"datetime" sign:"1"` //交易时间
|
|
Code string `json:"returncode" form:"returncode" sign:"1"`
|
|
Sign string `json:"sign" form:"sign" ` //签名
|
|
}
|
|
|
|
type DXZhiFuData struct {
|
|
PageURL string `json:"pageUrl"` //支付地址 原生
|
|
PayURL string `json:"qrcodeUrl"` //支付地址
|
|
LockSeconds int `json:"lock_seconds"` //有效时间
|
|
Body string `json:"body"` //消息内容
|
|
Money string `json:"payAmount"` //实际支付金额
|
|
}
|
|
|
|
// ToPay 支付发起
|
|
func (this *DXZhiFu) ToPay() (payURL string, err error) {
|
|
var errlog string
|
|
this.Fill()
|
|
var msgModel struct {
|
|
Status string `json:"status"`
|
|
Msg string `json:"msg"`
|
|
Data DXZhiFuData `json:"data"`
|
|
}
|
|
code, err := httputil.DefaultClientPostJsonWithRespWithProxy(appg.ProxyCfg, &msgModel, this.GetURL(), this.GetHeader(), this.GetBody())
|
|
if err != nil {
|
|
errlog = fmt.Sprintf("DXZhiFu ToPay Http.PostJson fail error:%+v/,data:%+v;", err, this)
|
|
err = errors.New(errlog)
|
|
log.Error(errlog)
|
|
return
|
|
}
|
|
if code != http.StatusOK {
|
|
errlog = fmt.Sprintf("DXZhiFu ToPay Http.PostJson fail error:%+v/,data:%+v;", err, code)
|
|
err = errors.New(errlog)
|
|
log.Error(errlog)
|
|
return
|
|
}
|
|
if msgModel.Msg != "success" {
|
|
bytes, _ := json.Marshal(msgModel)
|
|
errlog = fmt.Sprintf("LeiHuo topay response err :%s:", string(bytes))
|
|
err = errors.New(errlog)
|
|
log.Error(errlog)
|
|
return
|
|
}
|
|
payURL = msgModel.Data.PageURL
|
|
return
|
|
}
|
|
|
|
// QueryOrder 订单状态查询发起
|
|
func (this *DXZhiFuRes) QueryOrder() (*time.Time, error) {
|
|
var msg struct {
|
|
MercID string `json:"memberid" sign:"1"`
|
|
OID string `json:"orderid" sign:"1"`
|
|
Money string `json:"amount" sign:"1"`
|
|
PayTime string `json:"time_end" sign:"1"`
|
|
TradeNO string `json:"transaction_id" sign:"1"`
|
|
Code string `json:"returncode" sign:"1"`
|
|
Status string `json:"trade_state" sign:"1"`
|
|
Sign string `json:"sign" sign:"1"`
|
|
}
|
|
this.MercID = dc.MercID
|
|
this.Sign = this.ToSign()
|
|
hearder := make(map[string]string)
|
|
hearder["Content-Type"] = " application/x-www-form-urlencoded"
|
|
code, err := httputil.DefaultClientPostWithRespWithProxy(webg.ProxyCfg, &msg, dc.QueryUrl, hearder, common.StructToMap(*this))
|
|
if err != nil || code != 200 {
|
|
log.Error(fmt.Sprintf("DXZhiFu QueryOrder http.Get fail error:%+v:", err))
|
|
return nil, err
|
|
}
|
|
if msg.Code != "00" {
|
|
err = errors.New("DXZhiFu QueryOrder http query fail")
|
|
return nil, err
|
|
}
|
|
if msg.Status != "SUCCESS" {
|
|
return nil, errors.New("DXZhiFu order not pay:" + this.TradeNo)
|
|
}
|
|
loc, _ := time.LoadLocation("Local")
|
|
paymentAt, _ := time.ParseInLocation("20060102150405", msg.PayTime, loc)
|
|
return &paymentAt, nil
|
|
}
|
|
|
|
// Fill 补全配置信息和签名信息
|
|
func (this *DXZhiFu) Fill() {
|
|
this.Format = "json"
|
|
this.MercID = this.GetMercID()
|
|
this.NotifyURL = this.GetNotifyURL()
|
|
this.Type = this.PayMethod
|
|
this.CallbackUrl = this.GetCallBackURL()
|
|
if this.PayIP == "" {
|
|
this.PayIP = genIpaddr()
|
|
}
|
|
this.Sign = this.sign()
|
|
}
|
|
|
|
// sign 签名
|
|
func (this *DXZhiFu) sign() (sign string) {
|
|
ss := this.ToStringSlice()
|
|
sort.Sort(&ss)
|
|
var buf bytes.Buffer
|
|
for k, v := range ss {
|
|
if k == 0 {
|
|
buf.WriteString(v)
|
|
} else {
|
|
buf.WriteString("&")
|
|
buf.WriteString(v)
|
|
}
|
|
}
|
|
buf.WriteString("&key=")
|
|
buf.WriteString(this.GetAppSecret())
|
|
log.Info(fmt.Sprintf("DXZhiFu topay sign :%s", buf.String()))
|
|
sign = strings.ToUpper(md5Sign(buf.String()))
|
|
return
|
|
}
|
|
|
|
// sign 签名
|
|
func (this *DXZhiFuRes) ToSign() (sign string) {
|
|
ss := this.ToStringSlice()
|
|
sort.Sort(&ss)
|
|
var buf bytes.Buffer
|
|
for k, v := range ss {
|
|
if k == 0 {
|
|
buf.WriteString(v)
|
|
} else {
|
|
buf.WriteString("&")
|
|
buf.WriteString(v)
|
|
}
|
|
}
|
|
buf.WriteString("&key=")
|
|
buf.WriteString(dc.AppSecret)
|
|
sign = strings.ToUpper(md5Sign(buf.String()))
|
|
return
|
|
}
|
|
|
|
// ToStringSlice 转化为stirng切片切片
|
|
func (this *DXZhiFu) ToStringSlice() StringList {
|
|
data := make([]string, 0)
|
|
t := reflect.TypeOf(*this)
|
|
v := reflect.ValueOf(*this)
|
|
for k := 0; k < v.NumField(); k++ {
|
|
jsonTag, _ := t.Field(k).Tag.Lookup("json")
|
|
signTag, _ := t.Field(k).Tag.Lookup("sign")
|
|
if v.Field(k).String() != "" && signTag == "1" {
|
|
data = append(data, jsonTag+"="+v.Field(k).String())
|
|
}
|
|
}
|
|
return data
|
|
}
|
|
|
|
// ToStringSlice 转化为stirng切片切片
|
|
func (this *DXZhiFuRes) ToStringSlice() StringList {
|
|
data := make([]string, 0)
|
|
t := reflect.TypeOf(*this)
|
|
v := reflect.ValueOf(*this)
|
|
for k := 0; k < t.NumField(); k++ {
|
|
jsonTag, _ := t.Field(k).Tag.Lookup("json")
|
|
signTag, _ := t.Field(k).Tag.Lookup("sign")
|
|
if v.Field(k).String() != "" && signTag == "1" {
|
|
data = append(data, jsonTag+"="+v.Field(k).String())
|
|
}
|
|
}
|
|
return data
|
|
}
|
|
|
|
// GetBody 获取请求body
|
|
func (this *DXZhiFu) GetBody() interface{} {
|
|
m := make(map[string]string)
|
|
jsonStr, err := json.Marshal(this)
|
|
if err != nil {
|
|
log.Info(fmt.Sprintf("DXZhiFu GetBody json.Marshal is fail error:%+v/data:%+v", err, this))
|
|
}
|
|
sstr := string(jsonStr)
|
|
_ = json.Unmarshal(jsonStr, &m)
|
|
log.Info(fmt.Sprintf("DXZhiFu topay json data :%+v", sstr))
|
|
return m
|
|
}
|
|
|
|
// GetHeader 获取请求头信息
|
|
func (this *DXZhiFu) GetHeader() map[string]string {
|
|
header := make(map[string]string, 0)
|
|
return header
|
|
}
|
|
|
|
// GetURL 获取请求地址
|
|
func (*DXZhiFu) GetURL() string {
|
|
return dc.ExeUrl
|
|
}
|
|
|
|
// GetQueryURL 获取请求地址
|
|
func (*DXZhiFu) GetQueryURL() string {
|
|
return dc.QueryUrl
|
|
}
|
|
|
|
// GetCallBackURL 获取回掉函数
|
|
func (*DXZhiFu) GetNotifyURL() string {
|
|
if appg.Conf != nil {
|
|
return appg.Conf.URL.LocalWebUrl + dc.NotifyUrl
|
|
}
|
|
return webg.Conf.URL.LocalAppUrl + dc.NotifyUrl
|
|
}
|
|
|
|
// GetCallBackURL 获取回掉函数
|
|
func (*DXZhiFu) GetCallBackURL() string {
|
|
return dc.CallbackURL
|
|
}
|
|
|
|
// GetMercID 获取商户编号
|
|
func (*DXZhiFu) GetMercID() string {
|
|
return dc.MercID
|
|
}
|
|
|
|
// GetAppSecret 获取app签名密钥
|
|
func (*DXZhiFu) GetAppSecret() string {
|
|
return dc.AppSecret
|
|
}
|