Blog · Billing & payments

Cron jobs for Stripe, payroll and recurring billing flows

Stripe Reports and Sigma cover audits, not the daily reconciliation and per-tenant payroll loops most teams actually run. These posts cover the external cron pattern.

About this topic

Billing & payments

3 itemsBlog

Stripe gives you events and reports. It doesn't give you a clock. The daily reconciliation between Stripe's payments and your own ledger, the custom dunning emails that fire 3 days after a failed charge, the monthly invoice that needs to land at 09:00 in each tenant's local timezone, and the webhook-replay loop for missed events: all four sit outside Stripe's native scheduling. Multi-tenant payroll is the same shape squared. Per-tenant cadence, per-tenant timezone, tenants come and go, and any hardcoded crontab or in-process scheduler buckles on the tenant axis.

Crontap is the wall clock. One schedule per reconciliation job, per IANA timezone, with custom headers for the API tokens and retries on the inevitable 5xx. For multi-tenant work, the pattern is one schedule per tenant pointing at a shared endpoint, bulk-created from the tenant table, paused or deleted as tenants churn. Failure alerts to Slack, Discord, Telegram, email, or a webhook mean a missed reconciliation lands in the ops channel the moment it happens, not the next morning during the audit.

Blog on Billing & payments

3 items

Related on Crontap

The same Billing & payments topic, from other angles.

FAQ

Common questions on Billing & payments

Why not use Stripe webhooks for reconciliation instead of a cron?
Webhooks tell you about a single event. Reconciliation is about all the events in a window: which payments landed today, which fees were taken, which refunds processed. The right shape is a daily cron that lists payments by created and reconciles the window, with webhooks as the real-time path for anything that needs to happen instantly.
Multi-tenant timezones: hardcoded crontabs or per-tenant schedules?
Hardcoded crontabs hit one cadence and one timezone, so any timezone-sensitive tenant gets the wrong wall-clock fire. The per-tenant Crontap pattern is one schedule per tenant, each with its own IANA timezone, all pointing at a shared /tenants/{id}/run-payroll endpoint. DST is handled automatically.
How do I keep the dunning endpoint safe from public traffic?
A shared-secret header check inside the handler. Crontap sends custom headers per schedule, so an X-CRON-TOKEN paired with an env var on the function side keeps the endpoint locked. The Stripe reconciliation post shows the exact handler snippet.
What's the failure-alert path for a missed reconciliation?
Add a Slack (or Discord, Telegram, email, custom webhook) integration to the schedule. Crontap fires on 4xx and 5xx with the response body and timing in the payload, so a 500 from the reconciliation route lands in your ops channel within seconds.

More from Crontap

Topics across the site.

Every topic Crontap covers, in one row. Each one has its own page on the blog surface.

Ready to fix it?

Point Crontap at any URL. Pick any cron. Done.

WordPress, Shopify, Railway, Cloud Run, Vercel, HubSpot, Ghost, your own box. If it answers HTTP, Crontap can drive it on a clock you can read, in the timezone that actually matters, and page you when something breaks.

Free forever tier ・ No credit card required

GET

/wp-cron.php?doing_wp_cron=1

Running
Your next schedule

Schedule

"every 5 minutes"

Next

in 23s