Troubleshooting & FAQ
"Signature does not match" (401)
- Wrong secret. Student lookup, invoice lookup and webhooks each have their own secret. Regenerating invalidates the old one.
- Body modified before verification. Pass the raw body. Check middleware that parses and re-serialises JSON, and don't use
json_encode($request->all()). - Trailing whitespace or env quoting. A secret copied with a newline or quotes won't match.
trim()it and check the length (64 hex chars). - Proxy rewriting. Some CDNs and WAFs change bodies or strip custom headers. Confirm
X-Slimpay-*headers reach PHP.
"Request timestamp is outside the allowed window"
Your server clock is off. Sync with NTP (timedatectl status). Don't raise tolerance as a fix.
"Missing or invalid Slimpay signature headers"
- Headers aren't reaching PHP. Under php-fpm, use the
$_SERVERfallback in Other Frameworks. - Someone is calling the endpoint directly (browser, scanner). Rejecting that is correct.
Slimpay says my URL "can't be used"
URLs must be public HTTPS. http://, localhost, 127.0.0.1, private ranges and domains that don't resolve are refused. Use a tunnel for development.
Invoice collect fails with INVOICE_NOT_FOUND
Slimpay couldn't get a valid answer from your invoice lookup: wrong URL, endpoint slower than 8 s, a not-found response, or a body missing invoice.amount, student.student_id or student.name. Test the endpoint with the curl recipe in Testing and check your logs.
My webhook handler ran twice
Expected if someone pressed Resend. Make the handler idempotent on checkout_reference.
Webhooks aren't arriving
- Is the webhook URL saved and public HTTPS?
- Open the Webhooks page: is there a delivery row? Its status or error shows whether Slimpay reached you.
- Is your route behind auth, CSRF or a firewall?
- Does your endpoint return 2xx within 5 seconds?
FAQ
Do I need all three integrations? No. Webhooks alone are enough to reconcile payments; lookups and collectInvoice() are optional.
Sandbox vs live? The API key decides for Client. Lookups and webhooks use whichever environment the payment happened in.
Which PHP versions? 8.1+. Tested on 8.4.
Can I use Guzzle instead of curl? Yes, pass a transport callable (see API Client).
Can I verify signatures in another language? Yes. The algorithm is plain HMAC-SHA256 (see Security).
Is there a retry policy for webhooks? No automatic retry. Use Resend after fixing your endpoint, and reconcile via your dashboard if you were down.
Amounts: naira or kobo? Naira, as numbers (for example 25000).
docs