Checklist
- Use HTTPS
- Enable HMAC-SHA256 authentication
- Whitelist SePay IPs
- Deduplicate transactions
- Validate amount and account
- Reconcile periodically
URL requirements
The webhook URL must be reachable from the public Internet:
- HTTPS is required; HTTP is not accepted
- The domain must resolve via DNS to a public IP
- Internal IPs (
localhost,127.0.0.1,10.x,172.16-31.x,192.168.x) and reserved ranges are rejected
URLs that don't meet these are rejected when the webhook is saved.
Use a valid SSL certificate (Let's Encrypt offers free ones). Don't use self-signed certificates. The CA chain (intermediate certificates) must be complete.
Signature verification
Always verify the signature on every request. Best is HMAC-SHA256. At minimum use API Key.
Always verify incoming webhooks with at least API Key or HMAC-SHA256. Without authentication, anyone who knows the URL can send forged payloads.
IP Whitelist
Only allow requests from SePay IPs. List at IP addresses. Configure at firewall or middleware.
Replay attack protection
If you use HMAC-SHA256, also check the X-SePay-Timestamp header. Reject requests where the timestamp drifts more than 5 minutes from the current time to block attackers from replaying old requests. If your server clock drifts, enable NTP for automatic time sync.
Validate data
Before confirming a payment, check:
- Does
transferAmountmatch the order amount? - Is
accountNumberactually your account? - Does
codematch the order's payment code?
For extra confidence, call the transactions API to cross-check.
Save raw payload
Save the original payload to your database before processing. You'll have data for debugging, audit, or reconciliation later.
Periodic reconciliation
Webhooks can be lost if your endpoint is down for more than 5 hours. Run a cron every 15-30 minutes to fetch transactions via API, compare against your database, and add missing transactions. Details: Reconciliation.
Next
- Monitoring: logs, alerts, incidents
- Error handling: retry schedule and diagnostics when webhooks fail
- Reconciliation: backup when webhooks are lost