{% extends 'companies/superadmin/base.html' %} {% block content %}

Server Setup & Integrations

Configure Monnify webhook and the daily subscription automation task.

① Monnify Webhook URL Required

Monnify must call this URL after every payment to automatically activate or renew a company's subscription. Without this, payments will NOT activate subscriptions automatically.

Steps: Log in to app.monnify.comSettingsWebhook → paste the URL above → Save. Monnify will POST to this URL after every successful payment.
① Paystack Webhook URL Required if using Paystack

Paystack must call this URL after every successful payment to automatically activate or renew a company's subscription. Without this, payments may not activate subscriptions if the customer closes their browser.

Steps: Log in to dashboard.paystack.comSettingsAPI Keys & Webhooks → paste the URL above in the Webhook URL field → Save Changes. Paystack will POST to this URL after every successful charge.success event.
② Daily Subscription Task (cPanel Cron Job)

This task must run once every day. It does 3 things:

1 Suspends expired companies — companies whose subscription ran out lose access automatically.
2 Applies plan downgrades — switches plan at end of billing cycle if downgrade was requested.
3 Sends warning emails — notifies companies 3 days and 1 day before expiry.
If this is not set up, expired companies stay active forever and no one gets renewal reminders.
On a live cPanel server, the python path may differ. Try /usr/bin/python3 or /home/yourusername/virtualenv/swone/3.x/bin/python. Ask your host if unsure.

How to set this up on cPanel (step by step):

  1. Log in to your cPanel hosting account.
  2. Search for "Cron Jobs" in the cPanel search bar and open it.
  3. Scroll down to "Add New Cron Job".
  4. In the Common Settings dropdown, choose Once Per Day (runs at 1:00 AM).
  5. In the Command field, paste the command shown above.
  6. Click "Add New Cron Job". Done! ✅

Cron Schedule Reference (if setting time fields manually):

Minute Hour Day Month Weekday Meaning
0 1 * * * Every day at 1:00 AM ✅ Recommended
0 0 * * * Every day at midnight
To test manually: Go to cPanel → Terminal (or SSH), paste the command, and press Enter. It should print "Subscription processing complete" with no errors.
③ Daily Analytics & Insights (Midnight WAT)

This task runs once every day at midnight WAT. It does 4 things:

1 Generates Business Insights — sales trends, low-stock alerts, top products, staff performance, and more (15+ auto insights per company).
2 Stock Forecasting — calculates how many days until each product runs out and recommends restock quantities.
3 Sends Daily Email Reports — sends a business summary email to each company admin.
4 Cleans Old Notifications — removes notifications older than 30 days automatically.
Without this, the Analytics dashboard will show no insights and no email reports will be sent.
Set the schedule to 0 23 * * * (11 PM UTC = midnight WAT) or use Once Per Day in cPanel.

How to set up on cPanel (step by step):

  1. Log in to your cPanel hosting account.
  2. Search for "Cron Jobs" and open it.
  3. Scroll to "Add New Cron Job".
  4. Set Minute = 0, Hour = 23, Day/Month/Weekday = *.
  5. Paste the command above into the Command field.
  6. Click "Add New Cron Job". ✅

Cron Schedule (midnight WAT = 23:00 UTC):

MinuteHourDayMonthWeekdayMeaning
023*** Every day at 11 PM UTC (= midnight WAT) ✅ Recommended
00*** Every day at midnight UTC (= 1 AM WAT)
To test manually: In cPanel Terminal or SSH, run the command. It should print "Successfully generated insights for X companies".
④ reCAPTCHA v2 — Login Bot Protection Recommended

What reCAPTCHA does:

🤖 Blocks automated bots — prevents credential-stuffing and brute-force scripts from hammering the login page.
🔐 Gate before credentials — the reCAPTCHA token is verified before the username/password are even checked.
⚙️ Zero code needed — fully configurable from Django Admin. Toggle on/off at any time with no restart required.
Note: Even with reCAPTCHA disabled, SwiftPOS still enforces IP-based rate limiting (5 failures → 15-minute block) as a server-side backstop.

Setup steps (takes ~3 minutes):

  1. Go to google.com/recaptcha/admin/create and sign in with your Google account.
  2. Fill in a Label (e.g. SwiftPOS Login).
  3. Under reCAPTCHA type, choose reCAPTCHA v2"I'm not a robot" Checkbox.
  4. Under Domains, add your production domain (e.g. app.swiftpos.ng). For local testing also add 127.0.0.1 and localhost.
  5. Click Submit. Google will show you two keys:
Site Key (PUBLIC)
Paste into recaptcha_site_key in Django Admin.
This is embedded in the HTML — it's safe to be public.
Secret Key (PRIVATE)
Paste into recaptcha_secret_key in Django Admin.
Never share this. It verifies tokens server-side.
  1. In Django Admin, go to Site Configuration (under the Core section) → scroll to "reCAPTCHA — Login Protection".
  2. Paste the Site Key and Secret Key into the respective fields.
  3. Check Recaptcha enabledSave. Done! ✅

Troubleshooting:

  • Widget not appearing? Check that recaptcha_enabled is ✅ ON and recaptcha_site_key is not blank.
  • Always passing even when unchecked? Verify recaptcha_secret_key is correct. An empty secret key causes fail-open (graceful bypass).
  • "ERROR for site owner: Invalid domain"? Your domain is not registered in the Google reCAPTCHA console. Add it there.
  • Testing locally? Add localhost and 127.0.0.1 to allowed domains in Google console, then use those special test keys for dev.
{% endblock %}