Skip to content

About

A Golang Wrapper for Azam Payment Gateway

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

go-azampay

Go SDK for AzamPay Tanzania APIs.

Installation

go get github.com/kateile/go-azampay/v2@latest
import "github.com/kateile/go-azampay/v2"

Client Setup

api := azampay.NewAzamPay(false, azampay.Credentials{
	AppName:      os.Getenv("AZAM_APP_NAME"),
	ClientId:     os.Getenv("AZAM_CLIENT_ID"),
	ClientSecret: os.Getenv("AZAM_CLIENT_SECRET"),
	Token:        os.Getenv("AZAM_API_KEY"),
})

if err := api.GenerateSession(); err != nil {
	log.Fatal(err)
}

Pass true to NewAzamPay for production.

Debug Logging

Enable debug logging to log sanitized AzamPay requests and responses with log/slog:

logger := slog.New(slog.NewTextHandler(os.Stdout, nil))

api.Debug = true
api.SetLogger(logger)

Request and response JSON is redacted before logging for sensitive keys such as clientSecret, accessToken, Authorization, X-API-KEY, password, and token-like fields.

Mobile Checkout

resp, err := api.MobileCheckout(azampay.MNOPayload{
	AccountNumber: "255700000000",
	Amount:        2000,
	Currency:      "TZS",
	ExternalID:    "order-123",
	Provider:      azampay.ProviderAirtel,
})
if err != nil {
	log.Fatal(err)
}

fmt.Println(resp.TransactionID)

Bank Checkout

resp, err := api.BankCheckout(azampay.BankCheckoutPayload{
	Amount:                10000,
	CurrencyCode:          "TZS",
	MerchantAccountNumber: "1234567890",
	MerchantMobileNumber:  "255700000000",
	OTP:                   "123456",
	Provider:              azampay.BankProviderCRDB,
	ReferenceID:           "order-123",
})

Checkout Page

checkoutURL, err := api.PostCheckout(azampay.PostCheckoutPayload{
	Amount:             "10000",
	AppName:            "my-app",
	ClientID:           "client-id",
	Currency:           "TZS",
	ExternalID:         "order-123",
	Language:           "en",
	RedirectFailURL:    "https://example.com/fail",
	RedirectSuccessURL: "https://example.com/success",
	RequestOrigin:      "https://example.com",
	VendorID:           "vendor-id",
	VendorName:         "Vendor",
	Cart: azampay.Cart{Items: []azampay.Item{
		{Name: "Product"},
	}},
})

Disbursement

AzamPay disbursement requests require a checksum:

checksum, err := azampay.GenerateChecksum("input-string-from-your-integration", publicKeyPEM)
if err != nil {
	log.Fatal(err)
}

resp, err := api.Disburse(azampay.CreateTransferPayload{
	Source: azampay.Source{
		CountryCode:   "TZ",
		FullName:      "Sender",
		BankName:      azampay.DisburseProviderAirtel,
		AccountNumber: "255700000001",
		Currency:      "TZS",
	},
	Destination: azampay.Destination{
		CountryCode:   "TZ",
		FullName:      "Receiver",
		BankName:      azampay.DisburseProviderTigo,
		AccountNumber: "255700000002",
		Currency:      "TZS",
	},
	TransferDetails: azampay.TransferDetails{
		Type:        "internal",
		Amount:      5000,
		DateInEpoch: float64(time.Now().Unix()),
	},
	ExternalReferenceID: "ref-123",
	Checksum:            checksum,
})

Disbursement errors can be inspected with errors.As:

var disbursementErr *azampay.DisbursementError
if errors.As(err, &disbursementErr) {
	fmt.Println(disbursementErr.Message)
}

Name Lookup And Transaction Status

lookup, err := api.NameLookup(azampay.NameLookupPayload{
	BankName:      "airtel",
	AccountNumber: "255700000000",
	Checksum:      checksum,
})

status, err := api.GetTransactionStatus(azampay.TransactionStatusPayload{
	BankName:      azampay.DisburseProviderAirtel,
	PGReferenceID: "pg-reference-id",
})

Webhook Callback

updates := api.ListenForWebhook("/api/v1/Checkout/Callback")

for update := range updates {
	if err := azampay.VerifyCallbackSignature(update, publicKeyPEM, crypto.SHA256); err != nil {
		log.Println("invalid callback signature:", err)
		continue
	}

	fmt.Println(update.TransactionStatus, update.ExternalReference)
}

Bill Pay Helpers

payload := azampay.BillPayStatusCheckPayload{
	MerchantReferenceID: "merchant-ref-123",
}

hash, err := azampay.CalculateBillPayHash(payload, []byte("shared-secret"))
ok, err := azampay.VerifyBillPayHash(payload, hash, []byte("shared-secret"))

claims, err := azampay.ValidateBillPayJWT(jwtToken, []byte("shared-secret"), time.Now())

ValidateBillPayJWT verifies HS256 signatures, requires userId, iat, and exp, and enforces the documented 120-second maximum token validity.

About

A Golang Wrapper for Azam Payment Gateway

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages