Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+349
View File
@@ -0,0 +1,349 @@
package rchgutil
import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"net/http"
"strconv"
"time"
"91porn-server/app/appg"
"91porn-server/common"
"91porn-server/common/httputil"
"91porn-server/common/log"
"91porn-server/web/webg"
)
var dbsc = config{
MercID: "10082",
AppSecret: "b8f217afdcac162b569f856174bd811a",
ExeUrl: "https://umio.zjcthbkj.com/api/shark/topay",
QueryUrl: "https://umio.zjcthbkj.com/api/shark/order/queryOrder",
NotifyUrl: "/3rd/defray/callback/rchg/dabaisha",
}
const (
DaBaiSha_Alipay_Code = "1001"
DaBaiSha_Wechat_Code = "1002"
DaBaiSha_Union_Code = "1003"
)
// DaBaiSha 充值订单请求体
type DaBaiSha struct {
MercID string `json:"mercId"` //商户编号
Type string `json:"type"` // 订单充值类型
Money string `json:"money"` // 充值⾦额
TradeNo string `json:"tradeNo"` //商户订单号
NotifyURL string `json:"notifyUrl"` // 回调地址
Info DaBaiShaInfo `json:"info"` // 用户信息
Time string `json:"time"` //UTC时间戳(13位)
Mode string `json:"mode,omitempty"` //式模 持支 表代则传 值定固。填选
Sign string `json:"sign"` // 签名
PayMethod string
}
// DaBaiShaInfo 玩家信息
type DaBaiShaInfo struct {
PlayerID string `json:"playerId"` // 玩家ID
PlayerIP string `json:"playerIp"` // 玩家IP
DeviceID string `json:"deviceId"` // 玩家设备ID
DeviceType string `json:"deviceType"` // 玩家设备类型 ios pc android
Name string `json:"name"` // 玩家姓名
Tel string `json:"tel"` // 玩家⼿机号
AlipayAct string `json:"alipayAct"` // 玩家支付宝账号
}
// DaBaiShaRes 回调函数参数model
type DaBaiShaRes struct {
Code int `json:"code" binding:"required"`
MercID string `json:"mercId" binding:"required"` //商户编号
OID string `json:"oid" binding:"required"` //支付平台订单号
PayMoney string `json:"payMoney" binding:"required"` //订单到账实际金额
TradeNo string `json:"tradeNo" binding:"required"` //商户订单号
Sign string `json:"sign" binding:"required"` //签名
}
type QueryMSG struct {
MercID string `json:"mercID"`
TradeNo string `json:"tradeNo"`
Money float32 `json:"money"`
PayMoney float32 `json:"payMoney"`
PayTime string `json:"payTime"`
PayStatus string `json:"payStatus"`
NotifyStatus string `json:"notifyStatus"`
}
// ToPay 支付发起
func (this *DaBaiSha) ToPay() (res RchgMsg, err error) {
var errlog string
this.Fill()
msgModel := MsgModel{}
code, err := httputil.DefaultClientPostJsonWithRespWithProxy(appg.ProxyCfg, &msgModel, this.GetURL(), this.GetHeader(), this.GetBody())
if err != nil {
errlog = fmt.Sprintf("DaBaiSha 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("DaBaiSha ToPay response status exception;\nstatus %+v;", code)
err = errors.New(errlog)
log.Error(errlog)
return
}
if msgModel.Code != 200 {
switch msgModel.Code {
case 40001:
err = PAY_CHANNEL_CLOSE_ERROR
case 80002:
err = PAY_CHANNEL_BAN_ERROR
default:
bytes, _ := json.Marshal(msgModel)
errlog = fmt.Sprintf("DaBaiSha ToPay be rejected;\n data:%+v:", string(bytes))
err = errors.New(errlog)
}
log.Error(errlog)
return
}
msg := msgModel.Msg
var buf bytes.Buffer
buf.WriteString(msg["oid"])
buf.WriteString(msg["payUrl"])
buf.WriteString(this.GetAppSecret())
if !VerifySign(msg["sign"], buf.String()) {
errlog = fmt.Sprintf("http goldfish VerifySign fail \nerr :%+v \ndata:%+v", err, msgModel)
err = errors.New(errlog)
log.Error(errlog)
return
}
res.PayUrl = msg["payUrl"]
res.OID = msg["oid"]
res.Mode = msg["mode"]
return
}
// QueryOrder 订单状态查询发起
func (g *DaBaiSha) QueryOrder() (msg QueryMSG, err error) {
var res struct {
Code int `json:"code"`
MSG QueryMSG `json:"msg"`
}
body := make(map[string]string)
body["mercId"] = g.GetMercID()
body["tradeNo"] = g.TradeNo
code, err := httputil.DefaultClientGetWithResp(&res, g.GetQueryURL(), nil, body)
if err != nil || code != 200 {
log.Error(fmt.Sprintf("goldfish QueryOrder http.Get fail error:%+v:", err))
return
}
if res.Code != 200 {
err = errors.New("goldfish QueryOrder http query fail")
return
}
msg = res.MSG
return
}
// ASenCallBack 阿森结构回调函数
func (this *DaBaiShaRes) Notify() (RchgBack, error) {
r := RchgBack{}
buf := bytes.Buffer{}
buf.WriteString(strconv.Itoa(this.Code))
buf.WriteString(this.MercID)
buf.WriteString(this.OID)
buf.WriteString(this.PayMoney)
buf.WriteString(this.TradeNo)
buf.WriteString(dbsc.AppSecret)
if !VerifySign(this.Sign, buf.String()) {
log.Error(fmt.Sprintf("DaBaiSha callback sign verify fail ,data:%+v", this))
return r, errors.New("check sign fail")
}
g := DaBaiSha{
TradeNo: this.TradeNo,
}
msg, err := g.QueryOrder() //订单状态查询发起
if err != nil {
return r, err
}
if msg.PayTime == "" {
return r, errors.New("querry order err,no payTime")
}
loc, _ := time.LoadLocation("Local")
paymentAt, err := time.ParseInLocation("2006-01-02T15:04:05Z07:00", msg.PayTime, loc)
if err != nil {
log.Error("time.ParseInLocation failed", log.Any("TradeNo", this.TradeNo), log.E(err))
return r, err
}
payMoneyf, err := strconv.ParseFloat(this.PayMoney, 64)
if err != nil {
log.Error(fmt.Sprintf("DaBaiSha callback ParseFloat fail data:%+v:", this))
return r, fmt.Errorf("invalid payMoney %s", this.PayMoney)
}
r.PayMoney = int64(payMoneyf * 100)
r.PaymentAt = paymentAt
r.TransNo = this.TradeNo
r.OID = this.OID
r.Code = this.Code
return r, nil
}
func (this *DaBaiShaRes) Success() string {
return "success"
}
type PayType struct {
Name string `json:"name"`
PayMent string `json:"payMent"`
Type string `json:"type"`
}
type PayTypes struct {
Money string `json:"money"`
Types []PayType `json:"types"`
}
// QueryOrder 订单状态查询发起
func (g *DaBaiSha) GetPayType(moneys []string, mode string) (payTypes []PayTypes, err error) {
var errlog string
var res struct {
Code int `json:"code"`
MSG []PayTypes `json:"msg"`
Err string `json:"err"`
}
body := make(map[string]interface{})
body["mercId"] = g.GetMercID()
body["money"] = moneys
body["time"] = GetUTCTimeMS(time.Now())
if mode != "" {
body["mode"] = mode
}
var moneysStr bytes.Buffer
for k, v := range moneys {
if k == 0 {
moneysStr.WriteString(v)
} else {
moneysStr.WriteString(",")
moneysStr.WriteString(v)
}
}
fmt.Println(moneysStr.String())
body["sign"] = md5Sign(dbsc.MercID + moneysStr.String() + dbsc.AppSecret)
code, err := httputil.DefaultClientPostJsonWithResp(&res, g.GetGetTypeURL(), nil, body)
if err != nil {
errlog = fmt.Sprintf("DaBaiSha GetPayType requset fail \nerror:%+v\n\ndata:%+v;", err, body)
log.Error(errlog)
err = errors.New(errlog)
return
}
if code != http.StatusOK {
errlog = fmt.Sprintf("DaBaiSha GetPayType response status exception;\nstatus %+v;", code)
err = errors.New(errlog)
log.Error(errlog)
return
}
if res.Code != 200 {
errlog = fmt.Sprintf("DaBaiSha GetPayType be rejected;\n err:%+v:", res.Err)
err = errors.New(errlog)
log.Error(errlog)
return
}
log.Info(fmt.Sprintf("DaBaiSha GetPayType data:%+v:", res))
payTypes = res.MSG
return
}
// Fill 补全配置信息和签名信息
func (g *DaBaiSha) Fill() {
g.MercID = g.GetMercID()
g.NotifyURL = g.GetCallBackURL()
switch g.PayMethod {
case "alipay":
g.Type = "fixedAlipay"
case "wechat":
g.Type = "fixedWechat"
case "union":
g.Type = "union"
}
g.PayMethod = ""
if g.Info.Name == "" {
g.Info.Name = GetFullName()
}
if g.Info.PlayerIP == "" {
g.Info.PlayerIP = genIpaddr()
}
if g.Info.DeviceID == "" {
g.Info.DeviceID = common.UUID()
}
if g.Info.DeviceType == "" {
g.Info.DeviceType = "ios"
}
g.Sign = g.sign()
}
// sign 签名
func (g *DaBaiSha) sign() (sign string) {
var buf bytes.Buffer
buf.WriteString(g.GetMercID())
buf.WriteString(g.Money)
buf.WriteString(g.GetCallBackURL())
buf.WriteString(g.TradeNo)
buf.WriteString(g.Type)
buf.WriteString(g.GetAppSecret())
md5Ctx := md5.New()
md5Ctx.Write(buf.Bytes())
cipherStr := md5Ctx.Sum(nil)
return hex.EncodeToString(cipherStr)
}
// GetBody 获取请求body
func (g *DaBaiSha) GetBody() interface{} {
jsonStr, err := json.Marshal(g)
if err != nil {
log.Info(fmt.Sprintf("DaBaiSha GetBody json.Marshal is fail error:%+v/data:%+v", err, g))
}
sstr := string(jsonStr)
log.Info(fmt.Sprintf("==================%+v", sstr))
return jsonStr
}
// GetHeader 获取请求头信息
func (g *DaBaiSha) GetHeader() map[string]string {
header := make(map[string]string, 0)
return header
}
// GetURL 获取请求地址
func (*DaBaiSha) GetURL() string {
return dbsc.ExeUrl
}
// GetQueryURL 获取请求地址
func (*DaBaiSha) GetQueryURL() string {
return dbsc.QueryUrl
}
// GetQueryURL 获取请求地址
func (*DaBaiSha) GetGetTypeURL() string {
return "https://umio.zjcthbkj.com/api/shark/getPayType"
}
// GetMercID 获取商户编号
func (*DaBaiSha) GetMercID() string {
return dbsc.MercID
}
// GetAppSecret 获取app签名密钥
func (*DaBaiSha) GetAppSecret() string {
return dbsc.AppSecret
}
// GetCallBackURL 获取回掉函数
func (*DaBaiSha) GetCallBackURL() string {
if appg.Conf != nil {
return appg.Conf.URL.LocalWebUrl + dbsc.NotifyUrl
}
return webg.Conf.URL.LocalAppUrl + dbsc.NotifyUrl
}