Skip to main content

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:

CarrierGateway
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-fieldTypeDescription
site_urlURLFull site URL
platformSelectWooCommerce or BigCommerce
order_frequencyNumberExpected hours between orders
minimum_ordersNumberMinimum expected order count
api_keyTextAPI authentication key
consumer_keyTextWooCommerce consumer key
consumer_secretTextWooCommerce consumer secret
store_hashTextBigCommerce store hash
monitoring_rulesTextareaCustom rules/notes
contacts_to_notifyRepeaterPeople to alert

contacts_to_notify (Sub-repeater)

Sub-fieldTypeDescription
nameTextContact name
emailEmailEmail address
phoneTextPhone 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

TaskScheduleDescription
Order volume testsEvery 2–4 hoursRun all site checks
Log cleanupWeekly (Sunday)Delete logs older than 30 days
Daily summary emailDaily (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_frequency for 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