Go SDK
HashNut 官方 Go SDK,为 HashNut 支付 API 提供便捷的封装。
安装
bash
go get github.com/nuttybounty/hashnut-sdk-go/v4初始化客户端
go
import hashnut "github.com/nuttybounty/hashnut-sdk-go/v4"
client := hashnut.NewClient(
"your-access-key-id",
"your-secret-key",
)go
import hashnut "github.com/nuttybounty/hashnut-sdk-go/v4"
client := hashnut.NewClient(
"your-access-key-id",
"your-secret-key",
hashnut.WithTestnet(),
)go
import hashnut "github.com/nuttybounty/hashnut-sdk-go/v4"
client := hashnut.NewClient(
"your-access-key-id",
"your-secret-key",
hashnut.WithBaseURL("https://custom.endpoint.com"),
)方法
CreateOrder
创建新的支付订单。
go
import "github.com/nuttybounty/hashnut-sdk-go/v4/model"
order, err := client.CreateOrder(&model.CreateOrderRequest{
AccessKeyID: "your-access-key-id",
MerchantOrderID: "ORDER-001",
BlockChain: "ETH",
TokenSymbol: "usdt",
Amount: "25.00",
SplitterAddress: "0xYourSplitterAddress",
// Optional fields
Subject: "Monthly Subscription",
ExpireDuration: 1800,
CallbackURL: "https://yoursite.com/payment-result",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Pay Order ID: %s\n", order.PayOrderId)
fmt.Printf("Receipt Address: %s\n", order.ReceiptAddress)QueryOrder
查询订单的当前状态。
go
result, err := client.QueryOrder(&model.QueryOrderRequest{
MerchantOrderID: "ORDER-001",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("State: %d\n", result.State)
fmt.Printf("Paid Amount: %s\n", result.PaidAmount)
fmt.Printf("Tx Hash: %s\n", result.PayTxId)ConfirmPaid
使用交易哈希手动确认支付。
go
result, err := client.ConfirmPaid(&model.ConfirmPaidRequest{
PayOrderId: "PO202606210001",
MerchantOrderID: "ORDER-001",
PayTxId: "0x9876543210fedcba...",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("New State: %d\n", result.State)CancelOrder
取消未支付的订单。
go
result, err := client.CancelOrder(&model.CancelOrderRequest{
PayOrderId: "PO202606210001",
MerchantOrderID: "ORDER-001",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("State: %d\n", result.State) // -3 = CANCELEDQueryChains
查询所有支持的区块链网络。
go
chains, err := client.QueryChains()
if err != nil {
log.Fatal(err)
}
for _, chain := range chains {
fmt.Printf("%s (%s) - %s\n", chain.BlockChain, chain.ChainType, chain.NetworkType)
}QueryCoins
查询所有支持的代币,可按链进行筛选。
go
// All coins
coins, err := client.QueryCoins("")
if err != nil {
log.Fatal(err)
}
// Coins for a specific chain
coins, err := client.QueryCoins("ETH")
if err != nil {
log.Fatal(err)
}
for _, coin := range coins {
fmt.Printf("%s (%s) - %d decimals\n", coin.TokenSymbol, coin.CoinName, coin.Decimals)
}QueryFiats
查询所有支持的法币。
go
fiats, err := client.QueryFiats()
if err != nil {
log.Fatal(err)
}
for _, fiat := range fiats {
fmt.Printf("%s - %s\n", fiat.FiatCode, fiat.Description)
}错误处理
所有方法的第二个返回值为 error。SDK 将 API 错误封装为结构化的 APIError 类型:
go
order, err := client.CreateOrder(&model.CreateOrderRequest{
// ...
})
if err != nil {
var apiErr *hashnut.APIError
if errors.As(err, &apiErr) {
fmt.Printf("API Error Code: %d\n", apiErr.Code)
fmt.Printf("API Error Message: %s\n", apiErr.Msg)
} else {
// Network or other error
fmt.Printf("Error: %v\n", err)
}
return
}WARNING
API 响应中的数值字段(如 amount 和 paidAmount)以 json.Number 类型返回,以兼容后端可能返回的字符串或数值格式。使用 .String() 读取值,或使用 .Int64() / .Float64() 进行数值转换。
完整示例
go
package main
import (
"errors"
"fmt"
"log"
"time"
hashnut "github.com/nuttybounty/hashnut-sdk-go/v4"
"github.com/nuttybounty/hashnut-sdk-go/v4/model"
)
func main() {
client := hashnut.NewClient(
"your-access-key-id",
"your-secret-key",
hashnut.WithTestnet(),
)
// Create order
order, err := client.CreateOrder(&model.CreateOrderRequest{
AccessKeyID: "your-access-key-id",
MerchantOrderID: fmt.Sprintf("ORDER-%d", time.Now().Unix()),
BlockChain: "ETH",
TokenSymbol: "usdt",
Amount: "1.00",
SplitterAddress: "0xYourSplitterAddress",
Subject: "Test Order",
})
if err != nil {
var apiErr *hashnut.APIError
if errors.As(err, &apiErr) {
log.Fatalf("API error %d: %s", apiErr.Code, apiErr.Msg)
}
log.Fatal(err)
}
fmt.Printf("Order created: %s\n", order.PayOrderId)
fmt.Printf("Send %s %s to: %s\n", order.Amount, "usdt", order.ReceiptAddress)
// Poll for payment (in production, use webhooks instead)
for i := 0; i < 60; i++ {
time.Sleep(10 * time.Second)
result, err := client.QueryOrder(&model.QueryOrderRequest{
MerchantOrderID: order.MerchantOrderId,
})
if err != nil {
log.Printf("Query error: %v", err)
continue
}
fmt.Printf("State: %d\n", result.State)
if result.State == 3 { // SUCCESS
fmt.Println("Payment successful!")
return
}
}
}TIP
在生产环境中,建议使用 Webhook 通知而非轮询。此处使用轮询仅为演示方便。
