本文目录安装初始化客户端方法CreateOrderQueryOrderConfirmPaidCancelOrderQueryChainsQueryCoinsQueryFiats错误处理完整示例

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 = CANCELED

QueryChains ​

查询所有支持的区块链网络。

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 通知而非轮询。此处使用轮询仅为演示方便。