OpenInvoice uses cron jobs for automated tasks like generating recurring invoices and sending payment reminders.
CRON_SECRET environment variableEndpoint: /api/cron/recurring-invoices
Schedule: Daily (or as configured)
Purpose: Generate invoices from recurring templates
Endpoint: /api/cron/payment-reminders
Schedule: Daily
Purpose: Send payment reminder emails
Endpoint: /api/cron/payment-retry
Schedule: Hourly
Purpose: Retry failed payment transactions
CRON_SECRET=your-secret-key-here
Generate a secure secret:
openssl rand -hex 32
Cron endpoints verify the secret:
if (req.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) {
return new Response('Unauthorized', { status: 401 });
}
Create .github/workflows/cron.yml:
name: Cron Jobs
on:
schedule:
- cron: '0 0 * * *' # Daily at midnight UTC
workflow_dispatch:
jobs:
recurring-invoices:
runs-on: ubuntu-latest
steps:
- name: Generate Recurring Invoices
run: |
curl -X POST https://yourdomain.com/api/cron/recurring-invoices \
-H "Authorization: Bearer ${{ secrets.CRON_SECRET }}"
payment-reminders:
runs-on: ubuntu-latest
steps:
- name: Send Payment Reminders
run: |
curl -X POST https://yourdomain.com/api/cron/payment-reminders \
-H "Authorization: Bearer ${{ secrets.CRON_SECRET }}"
CRON_SECRET secret{
"crons": [
{
"path": "/api/cron/recurring-invoices",
"schedule": "0 0 * * *"
},
{
"path": "/api/cron/payment-reminders",
"schedule": "0 0 * * *"
}
]
}
Test endpoints manually:
curl -X POST http://localhost:3000/api/cron/recurring-invoices \
-H "Authorization: Bearer your-cron-secret"
Run cron logic locally:
// Test recurring invoice generation
const templates = await getDueTemplates();
for (const template of templates) {
await generateInvoiceFromTemplate(template);
}
Monitor cron job execution:
Set up alerts for: