215 lines
5.7 KiB
Go
215 lines
5.7 KiB
Go
package rchgutil
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"91porn-server/app/appg"
|
|
"91porn-server/common/httputil"
|
|
"91porn-server/common/log"
|
|
)
|
|
|
|
var ylc = config{
|
|
MercID: "xq032",
|
|
AppSecret: "635379bb1abe7ed814c95e083480b09aa2d47d5a",
|
|
ExeUrl: "https://www.hsipxix.cn/?c=Pay",
|
|
NotifyUrl: "/3rd/defray/callback/rchg/yongli",
|
|
}
|
|
|
|
// YongLi 充值订单请求体
|
|
type YongLi struct {
|
|
MercID string `json:"mch_id" sign:"1"` //商户编号
|
|
Type string `json:"ptype" sign:"1"` // 订单充值类型
|
|
TradeNo string `json:"order_sn" sign:"1"` //商户订单号
|
|
Money string `json:"money" sign:"1"` // 支付金额:元
|
|
NotifyURL string `json:"notify_url" sign:"1"` // 回调地址
|
|
Time string `json:"time" sign:"1"`
|
|
Sign string `json:"sign"` // 签名
|
|
PayMethod string `json:"-"`
|
|
Format string `json:"format" sign:"1"`
|
|
Desc string `json:"goods_desc" sign:"1"`
|
|
IP string `json:"client_ip" sign:"1"`
|
|
}
|
|
|
|
type YongLiMsgData struct {
|
|
Type string `json:"ptype" sign:"1"` // 订单充值类型
|
|
PayTypeName string `json:"ptype_name"`
|
|
RealNmae string `json:"realnmae"` //姓名
|
|
Act string `json:"account"` //账户
|
|
PayMoney string `json:"pay_money"`
|
|
Bank string `json:"bank"` //银行
|
|
QRcode string `json:"qrcode"` //二维码
|
|
PayURL string `json:"pay_url"` //
|
|
OID string `json:"order_sn"`
|
|
}
|
|
|
|
type YongLiMsg struct {
|
|
Code string `json:"code" sign:"1"` //交易返回码,返回SUCCESS 表示交易成功(不代表最终结果),
|
|
Data interface{} `json:"data"`
|
|
Msg string `json:"msg"` //签名
|
|
}
|
|
|
|
// RYRes 回调函数参数model
|
|
type YongLiBack struct {
|
|
TradeNo string `json:"sh_order" form:"sh_order" sign:"1"` //商户订单号
|
|
OID string `json:"pt_order" form:"pt_order" sign:"1"` //订单号
|
|
PayMoney float32 `json:"money" form:"money" sign:"1"` //订单到账实际金额
|
|
PayTime int64 `json:"time" form:"time" sign:"1"` //支付时间
|
|
Status string `json:"status" form:"status" sign:"1"` //交易结果 1(成功)
|
|
Sign string `json:"sign" form:"sign" ` //签名
|
|
}
|
|
|
|
// ToPay 支付发起
|
|
func (this *YongLi) ToPay() (res RchgMsg, err error) {
|
|
var errlog string
|
|
this.Fill()
|
|
msg := YongLiMsg{}
|
|
code, err := httputil.DefaultClientPostJsonWithResp(&msg, this.GetURL(), this.GetHeader(), this.GetBody())
|
|
if err != nil {
|
|
errlog = fmt.Sprintf("yongli 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("yongli ToPay response status exception;\nstatus %+v;", code)
|
|
log.Error(errlog)
|
|
err = errors.New(errlog)
|
|
return
|
|
}
|
|
if msg.Code != "1" {
|
|
errlog = fmt.Sprintf("yongli ToPay be rejected;\n msg:%+v:", msg)
|
|
err = errors.New(errlog)
|
|
log.Error(errlog)
|
|
return
|
|
}
|
|
var data YongLiMsgData
|
|
bytes, err := json.Marshal(msg.Data)
|
|
if err != nil {
|
|
errlog = fmt.Sprintf("yongli 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("yongli payUrl urlDecode fail \nerror:%+v;", err)
|
|
log.Error(errlog)
|
|
err = errors.New(errlog)
|
|
return
|
|
}
|
|
res.PayUrl = data.PayURL
|
|
res.OID = data.OID
|
|
res.Mode = "url"
|
|
return
|
|
}
|
|
|
|
// ASenCallBack 阿森结构回调函数
|
|
func (this *YongLiBack) Notify() (RchgBack, error) {
|
|
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 != "success" {
|
|
r.Code = 400
|
|
}
|
|
r.PaymentAt = time.Unix(this.PayTime, 0)
|
|
r.PayMoney = int64(this.PayMoney * 100)
|
|
r.TransNo = this.TradeNo
|
|
r.OID = this.OID
|
|
return r, nil
|
|
}
|
|
|
|
func (this *YongLiBack) Success() string {
|
|
return "success"
|
|
}
|
|
|
|
// Fill 补全配置信息和签名信息
|
|
func (this *YongLi) Fill() {
|
|
switch this.PayMethod {
|
|
case "alipay":
|
|
this.Type = "12"
|
|
case "wechat":
|
|
this.Type = "2"
|
|
}
|
|
this.PayMethod = ""
|
|
this.Format = "json"
|
|
this.Desc = "充值"
|
|
this.IP = genIpaddr()
|
|
this.MercID = this.GetMercID()
|
|
this.NotifyURL = this.GetCallBackURL()
|
|
this.Sign = this.sign()
|
|
}
|
|
|
|
// sign 签名
|
|
func (this *YongLi) sign() string {
|
|
ss := ToStringSlice(*this)
|
|
sort.Sort(&ss)
|
|
var buf bytes.Buffer
|
|
for k := range ss {
|
|
buf.WriteString(ss[k])
|
|
buf.WriteString("&")
|
|
}
|
|
buf.WriteString("key=" + ylc.AppSecret)
|
|
s := buf.String()
|
|
log.Info(fmt.Sprintf("--------------%s", s))
|
|
return strings.ToLower(md5Sign(s))
|
|
|
|
}
|
|
|
|
// sign 签名
|
|
func (this *YongLiBack) ToSign() string {
|
|
ss := ToStringSlice(*this)
|
|
sort.Sort(&ss)
|
|
var buf bytes.Buffer
|
|
for k := range ss {
|
|
buf.WriteString(ss[k])
|
|
buf.WriteString("&")
|
|
}
|
|
buf.WriteString("key=" + ylc.AppSecret)
|
|
log.Info(fmt.Sprintf("--------------%s", buf.String()))
|
|
return strings.ToLower(md5Sign(buf.String()))
|
|
}
|
|
|
|
// GetBody 获取请求body
|
|
func (this *YongLi) GetBody() interface{} {
|
|
m := make(map[string]string)
|
|
jsonStr, err := json.Marshal(this)
|
|
if err != nil {
|
|
log.Info(fmt.Sprintf("YongLi GetBody json.Marshal is fail error:%+v/data:%+v", err, this))
|
|
}
|
|
// sstr := string(jsonStr)
|
|
_ = json.Unmarshal(jsonStr, &m)
|
|
log.Info(fmt.Sprintf("==================%+v", m))
|
|
return m
|
|
}
|
|
|
|
// GetHeader 获取请求头信息
|
|
func (g *YongLi) GetHeader() map[string]string {
|
|
header := make(map[string]string, 0)
|
|
return header
|
|
}
|
|
|
|
// GetURL 获取请求地址
|
|
func (*YongLi) GetURL() string {
|
|
return ylc.ExeUrl
|
|
}
|
|
|
|
// GetCallBackURL 获取回掉函数
|
|
func (*YongLi) GetCallBackURL() string {
|
|
return appg.Conf.URL.LocalWebUrl + ylc.NotifyUrl
|
|
}
|
|
|
|
// GetMercID 获取商户编号
|
|
func (*YongLi) GetMercID() string {
|
|
return ylc.MercID
|
|
}
|