# Scheduled tasks

cPanel → Cron Jobs. Replace `USER` and confirm the PHP binary path (cPanel
usually shows it as `/usr/local/bin/php` or `/opt/cpanel/ea-php82/root/usr/bin/php`).

| Schedule | Command | Why |
|---|---|---|
| `*/5 * * * *` | `php /home/USER/bin/cron.php notifications` | Retries email that failed to send |
| `*/15 * * * *` | `php /home/USER/bin/cron.php reconcile-payments` | Completes orders where the customer's browser died mid-payment |
| `0 * * * *` | `php /home/USER/bin/cron.php prune` | Clears expired OTP records and rate-limit windows |
| `30 18 * * *` | `php /home/USER/bin/cron.php analytics` | Rolls up the previous day (18:30 UTC = 00:00 IST) |
| `0 3 * * *` | `php /home/USER/bin/cron.php stalled-cases` | Flags paid cases with no progress for a week |

Append `>/dev/null 2>&1` once you have confirmed each runs cleanly, or leave
output on and let cPanel email it to you for the first week.

## Notes

- Every task takes an exclusive lock, so a slow run will never overlap itself.
- Every task is idempotent. Running one twice does no harm.
- `reconcile-payments` only marks an order paid when the gateway reports the
  payment captured **and** the amount matches what we asked for. It cannot be
  used to force an order into a paid state.
- The runner refuses to execute over HTTP.
