SDKs
Security
How signing works
For lookups (and webhooks when a secret is set), Slimpay sends:
text
X-Slimpay-Timestamp: <unix seconds>
X-Slimpay-Signature: hex( HMAC-SHA256( secret, "<timestamp>.<raw request body>" ) )
The SDK:
- Rejects requests missing either header.
- Rejects timestamps more than
toleranceseconds (default 300) from your clock. The timestamp is inside the signed string, so an attacker can't refresh an old request. - Recomputes the HMAC over the raw bytes and compares with
hash_equals(constant time).
Verify it yourself
php
$expected = hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
$valid = hash_equals($expected, $signatureHeader);
Do
- Keep secrets and the API key in environment variables or a secret manager.
- Always verify before parsing or acting on a body.
- Serve endpoints over HTTPS and keep your server clock synced (NTP).
- Make webhook handlers idempotent.
- Regenerate a secret immediately if it leaks (the old one dies instantly).
Don't
- Don't commit secrets or log full signature headers or secrets.
- Don't verify against
json_encode($decoded); use the raw body. - Don't expose the live API key to browsers or mobile apps.
- Don't mark an invoice paid from the payer's redirect back to your site.
- Don't disable verification "temporarily" in production.
Secret rotation
- Generate a new secret in the Slimpay portal. The old one stops immediately.
- Update your environment and reload workers.
- Use Send Test Webhook or Test Connection to confirm.
Expect a short window of rejected requests; plan rotation for a quiet time. Report vulnerabilities privately to the Slimpay team rather than in public issues.
docs