Suma Order Volume Monitor Plugin (v1.2.2)
Monitors e-commerce order frequency across managed client sites and alerts operations staff when expected orders stop arriving — indicating potential site failures, payment gateway issues, or integration breakdowns.
Plugin Structure
suma-order-volume-monitor/
├── suma-order-volume-monitor.php ← Bootstrap, activation, cron hooks
├── includes/
│ ├── class-order-volume.php ← Core testing logic per platform
│ ├── class-system.php ← Test orchestrator
│ ├── class-notifier.php ← Email + SMS alerting
│ └── class-log.php ← File-based logging
└── [no build step - PHP only]
How It Works
Concept
Each monitored site has an expected order frequency (e.g., "at least 1 order every 8 hours"). The plugin periodically checks recent orders via API and alerts when the threshold is missed.
Test Flow
1. Cron triggers REST endpoint: POST /suma/v1/trigger-order-volume-tests
2. System class loads all monitored sites from ACF config
3. For each site:
a. Determine platform (WooCommerce or BigCommerce)
b. Query orders API for recent orders within frequency window
c. Apply night adjustment (3 AM – 9 AM reduces expectation)
d. Compare order count to threshold
e. Log result (SUCCESS or FAILURE)
f. If FAILURE → send notifications
Platform Testing
WooCommerce Sites
class Order_Volume {
public function test_woocommerce(array $site_config): array {
$client = new \Automattic\WooCommerce\Client(
$site_config['site_url'],
$site_config['consumer_key'],
$site_config['consumer_secret'],
['version' => 'wc/v3']
);
$orders = $client->get('orders', [
'after' => $this->get_window_start($site_config['order_frequency']),
'status' => ['processing', 'completed'],
'per_page' => 100,
]);
return [
'count' => count($orders),
'expected' => $site_config['minimum_orders'] ?? 1,
];
}
}
BigCommerce Sites
public function test_bigcommerce(array $site_config): array {
$response = wp_remote_get(
"https://api.bigcommerce.com/stores/{$site_config['store_hash']}/v2/orders",
[
'headers' => [
'X-Auth-Token' => $site_config['api_key'],
'Accept' => 'application/json',
],
'body' => [
'min_date_created' => $this->get_window_start($site_config['order_frequency']),
'status_id' => '2,5,10,11', // Shipped, Completed, etc.
],
]
);
$orders = json_decode(wp_remote_retrieve_body($response), true);
return [
'count' => count($orders),
'expected' => $site_config['minimum_orders'] ?? 1,
];
}
Night Adjustment
Between 3:00 AM and 9:00 AM (server time), order frequency expectations are reduced to avoid false positives during low-traffic hours:
private function apply_night_adjustment(int $frequency_hours): int {
$current_hour = (int) date('G');
// Between 3 AM and 9 AM, extend the monitoring window by 8 hours
if ($current_hour >= 3 && $current_hour < 9) {
return $frequency_hours + 8;
}
return $frequency_hours;
}
Example: A site expecting orders every 8 hours will not alert until 16 hours without orders if checked during nighttime hours.
Notification System
Email Notifications
class Notifier {
public function send_email(array $contacts, string $site_name, string $message): void {
$subject = "[Order Alert] {$site_name} - No recent orders detected";
$body = "Site: {$site_name}\n\n{$message}\n\nPlease investigate immediately.";
foreach ($contacts as $contact) {
wp_mail($contact['email'], $subject, $body);
}
}
}
SMS Notifications (Carrier Gateway)
SMS is sent via email-to-SMS carrier gateways:
public function send_sms(array $contacts, string $site_name, string $message): void {
$sms_body = "[{$site_name}] No orders - investigate";
foreach ($contacts as $contact) {
if (!empty($contact['phone'])) {
// Format: [email protected] (Verizon)
$sms_email = $contact['phone'] . '@vtext.com';
wp_mail($sms_email, '', $sms_body);
}
}
}
Carrier gateways supported:
| Carrier | Gateway |
|---|---|
| Verizon | @vtext.com |
| AT&T | @txt.att.net |
| T-Mobile | @tmomail.net |
Configuration (ACF)
Settings are managed via ACF options page (repeater fields):
sites_to_monitor (Repeater)
| Sub-field | Type | Description |
|---|---|---|
site_url | URL | Full site URL |
platform | Select | WooCommerce or BigCommerce |
order_frequency | Number | Expected hours between orders |
minimum_orders | Number | Minimum expected order count |
api_key | Text | API authentication key |
consumer_key | Text | WooCommerce consumer key |
consumer_secret | Text | WooCommerce consumer secret |
store_hash | Text | BigCommerce store hash |
monitoring_rules | Textarea | Custom rules/notes |
contacts_to_notify | Repeater | People to alert |
contacts_to_notify (Sub-repeater)
| Sub-field | Type | Description |
|---|---|---|
name | Text | Contact name |
email | Email address | |
phone | Text | Phone number (digits only) |
Logging
File-Based Logging
Results are logged to daily files:
wp-content/uploads/suma-logs/
├── order-volume-2025-05-04.log
├── order-volume-2025-05-03.log
└── ...
Log Format
[2025-05-04 08:00:15] SUCCESS | example.com | 3 orders in last 8 hours
[2025-05-04 08:00:18] FAILURE | shop.com | 0 orders in last 8 hours (expected 1+)
Database Logging
Results also stored in wp_order_volume_monitor_log table for dashboard viewing.
REST Endpoint
POST /wp-json/suma/v1/trigger-order-volume-tests
Triggers a full test run across all configured sites.
Authentication: Public (designed for cron execution).
Response:
{
"success": true,
"results": [
{
"site": "example.com",
"status": "SUCCESS",
"message": "3 orders in last 8 hours",
"order_count": 3
},
{
"site": "shop.com",
"status": "FAILURE",
"message": "0 orders in last 16 hours (night adjustment applied)",
"order_count": 0
}
]
}
Cron Schedule
| Task | Schedule | Description |
|---|---|---|
| Order volume tests | Every 2–4 hours | Run all site checks |
| Log cleanup | Weekly (Sunday) | Delete logs older than 30 days |
| Daily summary email | Daily (8 AM) | Send digest of last 24h results |
Cleanup
// Weekly cleanup cron removes old log files
public function cleanup_old_logs(): void {
$log_dir = WP_CONTENT_DIR . '/uploads/suma-logs/';
$files = glob($log_dir . 'order-volume-*.log');
foreach ($files as $file) {
$age_days = (time() - filemtime($file)) / DAY_IN_SECONDS;
if ($age_days > 30) {
unlink($file);
}
}
}
Troubleshooting
False Positives During Low Traffic
- Check if night adjustment is working (3–9 AM window)
- Increase
order_frequencyfor low-volume sites - Review timezone settings (server time vs. store time)
API Connection Failures
- Verify WooCommerce consumer key/secret are active
- Check BigCommerce API token hasn't expired
- Ensure site is accessible from manage.rhinogroup.com network
SMS Not Delivered
- Confirm phone number format (digits only, no dashes)
- Verify carrier gateway is correct for the contact
- Check WP Mail SMTP is properly configured