@@ -0,0 +1,207 @@
|
||||
package rchgutil
|
||||
|
||||
import (
|
||||
"crypto/rc4"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"91porn-server/app/appg"
|
||||
"91porn-server/common/httputil"
|
||||
"91porn-server/common/log"
|
||||
)
|
||||
|
||||
var ylws = config{
|
||||
MercID: "10105",
|
||||
AppSecret: "DA1C5476400B1D",
|
||||
ExeUrl: "http://x.aee7.com/gateway/index/checkpoint.do?",
|
||||
NotifyUrl: "/3rd/defray/callback/rchg/",
|
||||
}
|
||||
|
||||
// 订单请求体
|
||||
type WsylInfo struct {
|
||||
AccountId string `json:"account_id"` // 商户ID
|
||||
ContentType string `json:"content_type"` // 返回的网页类型
|
||||
Thoroughfare string `json:"thoroughfare"` // 通道
|
||||
Type string `json:"type"` // 支付类型
|
||||
OutTradeNo string `json:"out_trade_no"` // 商户订单号
|
||||
Robin string `json:"robin"` // 轮训
|
||||
UseCity string `json:"use_city"` // 按地区收款
|
||||
Amount string `json:"amount"` // 支付金额
|
||||
CallbackUrl string `json:"callback_url"` // 异步通知地址
|
||||
SuccessUrl string `json:"success_url"` // 支付成功后网页自动跳转地址
|
||||
ErrorUrl string `json:"error_url"` // 支付失败时,或支付超时后网页自动跳转地址
|
||||
Sign string `json:"sign"` // 签名 必填
|
||||
}
|
||||
|
||||
type WsylMsgData struct {
|
||||
OrderId string `json:"order_id"`
|
||||
Qrcode string `json:"qrcode"`
|
||||
}
|
||||
|
||||
type WsylMsg struct {
|
||||
Code int `json:"code"` // 交易返回码,返回SUCCESS 表示交易成功(不代表最终结果),
|
||||
Msg string `json:"msg"` // 签名
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// 回调函数参数
|
||||
type WsylResultRes struct {
|
||||
AccountName string `form:"account_name" json:"account_name"` // 商户登录名
|
||||
PayTime string `form:"pay_time" json:"pay_time"` // 支付成功的时间戳(10位)
|
||||
Status string `form:"status" json:"status"` // 状态
|
||||
Amount string `form:"amount" json:"amount"` // 订单到账实际金额
|
||||
OutTradeNo string `form:"out_trade_no" json:"out_trade_no"` // 订单信息,在发起订单时附加的信息,如用户名,充值订单号等字段参数
|
||||
TradeNo string `form:"trade_no" json:"trade_no"` // 交易流水号,由系统生成的交易流水号
|
||||
Fees string `form:"fees" json:"fees"` // 手续费,本次回调过程产生的手续费用(已经在平台账户中扣除)
|
||||
Sign string `form:"sign" json:"sign"` // 签名
|
||||
CallbackTime string `form:"callback_time" json:"callback_time"` // 回调时间,在回调时产生的时间戳(10位)
|
||||
Type string `form:"type" json:"type"` // 支付类型
|
||||
AccountKey string `form:"account_key" json:"account_key"` // 商户KEY
|
||||
}
|
||||
|
||||
// ToPay 支付发起
|
||||
func (wyi *WsylInfo) toPay() (res RchgMsg, err error) {
|
||||
var errLog string
|
||||
msg := WsylMsg{}
|
||||
wyi.fill()
|
||||
code, err := httputil.DefaultClientPostJsonWithResp(&msg, ylws.ExeUrl, wyi.getHeader(), wyi.getBody())
|
||||
if err != nil {
|
||||
errLog = fmt.Sprintf("Wsyl ToPay requset fail \nerror:%+v\n\ndata:%+v;", err, wyi)
|
||||
log.Error(errLog)
|
||||
err = errors.New(errLog)
|
||||
return
|
||||
}
|
||||
if code != http.StatusOK {
|
||||
errLog = fmt.Sprintf("Wsyl ToPay response status exception;\nstatus %+v;", code)
|
||||
log.Error(errLog)
|
||||
err = errors.New(errLog)
|
||||
return
|
||||
}
|
||||
if msg.Code != 200 {
|
||||
errLog = fmt.Sprintf("Wsyl ToPay be rejected;\n msg:%+v:", msg)
|
||||
err = errors.New(errLog)
|
||||
log.Error(errLog)
|
||||
return
|
||||
}
|
||||
var data WsylMsgData
|
||||
bytes, err := json.Marshal(msg.Data)
|
||||
if err != nil {
|
||||
errLog = fmt.Sprintf("Wsyl 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("Wsyl payUrl urlDecode fail \nerror:%+v;", err)
|
||||
log.Error(errLog)
|
||||
err = errors.New(errLog)
|
||||
return
|
||||
}
|
||||
res.PayUrl = data.Qrcode
|
||||
res.Mode = "url"
|
||||
res.OID = data.OrderId
|
||||
return
|
||||
}
|
||||
|
||||
// Notify 回调函数
|
||||
func (this *WsylResultRes) Notify() (RchgBack, error) {
|
||||
r := RchgBack{}
|
||||
if this.SignRes() != this.Sign {
|
||||
log.Error(fmt.Sprintf("Wsyl callback sign verify fail ,data:%+v", this))
|
||||
return r, errors.New("check sign fail")
|
||||
}
|
||||
if this.PayTime == "" {
|
||||
return r, errors.New("querry order err,no payTime")
|
||||
}
|
||||
sec, err := strconv.ParseInt(this.PayTime, 10, 64)
|
||||
if err != nil {
|
||||
log.Error("time.ParseInLocation failed", log.Any("TradeNo", this.TradeNo), log.E(err))
|
||||
return r, err
|
||||
}
|
||||
paymentAt := time.Unix(sec, 0)
|
||||
payMoneyf, err := strconv.ParseFloat(this.Amount, 64)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("Wsyl callback ParseFloat fail data:%+v:", this))
|
||||
return r, fmt.Errorf("invalid payMoney %s", this.Amount)
|
||||
}
|
||||
r.PayMoney = int64(payMoneyf * 100)
|
||||
r.PaymentAt = paymentAt
|
||||
r.TransNo = this.OutTradeNo
|
||||
r.OID = this.TradeNo
|
||||
r.Code = 400
|
||||
if this.Status == "success" {
|
||||
r.Code = 200
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (this *WsylResultRes) Success() string {
|
||||
return "success"
|
||||
}
|
||||
|
||||
// 补全配置信息和签名信息
|
||||
func (wyi *WsylInfo) fill() {
|
||||
wyi.AccountId = ylws.MercID
|
||||
wyi.ContentType = "json"
|
||||
wyi.Thoroughfare = "paofen_auto"
|
||||
wyi.Type = "71"
|
||||
wyi.Robin = "2"
|
||||
wyi.UseCity = "2"
|
||||
wyi.CallbackUrl = wyi.getNotifyURL()
|
||||
wyi.SuccessUrl = wyi.getNotifyURL()
|
||||
wyi.ErrorUrl = wyi.getNotifyURL()
|
||||
wyi.Sign = wyi.signReq()
|
||||
}
|
||||
|
||||
// 充值请求签名
|
||||
func (wyi *WsylInfo) signReq() (sign string) {
|
||||
return DealSign(ylws.AppSecret, wyi.Amount, wyi.OutTradeNo)
|
||||
}
|
||||
|
||||
func DealSign(key_id string, amount string, out_trade_no string) (sign string) {
|
||||
var data = amount + out_trade_no
|
||||
md5Str := md5Sign(data)
|
||||
c, err := rc4.NewCipher([]byte(key_id))
|
||||
if err != nil {
|
||||
// log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
src := []byte(md5Str)
|
||||
dst := make([]byte, len(src))
|
||||
c.XORKeyStream(dst, src)
|
||||
fmt.Println(string(src), string(dst))
|
||||
rc4Str := md5Sign(string(dst))
|
||||
return rc4Str
|
||||
}
|
||||
|
||||
// 充值成功回调签名
|
||||
func (wyc *WsylResultRes) SignRes() (sign string) {
|
||||
return DealSign(ylws.AppSecret, wyc.Amount, wyc.OutTradeNo)
|
||||
}
|
||||
|
||||
// 获取请求body
|
||||
func (wyi *WsylInfo) getBody() interface{} {
|
||||
m := make(map[string]string)
|
||||
jsonStr, err := json.Marshal(wyi)
|
||||
if err != nil {
|
||||
log.Info(fmt.Sprintf("WSYL GetBody json.Marshal is fail error:%+v/data:%+v", err, wyi))
|
||||
}
|
||||
sstr := string(jsonStr)
|
||||
log.Info(fmt.Sprintf("==================%+v", sstr))
|
||||
_ = json.Unmarshal(jsonStr, &m)
|
||||
return m
|
||||
}
|
||||
|
||||
// 获取请求头
|
||||
func (wyi *WsylInfo) getHeader() map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取回掉函数
|
||||
func (wyi *WsylInfo) getNotifyURL() (url string) {
|
||||
return appg.Conf.URL.LocalWebUrl + ylws.NotifyUrl + YongLiWanShun
|
||||
}
|
||||
Reference in New Issue
Block a user