Go
The official Go SDK — idiomatic, with contexts and typed errors.
18 min read
The github.com/wajub/wajub-go module follows Go
conventions: functional options, context.Context, and typed errors.
Installation
go get github.com/wajub/wajub-goInitialization
package main
import (
"os"
wajub "github.com/wajub/wajub-go"
)
func main() {
client := wajub.New(
os.Getenv("WAJUB_PUBLIC_KEY"),
wajub.WithGrant(os.Getenv("WAJUB_SECRET_KEY")),
wajub.WithMaxRetries(3),
)
_ = client
}Use cases
Collect a payment
res, err := client.Payments.Initialize(&wajub.PaymentParams{
Amount: 5000,
Currency: "XAF",
Customer: wajub.Customer{Email: "amina@example.com"},
Callback: "https://example.com/return",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(res.AuthorizationURL)Pay out
transfer, err := client.Transfers.Create(&wajub.TransferParams{
Amount: 100000,
Currency: "XAF",
Recipient: "+237670000000",
Channel: "cm.mtn",
}, wajub.WithIdempotencyKey(uuid.NewString()))Verify a webhook (net/http)
func webhook(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
event, err := wajub.ConstructEvent(
body,
r.Header.Get("X-Wajub-Signature"),
os.Getenv("WAJUB_WEBHOOK_SECRET"),
)
if err != nil {
http.Error(w, "bad signature", http.StatusBadRequest)
return
}
if event.Type == "payment.succeeded" {
fulfill(event.Data)
}
w.WriteHeader(http.StatusOK)
}Source code: github.com/wajub/wajub-go.
Available Methods
client.Payments.Initialize(*PaymentParams)(*Payment, error)optionalCreate a new payment and return an authorization URL.
client.Payments.Retrieve(reference)(*Payment, error)optionalRetrieve a payment by transaction reference.
client.Payments.List(*ListParams)([]Payment, error)optionalList payments with optional filters (limit, cursor, status).
client.Payments.Refund(reference, *RefundParams)(*Refund, error)optionalRefund a completed payment.
client.Transfers.Create(*TransferParams, ...Option)(*Transfer, error)optionalInitiate a mobile money payout or bank transfer.
client.Transfers.List(*ListParams)([]Transfer, error)optionalList transfers with optional filters.
client.Transfers.Retrieve(reference)(*Transfer, error)optionalRetrieve a single transfer by reference.
client.Customers.Create(*CustomerParams)(*Customer, error)optionalCreate a customer record.
client.Customers.List(*ListParams)([]Customer, error)optionalList customers with optional filters.
client.Customers.Retrieve(id)(*Customer, error)optionalRetrieve a customer by ID or email.
client.Customers.Update(id, *CustomerParams)(*Customer, error)optionalUpdate a customer's metadata or details.
client.Customers.Delete(id)erroroptionalDelete a customer record.
client.Balance.Retrieve()(*Balance, error)optionalFetch your current account balance across currencies.
wajub.ConstructEvent(body, sig, secret)(*Event, error)optionalVerify and parse an incoming webhook payload.
Configuration
Use functional options to customise the client.
package main
import (
"net/http"
"os"
"time"
wajub "github.com/wajub/wajub-go"
)
func main() {
client := wajub.New(
os.Getenv("WAJUB_PUBLIC_KEY"),
wajub.WithGrant(os.Getenv("WAJUB_SECRET_KEY")),
wajub.WithTimeout(30 * time.Second), // default: 30s
wajub.WithMaxRetries(3), // default: 3
wajub.WithBaseURL(os.Getenv("WAJUB_BASE_URL")), // override for proxies / staging
wajub.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}), // custom transport
wajub.WithHeaders(map[string]string{ // additional custom headers
"X-Custom-Header": "value",
}),
)
_ = client
}Error Handling
Errors returned by the client implement the wajub.Error interface with status code and underlying cause. Use errors.As to switch on error types.
import (
"errors"
"log"
"time"
wajub "github.com/wajub/wajub-go"
)
payment, err := client.Payments.Initialize(&wajub.PaymentParams{
Amount: 5000,
Currency: "XAF",
Customer: wajub.Customer{Email: "amina@example.com"},
Callback: "https://example.com/return",
})
if err != nil {
var aerr *wajub.AuthenticationError
var verr *wajub.ValidationError
var rerr *wajub.RateLimitError
var apierr *wajub.ApiError
var nerr *wajub.NetworkError
switch {
case errors.As(err, &aerr):
// 401 — invalid or missing API key
log.Printf("check WAJUB_PUBLIC_KEY: %v", aerr)
case errors.As(err, &verr):
// 422 — invalid parameters, per-field errors available
log.Printf("validation failed: %v", verr.Errors)
case errors.As(err, &rerr):
// 429 — wait and retry
time.Sleep(rerr.RetryAfter)
case errors.As(err, &apierr):
// 4xx / 5xx server errors
log.Printf("API error %d: %v", apierr.Code, apierr)
case errors.As(err, &nerr):
// Connection refused, DNS failure, timeout
log.Printf("network unreachable: %v", nerr)
default:
// Unknown error — log and return
log.Fatalf("unexpected error: %v", err)
}
}