Skip to content

Phase 11: Webhooks & Analytics

Implement outbound webhooks with HMAC-SHA256 signatures and an analytics service that detects licensing abuse patterns.

  • src/Services/WebhookService.php
  • src/Services/AnalyticsService.php

Merchants register webhook endpoints via POST /wplm/v1/webhooks:

{
"url": "https://example.com/webhook",
"events": ["license.created", "license.revoked", "subscription.renewed"]
}

Each endpoint gets a unique per-endpoint HMAC secret (32 random bytes) so different endpoints can be individually invalidated.

$webhook_svc->dispatch('license.revoked', $license->to_array());

Internally:

  1. Load all webhook records that subscribe to license.revoked.
  2. Build JSON payload with event, data, and delivered_at.
  3. Compute HMAC-SHA256(secret, payload).
  4. Send POST via wp_remote_post() with header X-WPLM-Signature: sha256=<hex>.
  5. Store delivery log (status code, response, duration).

Merchants verify:

$expected = hash_hmac('sha256', file_get_contents('php://input'), $secret);
hash_equals($expected, $received_sig); // timing-safe

license.created | license.activated | license.deactivated | license.revoked | license.suspended | license.terminated | license.expired | subscription.created | subscription.renewed | subscription.payment_failed | subscription.cancelled

get_overview() returns aggregate stats with a 10-minute transient cache:

[
'active_licenses' => int,
'inactive_licenses' => int,
'expiring_soon' => int, // expires within 30 days
'active_machines' => int,
'revenue_mtd' => float,
'renewals_today' => int,
]

detect_anomalies() runs three checks:

AnomalyThresholdSignal
Fingerprint churn> 5 new devices for 1 license in 24 hPossible key sharing / cracking
Validation spikeCurrent-hour rate > 3× 7-day hourly averageBot scraping or brute force
Impossible travel> 2 distinct countries for 1 license in 1 hCredential sharing or VPN rotation

When an anomaly is detected:

do_action('wplm_anomaly_detected', $type, $license_id, $detail);

Default handler logs to the audit log. Merchants can hook this action to send Slack alerts, suspend the license automatically, etc.

Both get_overview() and detect_anomalies() are exposed via the REST API at /wplm/v1/analytics/*.