Help us shape the future of Go! Take the 2026 Go Developer Survey

kkhay

package module
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2026 License: MIT Imports: 15 Imported by: 0

README

kkhay-go

Official Go SDK for K Khay — The Non-Custodial Crypto Payment Gateway

Go Reference CI Go Report Card

Accept cryptocurrency payments across 190+ blockchain networks and 500+ tokens (EVM, Bitcoin, Solana, TON, Tron, and XRPL) with zero custody and automatic direct-to-wallet settlement. Built with zero external dependencies using the Go standard library.

Gateway Dashboard • API Keys • Website


⚡ Key Highlights

  • 🛡️ 100% Non-Custodial: Payments settle directly to your destination blockchain address in seconds. K Khay never holds your private keys or customer funds.
  • 🌐 190+ Networks Supported:
    • EVM Networks: Ethereum, BNB Smart Chain, Polygon, Arbitrum, Base, Optimism, Avalanche, and 180+ more.
    • UTXO Networks: Bitcoin (btc), Dogecoin (doge), Litecoin (ltc), Bitcoin Cash (bch).
    • High-Throughput Chains: Solana (sol), TON (ton), Tron (trx), XRP Ledger (xrp).
  • 🪙 500+ Cryptocurrencies: Native coins and tokens (USDT, USDC, BTC, ETH, SOL, TON, BNB, DOGE, XRP, TRX, LTC, and more).
  • 🔗 Branded Hosted Checkouts: Automatic payment links with dynamic QR codes, live blockchain polling, and wallet deep linking.
  • 🔔 Cryptographic Webhooks: HMAC-SHA256 signed Instant Payment Notifications (x-kkhay-signature).
  • 🪶 Zero Dependencies: Pure Go standard library implementation (net/http, crypto/hmac, crypto/sha256, encoding/json).

📦 Installation

go get github.com/boboaungdev/kkhay-go@v1.0.4

(Requires Go 1.20 or newer)


🚀 Quickstart

1. Initialize the Client

Generate your API key in the K Khay Gateway Dashboard.

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/boboaungdev/kkhay-go"
)

func main() {
    client, err := kkhay.NewClient(os.Getenv("KKHAY_API_KEY")) // starts with "kkhay_live_"
    if err != nil {
        log.Fatalf("Failed to initialize client: %v", err)
    }

    ctx := context.Background()

    // 2. Create a crypto payment invoice
    resp, err := client.CreateInvoice(ctx, kkhay.CreateInvoiceRequest{
        Amount:        49.99,
        Currency:      "USD",
        PayNetwork:    "bsc",       // "bsc", "polygon", "base", "arbitrum", "ethereum", "solana", "bitcoin", "ton"
        PayToken:      "USDT",      // "USDT", "USDC", "BTC", "ETH", "SOL", "TON"
        OrderID:       "ORDER-9842",
        Title:         "Annual Pro Plan",
        CustomerName:  "Alice Smith",
        CustomerEmail: "alice@example.com",
        RedirectURL:   "https://myshop.com/orders/success",
        CancelURL:     "https://myshop.com/cart",
    })
    if err != nil {
        log.Fatalf("Failed to create invoice: %v", err)
    }

    fmt.Printf("Invoice ID: %s\n", resp.Invoice.ID)
    fmt.Printf("Gateway ID: %s\n", resp.Invoice.GatewayID)
    fmt.Printf("Deposit Address: %s\n", resp.Invoice.DepositAddress)
    fmt.Printf("Hosted Checkout URL: %s\n", resp.Invoice.HostedURL)
}

3. Query Invoice & Transaction Confirmations
inv, err := client.GetInvoice(ctx, "inv_0192a3b4c5d6")
if err != nil {
    log.Fatalf("Failed to get invoice: %v", err)
}

fmt.Printf("Status: %s\n", inv.Invoice.Status) // "WAITING" | "PAID" | "EXPIRED" | "CANCELED"

for _, p := range inv.Payments {
    fmt.Printf("Payment received: %s (Confirmations: %d, Status: %s)\n",
        p.AmountReceived, p.Confirmations, p.Status)
    fmt.Printf("Blockchain Tx: %s\n", p.TxHash)
}

4. List & Filter Invoices
res, err := client.ListInvoices(ctx, kkhay.ListInvoicesQuery{
    Page:   1,
    Limit:  20,
    Status: kkhay.StatusPaid,
})
if err != nil {
    log.Fatalf("Failed to list invoices: %v", err)
}

fmt.Printf("Total paid invoices: %d\n", res.TotalCount)
for _, item := range res.Items {
    fmt.Printf("- %s: %f %s (%s)\n", item.ID, item.Amount, item.Currency, item.Status)
}

5. Verify Incoming Webhooks (IPN)

When a customer pays and the blockchain confirms the transaction, K Khay sends a cryptographically signed POST webhook to your server with the x-kkhay-signature header.

package main

import (
    "io"
    "log"
    "net/http"
    "os"

    "github.com/boboaungdev/kkhay-go"
)

func webhookHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }

    body, err := io.ReadAll(r.Body)
    if err != nil {
        http.Error(w, "Cannot read body", http.StatusBadRequest)
        return
    }
    defer r.Body.Close()

    signature := r.Header.Get("x-kkhay-signature")
    secret := os.Getenv("KKHAY_IPN_SECRET")

    event, err := kkhay.ParseWebhookEvent(body, signature, secret)
    if err != nil {
        http.Error(w, "Invalid signature", http.StatusUnauthorized)
        return
    }

    if event.Event == kkhay.EventPaymentPaid || event.Event == kkhay.EventPaymentFinished {
        log.Printf("Payment confirmed for invoice %s (Gateway: %s)!", event.InvoiceID, event.GatewayID)
        log.Printf("Received: %s %s on %s", event.PayAmount, event.PayToken, event.PayNetwork)
        if event.TxHash != nil {
            log.Printf("Transaction Hash: %s", *event.TxHash)
        }
        // Fulfill your customer's order in your database
    }

    w.WriteHeader(http.StatusOK)
    w.Write([]byte(`{"ok": true}`))
}

func main() {
    http.HandleFunc("/webhooks/kkhay", webhookHandler)
    log.Println("Server listening on :8080...")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

🌐 Supported Networks & Families

Network Family Popular Chains Supported Tokens
EVM (180+ Chains) Ethereum, BNB Smart Chain, Polygon, Arbitrum, Base, Optimism, Avalanche USDT, USDC, ETH, BNB, POL, AVAX, DAI, and all ERC-20s
UTXO Bitcoin, Dogecoin, Litecoin, Bitcoin Cash BTC, DOGE, LTC, BCH
Solana Solana Mainnet SOL, USDT, USDC
TON The Open Network TON, USDT
Tron (TVM) Tron Mainnet TRX, USDT
XRPL XRP Ledger XRP

🛡️ Error Handling

The SDK returns structured *kkhay.APIError instances with HTTP status codes and error messages:

inv, err := client.GetInvoice(ctx, "inv_nonexistent")
if err != nil {
    if apiErr, ok := err.(*kkhay.APIError); ok {
        fmt.Printf("API Error HTTP %d [%s]: %s\n", apiErr.Status, apiErr.Code, apiErr.Message)
    } else {
        fmt.Printf("Unexpected error: %v\n", err)
    }
}

📄 License

MIT © K Khay

Documentation

Index

Constants

View Source
const (
	StatusWaiting  = "WAITING"
	StatusPaid     = "PAID"
	StatusExpired  = "EXPIRED"
	StatusCanceled = "CANCELED"
)

Invoice status constants matching PostgreSQL GatewayInvoiceStatus enum.

View Source
const (
	TypePayment      = "PAYMENT"
	TypeDonation     = "DONATION"
	TypeSubscription = "SUBSCRIPTION"
)

Invoice type constants matching PostgreSQL GatewayInvoiceType enum.

View Source
const (
	SettlementModeNonCustodial = "NON_CUSTODIAL"
	SettlementModeCustodial    = "CUSTODIAL"
)

Settlement mode constants matching PostgreSQL GatewaySettlementMode enum.

View Source
const (
	PaymentMethodDeposit = "DEPOSIT"
	PaymentMethodWallet  = "WALLET"
)

Payment method constants matching PostgreSQL GatewayPaymentMethod enum.

View Source
const (
	PaymentStatusSettling = "SETTLING"
	PaymentStatusSettled  = "SETTLED"
	PaymentStatusFailed   = "FAILED"
)

Payment status constants matching PostgreSQL GatewayPaymentStatus enum.

View Source
const (
	EventPaymentPaid       = "payment.paid"
	EventPaymentFinished   = "payment.finished"
	EventPaymentConfirming = "payment.confirming"
	EventPaymentFailed     = "payment.failed"
	EventInvoiceCanceled   = "invoice.canceled"
)

Webhook event constants sent via Instant Payment Notifications (IPN).

View Source
const DefaultBaseURL = "https://api.kkhay.com"

DefaultBaseURL is the production API endpoint.

View Source
const Version = "1.0.4"

Version of the K Khay Go SDK.

Variables

View Source
var (
	// ErrInvalidSignature is returned when the webhook HMAC signature does not match.
	ErrInvalidSignature = errors.New("kkhay: invalid webhook signature")
)

Functions

func VerifyWebhookSignature

func VerifyWebhookSignature(payload []byte, signature string, ipnSecret string) bool

VerifyWebhookSignature verifies the HMAC-SHA256 signature sent with incoming IPN webhooks.

Types

type APIError

type APIError struct {
	Status  int         `json:"status"`
	Message string      `json:"message"`
	Code    string      `json:"code,omitempty"`
	Details interface{} `json:"details,omitempty"`
}

APIError represents an error response returned by the K Khay API.

func (*APIError) Error

func (e *APIError) Error() string

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the official Go HTTP client for K Khay Payment Gateway.

func NewClient

func NewClient(apiKey string, opts ...ClientOption) (*Client, error)

NewClient constructs a new K Khay API client.

func (*Client) CheckHealth

func (c *Client) CheckHealth(ctx context.Context) (map[string]interface{}, error)

CheckHealth queries API health status.

func (*Client) CreateInvoice

func (c *Client) CreateInvoice(ctx context.Context, req CreateInvoiceRequest) (*CreateInvoiceResponse, error)

CreateInvoice creates a new sovereign crypto payment invoice.

func (*Client) GetInvoice

func (c *Client) GetInvoice(ctx context.Context, invoiceID string) (*GetInvoiceResponse, error)

GetInvoice retrieves an existing invoice by UUID.

func (*Client) ListInvoices

func (c *Client) ListInvoices(ctx context.Context, query ListInvoicesQuery) (*ListInvoicesResponse, error)

ListInvoices queries and paginates gateway invoices.

type ClientOption

type ClientOption func(*Client)

ClientOption configures a Client instance.

func WithBaseURL

func WithBaseURL(url string) ClientOption

WithBaseURL sets a custom base URL.

func WithHTTPClient

func WithHTTPClient(client *http.Client) ClientOption

WithHTTPClient sets a custom http.Client.

func WithTimeout

func WithTimeout(timeout time.Duration) ClientOption

WithTimeout sets a custom request timeout.

type CreateInvoiceRequest

type CreateInvoiceRequest struct {
	Amount          float64                `json:"amount,omitempty"`
	Currency        string                 `json:"currency,omitempty"`
	PriceAmount     float64                `json:"priceAmount,omitempty"`
	PriceCurrency   string                 `json:"priceCurrency,omitempty"`
	PayNetwork      string                 `json:"payNetwork"`
	PayToken        string                 `json:"payToken"`
	SettlementAsset string                 `json:"settlementAsset,omitempty"`
	Type            string                 `json:"type,omitempty"`
	OrderID         string                 `json:"orderId,omitempty"`
	Title           string                 `json:"title,omitempty"`
	CustomerName    string                 `json:"customerName,omitempty"`
	CustomerEmail   string                 `json:"customerEmail,omitempty"`
	RedirectURL     string                 `json:"redirectUrl,omitempty"`
	CancelURL       string                 `json:"cancelUrl,omitempty"`
	IPNCallbackURL  string                 `json:"ipnCallbackUrl,omitempty"`
	Metadata        map[string]interface{} `json:"metadata,omitempty"`
}

CreateInvoiceRequest parameters for generating a new crypto payment invoice.

type CreateInvoiceResponse

type CreateInvoiceResponse struct {
	OK      bool    `json:"ok"`
	Invoice Invoice `json:"invoice"`
}

CreateInvoiceResponse contains the created invoice and hosted checkout URL.

type GetInvoiceResponse

type GetInvoiceResponse struct {
	OK       bool            `json:"ok"`
	Invoice  Invoice         `json:"invoice"`
	Payments []PaymentRecord `json:"payments"`
}

GetInvoiceResponse contains the requested invoice and transaction records.

type Invoice

type Invoice struct {
	ID              string                 `json:"id"`
	GatewayID       string                 `json:"gatewayId"`
	Type            string                 `json:"type"`
	OrderID         *string                `json:"orderId"`
	Title           *string                `json:"title"`
	Amount          float64                `json:"amount"`
	Currency        string                 `json:"currency"`
	PriceAmount     float64                `json:"priceAmount"`
	PriceCurrency   string                 `json:"priceCurrency"`
	SettlementAsset *string                `json:"settlementAsset"`
	PayAmount       *string                `json:"payAmount"`
	PayToken        *string                `json:"payToken"`
	PayNetwork      *string                `json:"payNetwork"`
	LockedRate      *string                `json:"lockedRate"`
	DepositAddress  string                 `json:"depositAddress"`
	DerivationIndex *int                   `json:"derivationIndex,omitempty"`
	PayoutAddress   string                 `json:"payoutAddress"`
	Status          string                 `json:"status"`
	FeeAmount       string                 `json:"feeAmount"`
	NetAmount       string                 `json:"netAmount"`
	CustomerName    *string                `json:"customerName"`
	CustomerEmail   *string                `json:"customerEmail"`
	RedirectURL     *string                `json:"redirectUrl"`
	CancelURL       *string                `json:"cancelUrl"`
	IPNCallbackURL  *string                `json:"ipnCallbackUrl"`
	PaymentMethod   *string                `json:"paymentMethod"`
	SettlementMode  *string                `json:"settlementMode"`
	HostedURL       string                 `json:"hostedUrl"`
	Metadata        map[string]interface{} `json:"metadata"`
	ExpiresAt       string                 `json:"expiresAt"`
	CreatedAt       string                 `json:"createdAt"`
	UpdatedAt       string                 `json:"updatedAt"`
}

Invoice represents a K Khay sovereign payment invoice record.

type ListInvoicesQuery

type ListInvoicesQuery struct {
	Page   int    `json:"page,omitempty"`
	Limit  int    `json:"limit,omitempty"`
	Status string `json:"status,omitempty"`
	Type   string `json:"type,omitempty"`
	Search string `json:"search,omitempty"`
}

ListInvoicesQuery parameters for pagination and filtering.

type ListInvoicesResponse

type ListInvoicesResponse struct {
	OK          bool      `json:"ok"`
	Items       []Invoice `json:"items"`
	TotalCount  int       `json:"totalCount"`
	TotalPages  int       `json:"totalPages"`
	CurrentPage int       `json:"currentPage"`
	Limit       int       `json:"limit"`
}

ListInvoicesResponse paginated list of gateway invoices.

type PaymentRecord

type PaymentRecord struct {
	ID              string  `json:"id"`
	InvoiceID       string  `json:"invoiceId"`
	TxHash          string  `json:"txHash"`
	FromAddress     *string `json:"fromAddress"`
	AmountReceived  string  `json:"amountReceived"`
	Confirmations   int     `json:"confirmations"`
	Status          string  `json:"status"`
	ForwardedTxHash *string `json:"forwardedTxHash"`
	ForwardedAt     *string `json:"forwardedAt"`
	Token           *string `json:"token,omitempty"`
	Network         *string `json:"network,omitempty"`
	OrderID         *string `json:"orderId,omitempty"`
	Title           *string `json:"title,omitempty"`
	CreatedAt       string  `json:"createdAt"`
}

PaymentRecord details on-chain transaction hashes, confirmations, and settlement status.

type WebhookEvent

type WebhookEvent struct {
	Event          string  `json:"event"`
	InvoiceID      string  `json:"invoice_id"`
	GatewayID      string  `json:"gateway_id,omitempty"`
	InvoiceType    string  `json:"invoice_type,omitempty"`
	OrderID        *string `json:"order_id"`
	Amount         float64 `json:"amount,omitempty"`
	Currency       string  `json:"currency,omitempty"`
	PriceAmount    float64 `json:"price_amount"`
	PriceCurrency  string  `json:"price_currency"`
	PayAmount      string  `json:"pay_amount"`
	PayToken       string  `json:"pay_token"`
	PayNetwork     string  `json:"pay_network"`
	DepositAddress string  `json:"deposit_address"`
	TxHash         *string `json:"tx_hash"`
	Status         string  `json:"status"`
	Timestamp      string  `json:"timestamp"`
}

WebhookEvent payload sent via IPN.

func ParseWebhookEvent

func ParseWebhookEvent(rawBody []byte, signature string, ipnSecret string) (*WebhookEvent, error)

ParseWebhookEvent validates signature and parses the raw JSON body into WebhookEvent.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL