On this page
InstallationInitialize the ClientMethodsCreateOrderQueryOrderConfirmPaidCancelOrderQueryChainsQueryCoinsQueryFiatsError HandlingComplete ExampleGo SDK
The official HashNut Go SDK provides a convenient wrapper around the HashNut Payment API.
Installation
go get github.com/nuttybounty/hashnut-sdk-go/v4Initialize the Client
import hashnut "github.com/nuttybounty/hashnut-sdk-go/v4"
client := hashnut.NewClient(
"your-access-key-id",
"your-secret-key",
)import hashnut "github.com/nuttybounty/hashnut-sdk-go/v4"
client := hashnut.NewClient(
"your-access-key-id",
"your-secret-key",
hashnut.WithTestnet(),
)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"),
)Methods
CreateOrder
Create a new payment order.
import "github.com/nuttybounty/hashnut-sdk-go/v4/model"
order, err := client.CreateOrder(&model.CreateOrderRequest{
AccessKeyID: "your-access-key-id",
MerchantOrderID: "ORDER-001",
ChainCode: "erc20",
CoinCode: "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
Query the current state of an order.
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
Manually confirm payment with a transaction hash.
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
Cancel an unpaid order.
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
Query all supported blockchain networks.
chains, err := client.QueryChains()
if err != nil {
log.Fatal(err)
}
for _, chain := range chains {
fmt.Printf("%s (%s) - %s\n", chain.ChainCode, chain.ChainType, chain.NetworkType)
}QueryCoins
Query all supported tokens, optionally filtered by chain.
// All coins
coins, err := client.QueryCoins("")
if err != nil {
log.Fatal(err)
}
// Coins for a specific chain
coins, err := client.QueryCoins("erc20")
if err != nil {
log.Fatal(err)
}
for _, coin := range coins {
fmt.Printf("%s (%s) - %d decimals\n", coin.CoinCode, coin.CoinName, coin.Decimals)
}QueryFiats
Query all supported fiat currencies.
fiats, err := client.QueryFiats()
if err != nil {
log.Fatal(err)
}
for _, fiat := range fiats {
fmt.Printf("%s - %s\n", fiat.FiatCode, fiat.Description)
}Error Handling
All methods return an error as the second return value. The SDK wraps API errors in a structured APIError type:
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
Numeric fields in API responses (such as amount and paidAmount) are returned as json.Number to handle both string and number representations from the backend. Use .String() to read the value or .Int64() / .Float64() for numeric conversion.
Complete Example
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()),
ChainCode: "erc20",
CoinCode: "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
In production, prefer webhook notifications over polling. Polling is shown here for simplicity.
