To build Paystack subscriptions in Go, create a plan via the API, initialize a transaction with the plan code, handle subscription webhooks in your webhook handler, track status in your database, and provide an endpoint for cancellation.
func subscribeHandler(w http.ResponseWriter, r *http.Request) {
var input struct {
Email string "json:\"email\""
PlanCode string "json:\"plan_code\""
}
json.NewDecoder(r.Body).Decode(&input)
body, _ := json.Marshal(map[string]string{
"email": input.Email,
"plan": input.PlanCode,
"callback_url": "http://localhost:8080/subscription/callback",
})
req, _ := http.NewRequest("POST", "https://api.paystack.co/transaction/initialize",
bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+paystackSecret)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
http.Error(w, "Failed", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
var result PaystackResponse
json.NewDecoder(resp.Body).Decode(&result)
if result.Status {
json.NewEncoder(w).Encode(map[string]string{
"authorization_url": result.Data.AuthorizationURL,
})
return
}
http.Error(w, result.Message, http.StatusBadRequest)
}
// In processEvent:
case "subscription.create":
var sub struct {
SubscriptionCode string "json:\"subscription_code\""
EmailToken string "json:\"email_token\""
Customer struct {
Email string "json:\"email\""
} "json:\"customer\""
Plan struct {
PlanCode string "json:\"plan_code\""
} "json:\"plan\""
}
json.Unmarshal(data, &sub)
// Save to database
case "invoice.payment_failed":
var inv struct {
Subscription struct {
SubscriptionCode string "json:\"subscription_code\""
} "json:\"subscription\""
}
json.Unmarshal(data, &inv)
// Update status to past_due
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
func cancelHandler(w http.ResponseWriter, r *http.Request) {
// Get subscription from database for current user
subCode := "SUB_xxx" // from database
emailToken := "token_xxx" // from database
body, _ := json.Marshal(map[string]string{
"code": subCode,
"token": emailToken,
})
req, _ := http.NewRequest("POST", "https://api.paystack.co/subscription/disable",
bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+paystackSecret)
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
// Update database status to cancelled
w.Write([]byte("Subscription cancelled"))
}
func requireSubscription(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Check user subscription status from database
// If not active, return 403
// Otherwise, call next(w, r)
next(w, r)
}
}
// Usage:
http.HandleFunc("/premium", requireSubscription(premiumHandler))
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course