Go Package
github.com/billing-io/billing-go
GitHub
billing-io/billing-go
Installation
go get github.com/billing-io/billing-go
Quick Start
package main
import (
"context"
"fmt"
billingio "github.com/billing-io/billing-go"
)
func main() {
client := billingio.New("sk_live_...")
checkout, err := client.Checkouts.Create(context.Background(), billingio.CreateCheckoutParams{
AmountUSD: 49.99,
Chain: "tron",
Token: "USDT",
Metadata: map[string]string{
"order_id": "ord_12345",
},
})
if err != nil {
panic(err)
}
fmt.Println(checkout.CheckoutID)
fmt.Println(checkout.DepositAddress)
}
Create a Checkout
checkout, err := client.Checkouts.Create(ctx, billingio.CreateCheckoutParams{
AmountUSD: 100.00,
Chain: "arbitrum",
Token: "USDC",
Metadata: map[string]string{
"customer_email": "alice@example.com",
},
})
List with Auto-Pagination
The SDK provides an iterator for automatic cursor-based pagination:iter := client.Checkouts.List(ctx, billingio.ListParams{Limit: 25})
for iter.Next() {
checkout := iter.Current()
fmt.Println(checkout.CheckoutID, checkout.Status)
}
if err := iter.Err(); err != nil {
// handle error
}
page, err := client.Checkouts.ListPage(ctx, billingio.ListParams{Limit: 10})
for _, checkout := range page.Data {
fmt.Println(checkout.CheckoutID)
}
Get Checkout Status
status, err := client.Checkouts.GetStatus(ctx, "chk_abc123")
fmt.Println(status.Status) // "confirming"
fmt.Println(status.Confirmations) // 8
fmt.Println(status.RequiredConfirmations) // 19
Webhook Signature Verification
func handleWebhook(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
isValid := billingio.VerifyWebhookSignature(
string(body),
r.Header.Get("X-Billing-Signature"),
"whsec_...",
)
if !isValid {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}
// process event...
w.WriteHeader(http.StatusOK)
}
Error Handling
The SDK provides typed error helpers:checkout, err := client.Checkouts.Create(ctx, params)
if err != nil {
if billingio.IsNotFound(err) {
// 404 - resource not found
} else if billingio.IsRateLimited(err) {
// 429 - back off and retry
} else if billingio.IsAuthError(err) {
// 401 - check API key
}
return err
}
*billingio.Error:
var apiErr *billingio.Error
if errors.As(err, &apiErr) {
fmt.Println(apiErr.Status) // 422
fmt.Println(apiErr.Code) // "validation_error"
fmt.Println(apiErr.Message) // "amount_usd must be positive"
}
Customers
customer, err := client.Customers.Create(ctx, billingio.CreateCustomerParams{
Email: "alice@example.com",
Name: "Alice Johnson",
Metadata: map[string]string{"plan": "pro"},
})
customer, err := client.Customers.Get(ctx, "cus_abc123")
updated, err := client.Customers.Update(ctx, "cus_abc123", billingio.UpdateCustomerParams{
Name: "Alice Smith",
})
iter := client.Customers.List(ctx, billingio.ListParams{Limit: 25})
for iter.Next() {
fmt.Println(iter.Current().Email)
}
Payment Methods
pm, err := client.PaymentMethods.Create(ctx, billingio.CreatePaymentMethodParams{
Chain: "tron",
Token: "USDT",
DisplayName: "Primary USDT",
})
err = client.PaymentMethods.SetDefault(ctx, "pm_abc123")
iter := client.PaymentMethods.List(ctx, billingio.ListParams{Limit: 10})
for iter.Next() {
pm := iter.Current()
fmt.Println(pm.DisplayName, pm.Chain, pm.Token)
}
Payment Links
link, err := client.PaymentLinks.Create(ctx, billingio.CreatePaymentLinkParams{
AmountUSD: 99.99,
Chain: "arbitrum",
Token: "USDC",
Description: "Annual subscription",
})
fmt.Println(link.URL)
Subscriptions
plan, err := client.SubscriptionPlans.Create(ctx, billingio.CreateSubscriptionPlanParams{
Name: "Pro Monthly",
AmountUSD: 29.99,
Interval: "monthly",
Token: "USDT",
Chain: "tron",
})
sub, err := client.Subscriptions.Create(ctx, billingio.CreateSubscriptionParams{
CustomerID: "cus_abc123",
PlanID: plan.ID,
PaymentMethodID: "pm_abc123",
})
// Cancel
_, err = client.Subscriptions.Update(ctx, "sub_abc123", billingio.UpdateSubscriptionParams{
Status: "canceled",
})
// List renewals
iter := client.SubscriptionRenewals.List(ctx, billingio.ListSubscriptionRenewalsParams{
SubscriptionID: "sub_abc123",
})
for iter.Next() {
r := iter.Current()
fmt.Println(r.Status, r.AmountUSD)
}
Entitlements
ent, err := client.Entitlements.Create(ctx, billingio.CreateEntitlementParams{
PlanID: "plan_abc123",
FeatureKey: "api_calls",
ValueType: "numeric",
ValueNumeric: 10000,
})
check, err := client.Entitlements.Check(ctx, billingio.CheckEntitlementParams{
CustomerID: "cus_abc123",
FeatureKey: "api_calls",
})
fmt.Println(check.HasAccess, check.Value)
Payouts
payout, err := client.PayoutIntents.Create(ctx, billingio.CreatePayoutIntentParams{
RecipientAddress: "TXyz...",
Chain: "tron",
Token: "USDT",
Amount: 500.00,
Currency: "USD",
})
// Submit tx hash after executing externally
err = client.PayoutIntents.Execute(ctx, "po_abc123", billingio.ExecutePayoutParams{
TxHash: "0xabc...",
})
// List settlements
iter := client.Settlements.List(ctx, billingio.ListParams{Limit: 25})
for iter.Next() {
s := iter.Current()
fmt.Println(s.TxHash, s.ConfirmedAt)
}
Revenue
iter := client.RevenueEvents.List(ctx, billingio.ListParams{Limit: 25})
for iter.Next() {
e := iter.Current()
fmt.Println(e.EventType, e.Amount, e.Currency)
}
adj, err := client.Adjustments.Create(ctx, billingio.CreateAdjustmentParams{
Type: "credit",
AmountUSD: 10.00,
Description: "Loyalty discount",
CustomerID: "cus_abc123",
})
Context Support
All methods accept acontext.Context for cancellation and timeouts:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
checkout, err := client.Checkouts.Create(ctx, params)