生成签名优化

tags/v0.0.1^0 v0.0.1
zhuxianglong 2 months ago
parent e3fd6326dc
commit 1b3d551f0c

@ -2,9 +2,6 @@ module gitea.weitiangame.com/sdk/wt-game
go 1.20
require (
github.com/go-resty/resty/v2 v2.16.3
go.uber.org/zap v1.27.0
)
require github.com/go-resty/resty/v2 v2.16.3
require golang.org/x/net v0.33.0 // indirect

@ -1,11 +1,5 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/go-resty/resty/v2 v2.16.3 h1:zacNT7lt4b8M/io2Ahj6yPypL7bqx9n1iprfQuodV+E=
github.com/go-resty/resty/v2 v2.16.3/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

@ -0,0 +1,118 @@
# SDK 使用文档
## 概述
本SDK 提供了生成签名的功能,主要用于订单相关操作的签名验证。
## 安装
在Go项目中导入本SDK
```bash
go get "gitea.weitiangame.com/sdk/wt-game"
```
请将 `"gitea.weitiangame.com/sdk/wt-game"` 替换为实际的导入路径。
## 初始化
通过 `New` 函数创建SDK实例并传入秘钥
```go
import (
"fmt"
"gitea.weitiangame.com/sdk/wt-game/sdk"
)
func main() {
secretKey := "your_secret_key"
sdk := sdk.New(secretKey)
// 继续使用SDK
}
```
## 生成签名
创建一个 `Order` 对象并填充相关字段,然后调用 `SignParam` 方法生成签名:
```go
order := &sdk.Order{
Uid: "12345",
BsTradeNo: "TRADE001",
Role: "Player",
RoleId: "ROLE001",
ServerId: "SERVER01",
GoodsName: "Game Coin",
OutTradeNo: "OUT001",
Body: "Purchase Game Coin",
CpExtraInfo: "extra_info",
TradeState: "SUCCESS",
TotalFee: "100",
PayFee: "95",
PayTime: "2023-10-05 14:30:00",
}
sign, err := sdk.SignParam(order)
if err != nil {
fmt.Println("生成签名失败:", err)
return
}
fmt.Println("签名:", sign)
```
## 示例代码
完整的示例代码如下:
```go
package main
import (
"fmt"
"gitea.weitiangame.com/sdk/wt-game/sdk"
)
func main() {
secretKey := "your_secret_key"
sdk := sdk.New(secretKey)
order := &sdk.Order{
Uid: "12345",
BsTradeNo: "TRADE001",
Role: "Player",
RoleId: "ROLE001",
ServerId: "SERVER01",
GoodsName: "Game Coin",
OutTradeNo: "OUT001",
Body: "Purchase Game Coin",
CpExtraInfo: "extra_info",
TradeState: "SUCCESS",
TotalFee: "100",
PayFee: "95",
PayTime: "2023-10-05 14:30:00",
}
sign, err := sdk.SignParam(order)
if err != nil {
fmt.Println("生成签名失败:", err)
return
}
fmt.Println("签名:", sign)
}
```
## 注意事项
- **秘钥安全**:秘钥是生成签名的重要参数,务必妥善保管,防止泄露。
- **签名生成**:签名生成过程中,参数按字典序排序,并且排除`sign`和`-`字段。
- **时间格式**`PayTime`字段请使用`YYYY-MM-DD HH:MM:SS`格式,以保证签名的一致性。
## 常见问题
- **签名不匹配**:请检查参数是否正确,秘钥是否一致,以及时间格式是否正确。
## 联系方式
如有任何问题,请联系开发人员或查阅相关文档。

@ -1,70 +0,0 @@
package sdk
import (
"fmt"
"github.com/go-resty/resty/v2"
"sync"
"time"
)
// Configuration for SDK
type HttpConfig struct {
AppID string
PlatformID string // Renamed for consistency
ChannelID string
AppSecret string
BaseURL string // Either Test or Production
}
// RequestParams for common parameters
type RequestParams map[string]interface{} // Renamed to be more descriptive
// Response for API responses
type Response struct {
ErrorCode int `json:"code"` // Renamed to ErrorCode for clarity
ErrorMessage string `json:"msg"` // Renamed to ErrorMessage for clarity
}
var (
clientInstance *Client
once sync.Once
)
// NewClient initializes the SDK client with reusable resty client (Singleton)
func NewClient(config Config) *Client {
once.Do(func() {
clientInstance = &Client{
config: config,
client: resty.New().SetRetryCount(3).SetRetryWaitTime(1 * time.Second),
}
})
return clientInstance
}
// Client struct to manage requests
type Client struct {
config Config
client *resty.Client
}
// HTTP POST helper function with retry logic
func (c *Client) post(url string, params interface{}) (*Response, error) {
// Retry up to 3 times with a 1-second delay between retries
var resp *Response
response, err := c.client.R().
SetBody(params).
SetResult(&resp). // Set result to unmarshal JSON into Response struct
Post(url)
if err != nil {
return nil, fmt.Errorf("request failed: %v", err)
}
// Check the response status code
if response.StatusCode() != 200 {
return nil, fmt.Errorf("non-200 response received: %v", response.StatusCode())
}
// Return the response body directly after it has been unmarshalled
return resp, nil
}

@ -3,7 +3,6 @@ package sdk
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"sort"
"strings"
"sync"
@ -26,11 +25,6 @@ type Order struct {
PayTime string // 支付时间
}
// Config 用于保存SDK的配置信息例如appId和secretKey
type Config struct {
SecretKey string // 秘钥
}
// SDK结构体封装了SDK的配置和工具函数
type SDK struct {
SecretKey string // 秘钥
@ -38,11 +32,11 @@ type SDK struct {
// 单例实例和互斥锁,确保线程安全
var instance *SDK
var onces sync.Once
var once sync.Once
// New 返回一个SDK单例实例初始化时传入秘钥
func New(secretKey string) *SDK {
onces.Do(func() {
once.Do(func() {
instance = &SDK{
SecretKey: secretKey,
}
@ -62,7 +56,7 @@ func (s *SDK) SignParam(order *Order) (string, error) {
paramMap := s.createParamMap(order)
// 按照字典顺序排序并生成待签名字符串
signStr := s.buildSignString(paramMap)
signStr := s.BuildSignString(paramMap)
// 计算最终签名并返回
return s.Md5String(signStr), nil
@ -89,7 +83,7 @@ func (s *SDK) createParamMap(order *Order) map[string]string {
}
// buildSignString 按照字典顺序排序参数并拼接成签名字符串
func (s *SDK) buildSignString(params map[string]string) string {
func (s *SDK) BuildSignString(params map[string]string) string {
var builder strings.Builder
keys := s.getSortedKeys(params) // 获取排序后的键
@ -117,13 +111,3 @@ func (s *SDK) getSortedKeys(params map[string]string) []string {
sort.Strings(keys) // 排序键
return keys
}
// ToJson 将一个接口类型转换为JSON字符串
func (s *SDK) ToJson(item interface{}) (string, error) {
// 使用json.Marshal将对象转换为JSON
res, err := json.Marshal(item)
if err != nil {
return "", err // 返回错误
}
return string(res), nil // 返回JSON字符串
}

Loading…
Cancel
Save