To verify a Paystack payment in Go, make a GET request to the verify endpoint, decode the JSON response into a typed struct, check status, amount, and currency, and use an atomic database update to prevent double-granting.
func verifyTransaction(reference string) (*VerifyResponse, error) {
req, err := http.NewRequest("GET",
"https://api.paystack.co/transaction/verify/"+reference, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+paystackSecret)
client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result VerifyResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, err
}
return &result, nil
}
func verifyAndFulfill(reference string, db *sql.DB) error {
result, err := verifyTransaction(reference)
if err != nil {
return fmt.Errorf("verification failed: %w", err)
}
if !result.Status || result.Data.Status != "success" {
return fmt.Errorf("payment not successful: %s", result.Data.Status)
}
// TODO: Check amount and currency against database
// Atomic update
res, err := db.Exec(
"UPDATE orders SET paid = true, paid_at = NOW() WHERE reference = $1 AND paid = false",
reference,
)
if err != nil {
return err
}
rows, _ := res.RowsAffected()
if rows == 0 {
// Already fulfilled
return nil
}
// Deliver value
return nil
}
func verifyWithRetry(reference string, maxRetries int) (*VerifyResponse, error) {
for attempt := 0; attempt < maxRetries; attempt++ {
result, err := verifyTransaction(reference)
if err == nil {
return result, nil
}
if attempt < maxRetries-1 {
time.Sleep(time.Duration(1<
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
func verifyHandler(w http.ResponseWriter, r *http.Request) {
reference := r.URL.Query().Get("reference")
if reference == "" {
http.Error(w, "Missing reference", http.StatusBadRequest)
return
}
err := verifyAndFulfill(reference, db)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]bool{"success": true})
}
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