|
|
package wt_sdk
|
|
|
|
|
|
import (
|
|
|
"gitea.weitiangame.com/sdk/wt-game/utils"
|
|
|
"sort"
|
|
|
"strings"
|
|
|
"sync"
|
|
|
)
|
|
|
|
|
|
// Order 表示订单对象,用于签名参数
|
|
|
type Order struct {
|
|
|
Uid string // 用户ID
|
|
|
BsTradeNo string // 交易编号
|
|
|
Role string // 用户角色
|
|
|
RoleId string // 角色ID
|
|
|
ServerId string // 服务器ID
|
|
|
GoodsName string // 商品名称
|
|
|
OutTradeNo string // 外部交易编号
|
|
|
Body string // 商品描述
|
|
|
CpExtraInfo string // 扩展信息
|
|
|
TradeState string // 交易状态
|
|
|
TotalFee string // 总费用
|
|
|
PayFee string // 支付费用
|
|
|
PayTime string // 支付时间
|
|
|
}
|
|
|
|
|
|
// SDK结构体封装了SDK的配置和工具函数
|
|
|
type SDK struct {
|
|
|
SecretKey string // 秘钥
|
|
|
}
|
|
|
|
|
|
// 单例实例和互斥锁,确保线程安全
|
|
|
var instance *SDK
|
|
|
var once sync.Once
|
|
|
|
|
|
// NewOrderPayment 返回一个SDK单例实例,初始化时传入秘钥
|
|
|
func NewOrderPayment(secretKey string) *SDK {
|
|
|
once.Do(func() {
|
|
|
instance = &SDK{
|
|
|
SecretKey: secretKey,
|
|
|
}
|
|
|
})
|
|
|
return instance // 返回单例实例
|
|
|
}
|
|
|
|
|
|
// SignParam 为提供的Order对象生成签名
|
|
|
func (s *SDK) SignParam(order *Order) (string, error) {
|
|
|
// 创建待签名参数映射
|
|
|
paramMap := s.createParamMap(order)
|
|
|
|
|
|
// 按照字典顺序排序并生成待签名字符串
|
|
|
signStr := s.BuildSignString(paramMap)
|
|
|
|
|
|
// 计算最终签名并返回
|
|
|
return utils.Md5String(signStr), nil
|
|
|
}
|
|
|
|
|
|
// createParamMap 构建参数映射,跳过 "sign" 和 "-" 键
|
|
|
func (s *SDK) createParamMap(order *Order) map[string]string {
|
|
|
return map[string]string{
|
|
|
"uid": order.Uid,
|
|
|
"bs_trade_no": order.BsTradeNo,
|
|
|
"role": order.Role,
|
|
|
"role_id": order.RoleId,
|
|
|
"server_id": order.ServerId,
|
|
|
"goods_name": order.GoodsName,
|
|
|
"out_trade_no": order.OutTradeNo,
|
|
|
"body": order.Body,
|
|
|
"extra_info": order.CpExtraInfo,
|
|
|
"order_status": order.TradeState,
|
|
|
"total_fee": order.TotalFee,
|
|
|
"pay_fee": order.PayFee,
|
|
|
"pay_time": order.PayTime,
|
|
|
"sign": "", // 初始化签名为空
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// buildSignString 按照字典顺序排序参数并拼接成签名字符串
|
|
|
func (s *SDK) BuildSignString(params map[string]string) string {
|
|
|
var builder strings.Builder
|
|
|
keys := s.getSortedKeys(params) // 获取排序后的键
|
|
|
|
|
|
// 拼接所有键对应的值
|
|
|
for _, k := range keys {
|
|
|
builder.WriteString(params[k])
|
|
|
}
|
|
|
|
|
|
// 将秘钥追加到签名字符串后
|
|
|
builder.WriteString(s.SecretKey)
|
|
|
|
|
|
return builder.String()
|
|
|
}
|
|
|
|
|
|
// getSortedKeys 返回排除 "sign" 和 "-" 键后的排序键列表
|
|
|
func (s *SDK) getSortedKeys(params map[string]string) []string {
|
|
|
var keys []string
|
|
|
for k := range params {
|
|
|
// 跳过 "sign" 和 "-" 键
|
|
|
if k == "sign" || k == "-" {
|
|
|
continue
|
|
|
}
|
|
|
keys = append(keys, k)
|
|
|
}
|
|
|
sort.Strings(keys) // 排序键
|
|
|
return keys
|
|
|
}
|