Skip to content

05 · Go SDK 使用文档

linkepay-sdk-go 封装了签名、请求、验签,Go 商户推荐直接使用。


1. 安装

bash
go get github.com/linkepay/linkepay-sdk-go
go mod tidy

要求 Go 1.23+。


2. 初始化客户端

go
package main

import (
	linkepay "github.com/linkepay/linkepay-sdk-go"
	"github.com/linkepay/linkepay-sdk-go/types"
)

var client *linkepay.Client

func init() {
	client = linkepay.NewClient(&types.Config{
		// 生产环境(主网)
		BaseURL: "https://linkepay-api.bestxx.com",

		ProjectID:  "<PROJECT_UID>",           // 平台分配,如 Ab3xY9Kq7Z
		PrivateKey: "<MERCHANT_PRIVATE_KEY>",  // 商户私钥,0x + 64 hex,用于请求签名
		PublicKey:  "<MERCHANT_PUBLIC_KEY>",   // 商户公钥(需已登记到平台)
		ApiKey:     "<API_KEY>",               // 查询类接口需要

		// 平台公钥,用于验证回调 / 响应签名
		PayPlatformPublicKey: "0xc0b2388188f35c087400575393c124e9c459550f1dfcf848214f47637b599ee08a6b64876c4687e869d070d892b97071fd4c90b0a3491814823b4e97f8e7d50f",

		Timeout: 30, // 秒,默认 30
	})
}

Config 字段说明:

字段必填用途
BaseURL生产环境填 https://linkepay-api.bestxx.com
ProjectID拼进所有接口路径
PrivateKey写接口必填生成 X-Signature
PublicKey建议填自检用;平台侧用的是已登记的那份
ApiKey查询接口必填生成 X-API-Key
PayPlatformPublicKey回调验签必填VerifyPlatformSignature / ParseCallbackData 使用
Timeout请求超时(秒),默认 30

配置来源:私钥和 API Key 请从环境变量 / KMS / K8s Secret 注入,不要写进代码或提交到仓库。


3. 方法一览

方法对应接口鉴权
CreateDepositAddress按用户 uid 生成充值地址签名
CreateMultipleDepositAddress批量生成充值地址签名
GetDepositAddress查询用户充值地址API Key
RequestWithdrawal发起提现签名
GetDeposits查询充值记录API Key
GetWithdrawals查询提现记录API Key
VerifyPlatformSignature验证平台签名
ParseCallbackData验签并解析回调
GenerateKeys生成商户密钥对
SignDataWithPrivateKey用指定私钥对任意数据签名

4. 生成充值地址(按用户 uid)

go
resp, err := client.CreateDepositAddress(&types.CreateDepositAddressRequest{
	UserUID:   "100286", // SDK 会自动补成 "<PROJECT_UID>-100286"
	NetworkID: 4,        // TRON 主网
})
if err != nil {
	return err
}

fmt.Println("address:", resp.Address) // TNf6U6U4JtLGBYLvPF7mWQimb8UsagJ22u
fmt.Println("uid:", resp.UID)         // Ab3xY9Kq7Z-100286

SDK 会自动检查并补上 {ProjectID}- 前缀,你传原始用户 ID 或已带前缀的值都可以。

同一个 uid 重复调用会返回 HTTP 400: uid already used。业务上应先查本地映射表, 没有再调接口,避免依赖报错做分支。


5. 批量生成充值地址

go
resp, err := client.CreateMultipleDepositAddress(&types.CreateMultipleDepositAddressRequest{
	NetworkID: 56, // BSC 主网
	Count:     10, // 1~100
})
if err != nil {
	return err
}

for _, addr := range resp.Data.Addresses {
	fmt.Println(addr.Uid, addr.Address, addr.NetworkName)
}

6. 查询用户充值地址

go
resp, err := client.GetDepositAddress(&types.GetDepositAddressRequest{
	UserUID:   "Ab3xY9Kq7Z-100286", // 这里要传完整 uid(含项目前缀)
	NetworkID: 4,
})
if err != nil {
	return err
}
fmt.Println(resp.Address)

注意与 CreateDepositAddress 的差异:创建时 SDK 会自动补前缀,查询时不会,需要传完整 uid。


7. 发起提现

go
import "github.com/google/uuid"

withdrawUID := uuid.NewString() // 全局唯一,同时是幂等键,务必落库

resp, err := client.RequestWithdrawal(types.RequestWithdrawalRequest{
	UID:       withdrawUID,
	AssetID:   2,      // USDT
	NetworkID: 56,     // BSC 主网
	Amount:    100.5,  // 可读金额
	ToAddress: "0x4b2048ede5ca5d962795fec5edf8b41a860e2d4d",
	UserUID:   "Ab3xY9Kq7Z-100286", // 仅业务记录用,不参与签名与落库
})
if err != nil {
	// 网络错误/超时:可以用【同一个 withdrawUID】安全重试
	return err
}

fmt.Println(resp.Code, resp.Status, resp.Message)

要点:

  • 先落库再调用:把 withdrawUID 与业务单号绑定后再发请求,这样超时后能安全重试。
  • Amountfloat64,SDK 内部用 strconv.FormatFloat(amount, 'f', -1, 64) 转成字符串。 大额或高精度金额建议自行确认转换结果,必要时直接用 HTTP 调用传字符串金额,规避浮点误差。
  • 返回 HTTP 500: uid already used 说明这单已经提交过,按已提交处理,不要换新 uid 重发。
  • 最终结果以提现回调为准。

8. 查询充值 / 提现记录

go
deposits, err := client.GetDeposits(&types.GetDepositsRequest{Page: 1, PageSize: 10})
withdrawals, err := client.GetWithdrawals(&types.GetWithdrawalsRequest{Page: 1, PageSize: 10})

SDK 只暴露了 Page / PageSize。若需要按交易哈希、状态、时间范围等条件过滤, 直接按 02-API-参考.md 第 7 节「查询充值 / 提现记录」发 HTTP 请求即可。

实时入账请以回调为准,本接口用于对账与历史查询。


9. 回调验签

方式一:VerifyPlatformSignature(拿到 bool 结果,自行控制流程)

go
ok, err := client.VerifyPlatformSignature(
	client.GetPlatformPublicKey(),
	callbackReq.VerifyData, // map[string]interface{} 或结构体
	callbackReq.Sig,
)

方式二:ParseCallbackData(验签 + 反序列化一步到位)

go
data, err := client.ParseCallbackData(types.CallbackRequestDataWithSig{
	Data: respData, // types.CallbackRespData
	Sig:  sig,
})
if err != nil {
	// 验签失败或数据非法
	return err
}
fmt.Println(data.Type, data.Uid, data.Status, data.Confirmed, data.FloatAmount)

完整的回调服务端示例见 03-回调通知.md 第 7 节「接收端示例(Go)」。


10. 生成密钥对

go
keys, err := client.GenerateKeys()
if err != nil {
	return err
}
fmt.Println(keys.PrivateKey) // 自己保管
fmt.Println(keys.PublicKey)  // 提交给平台登记
fmt.Println(keys.Address)

11. 错误处理

SDK 在 HTTP 状态码非 200 时返回形如下面的 error:

HTTP 403: {"code":403,"status":"error","message":"IP address not whitelisted or not approved","error":"no access"} (outbound_ip=1.2.3.4 local_addr=10.0.0.5:41234)

outbound_ip 是 SDK 自动探测的本机公网出口 IP(通过 api.ipify.org), 遇到 403 时可以直接拿这个值去核对 IP 白名单,无需登录服务器排查。

SDK 会把请求/响应摘要打到标准输出([LinkePay Debug] 前缀)。生产环境如需静默, 请在部署层做日志过滤,或改用直接 HTTP 调用。

建议的重试策略:

错误处理
网络错误 / 超时 / HTTP 5xx指数退避重试,写接口务必带相同的 uid
HTTP 429退避后重试,并检查调用频率(限流约 125 req/s per IP)
HTTP 403不要重试,检查 IP 白名单
HTTP 401 invalid signature不要重试,检查签名实现与已登记公钥
HTTP 400/500 uid already used不要重试,按已提交处理
code 1028 insufficient balance不要重试,先补充归集地址余额

12. 完整可运行示例

仓库内自带示例(linkepay-sdk-go/example/):

目录内容
example/generate-keys生成商户密钥对
example/deposit生成充值地址 + 查询充值记录
example/withdrawal发起提现
example/callback-server回调接收服务(含验签)
example/verify-callback-sign单独验证回调签名
example/verify-sign验证任意签名

示例代码里的 BaseURL / 密钥 / API Key 均为占位或历史环境值,运行前请替换为你自己的生产配置

本文档描述 LinkePay 生产环境(主网)接口。接口如有变更以本文档为准。