On this pageInstallationInitialize the ClientMethodsCreateOrderQueryOrderConfirmPaidCancelOrderQueryChainsQueryCoinsQueryFiatsError HandlingComplete Example

Go SDK ​

The official HashNut Go SDK provides a convenient wrapper around the HashNut Payment API.

Installation ​

bash
go get github.com/nuttybounty/hashnut-sdk-go/v4

Initialize the Client ​

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"),
)

Methods ​

CreateOrder ​

Create a new payment order.

go
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.

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 ​

Manually confirm payment with a transaction hash.

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 ​

Cancel an unpaid order.

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 ​

Query all supported blockchain networks.

go
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.

go
// 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.

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 Handling ​

All methods return an error as the second return value. The SDK wraps API errors in a structured APIError type:

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

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 ​

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()),
		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.