tags/v0.0.1
zhuxianglong 2 months ago
parent eadd54d13f
commit e3fd6326dc

@ -9,57 +9,68 @@ import (
"sync" "sync"
) )
// Order represents an order object used for signing parameters // Order 表示订单对象,用于签名参数
type Order struct { type Order struct {
Uid string Uid string // 用户ID
BsTradeNo string BsTradeNo string // 交易编号
Role string Role string // 用户角色
RoleId string RoleId string // 角色ID
ServerId string ServerId string // 服务器ID
GoodsName string GoodsName string // 商品名称
OutTradeNo string OutTradeNo string // 外部交易编号
Body string Body string // 商品描述
CpExtraInfo string CpExtraInfo string // 扩展信息
TradeState string TradeState string // 交易状态
TotalFee string TotalFee string // 总费用
PayFee string PayFee string // 支付费用
PayTime string PayTime string // 支付时间
} }
// Config holds the configuration for SDK, such as appId and secret keys // Config 用于保存SDK的配置信息例如appId和secretKey
type Config struct { type Config struct {
SecretKey string SecretKey string // 秘钥
} }
// SDK struct encapsulates SDK configuration and utility functions // SDK结构体封装了SDK的配置和工具函数
type SDK struct { type SDK struct {
SecretKey string SecretKey string // 秘钥
} }
// Singleton instance and mutex for thread safety // 单例实例和互斥锁,确保线程安全
var instance *SDK var instance *SDK
var once2 sync.Once var onces sync.Once
// New initializes a new SDK with the given configuration, but ensures that only one instance exists. // New 返回一个SDK单例实例初始化时传入秘钥
func New(secretKey string) *SDK { func New(secretKey string) *SDK {
once2.Do(func() { onces.Do(func() {
instance = &SDK{ instance = &SDK{
SecretKey: secretKey, SecretKey: secretKey,
} }
}) })
return instance return instance // 返回单例实例
} }
// Md5String generates MD5 hash of a given string // Md5String 生成给定字符串的MD5哈希值并返回十六进制字符串
func (s *SDK) Md5String(str string) string { func (s *SDK) Md5String(str string) string {
hash := md5.Sum([]byte(str)) // Use md5.Sum for fixed size output hash := md5.Sum([]byte(str)) // 计算MD5哈希
return hex.EncodeToString(hash[:]) return hex.EncodeToString(hash[:]) // 转为十六进制字符串并返回
} }
// SignParam generates a signed URL-encoded string for the provided Order object // SignParam 为提供的Order对象生成签名
func (s *SDK) SignParam(order *Order) (string, error) { func (s *SDK) SignParam(order *Order) (string, error) {
// Create a map of the parameters to be signed // 创建待签名参数映射
paramMap := map[string]string{ paramMap := s.createParamMap(order)
// 按照字典顺序排序并生成待签名字符串
signStr := s.buildSignString(paramMap)
// 计算最终签名并返回
return s.Md5String(signStr), nil
}
// createParamMap 构建参数映射,跳过 "sign" 和 "-" 键
func (s *SDK) createParamMap(order *Order) map[string]string {
return map[string]string{
"uid": order.Uid, "uid": order.Uid,
"bs_trade_no": order.BsTradeNo, "bs_trade_no": order.BsTradeNo,
"role": order.Role, "role": order.Role,
@ -73,43 +84,46 @@ func (s *SDK) SignParam(order *Order) (string, error) {
"total_fee": order.TotalFee, "total_fee": order.TotalFee,
"pay_fee": order.PayFee, "pay_fee": order.PayFee,
"pay_time": order.PayTime, "pay_time": order.PayTime,
"sign": "", "sign": "", // 初始化签名为空
}
} }
// Generate the signed value // buildSignString 按照字典顺序排序参数并拼接成签名字符串
signStr := s.SortMapString(paramMap) + s.SecretKey func (s *SDK) buildSignString(params map[string]string) string {
var builder strings.Builder
keys := s.getSortedKeys(params) // 获取排序后的键
// Return the MD5 hash // 拼接所有键对应的值
return s.Md5String(signStr), nil for _, k := range keys {
builder.WriteString(params[k])
} }
// SortMapString sorts the keys of a map and returns a concatenated string // 将秘钥追加到签名字符串后
func (s *SDK) SortMapString(params map[string]string) string { builder.WriteString(s.SecretKey)
var builder strings.Builder
keys := make([]string, 0, len(params)) return builder.String()
}
// Avoid sorting the "sign" and "-" keys // getSortedKeys 返回排除 "sign" 和 "-" 键后的排序键列表
func (s *SDK) getSortedKeys(params map[string]string) []string {
var keys []string
for k := range params { for k := range params {
// 跳过 "sign" 和 "-" 键
if k == "sign" || k == "-" { if k == "sign" || k == "-" {
continue continue
} }
keys = append(keys, k) keys = append(keys, k)
} }
sort.Strings(keys) // Sort the keys sort.Strings(keys) // 排序键
return keys
// Efficiently concatenate the values
for _, k := range keys {
builder.WriteString(params[k])
}
return builder.String()
} }
// ToJson converts an interface{} to JSON string // ToJson 将一个接口类型转换为JSON字符串
func (s *SDK) ToJson(item interface{}) (string, error) { func (s *SDK) ToJson(item interface{}) (string, error) {
// 使用json.Marshal将对象转换为JSON
res, err := json.Marshal(item) res, err := json.Marshal(item)
if err != nil { if err != nil {
return "", err // Simplified error handling return "", err // 返回错误
} }
return string(res), nil return string(res), nil // 返回JSON字符串
} }

Loading…
Cancel
Save