TECHNICAL DEEP-DIVE

Architecture

How eight WordPress plugins share one security model, one UX system, and one licensing infrastructure. A deep-dive into the engineering decisions, dependency chain, and inter-plugin communication that holds the ecosystem together.

Scroll

The Dependency Chain

01 / STRUCTURE

How the eight plugins relate to each other and the server-authoritative licensing backend.

The licensing backend sits at the top, a server-authoritative system running on ajt.support. It never ships to customers. Every client plugin phones home for registration, heartbeat verification, and RSA JWT token refresh.

Stripe Pro is the parent, a standalone billing platform that provides the customer portal framework, encryption utilities, and the full 14-file License Module. MSP Hub is its child, extending every surface via WordPress hooks.

MFA, Backup, and SMTP Pro are standalone companions, each uses License Lite (single-file, lighter weight) and registers as a GLASS app. They have zero dependencies on each other but share the same security patterns and UX conventions.

RSA JWT Licensing

02 / SECURITY

Every AJT plugin verifies its license using RS256 asymmetric JWT tokens. The private key lives only on the licensing server, customers cannot forge tokens even if they have full filesystem access to their WordPress install.

Heartbeat verification runs every 10 minutes via WP-Cron. If the server is unreachable, a 120-minute offline grace period prevents false lockouts. The Sentinel MU-plugin monitors file integrity via hash checks and enforces compliance independently, it cannot be deactivated from the admin UI.

HMAC-SHA256 request verification protects every API call between client and master. Timestamps and nonces prevent replay attacks. The nonce table is pruned every 60 seconds with a 10-minute TTL.

Stripe Pro's customer portal is a tabbed interface rendered by the [ajt_customer_portal] shortcode. Default tabs: Invoices, Subscriptions, Payment Methods, Profile. But the architecture is extensible, MSP Hub injects four additional tabs via hooks.

Every tab follows the same "table-in-panel" design pattern: summary strip with gradient metric boxes, bordered panel with filter pill tabs, scrollable table, and centred pagination. CSS classes are shared across all tabs.

This means when MSP Hub adds a Tickets tab, it looks exactly like the Invoices tab. The portal is a framework, not a monolith, and the MSP's white-label branding applies uniformly because everything uses CSS custom properties.

The Portal Framework

03 / EXTENSIBILITY

A tabbed interface that grows through WordPress hooks, not monolithic code.

Encryption Model

All PII is encrypted at rest using AES-256-CBC with keys derived from WordPress's AUTH_KEY and AUTH_SALT constants. Every customer email, name, phone number, address, and payment method ID is encrypted before database storage.

SHA-256 blind indexes enable searching encrypted fields without decrypting every row. You can look up a customer by email hash without ever exposing the plaintext email to a database query.

Client and server use separate encryption key chains, a compromised client site cannot decrypt server-side data, and vice versa.

Command Bus

On ajt.support where the licensing backend and Stripe Pro are co-located, they communicate via a local WordPress hook, do_action( 'ajt_payments/command', $envelope ). No HTTP, no REST API, no network latency.

Commands include CREATE_INVOICE, SYNC_CUSTOMER, CANCEL_ACCOUNT, and SYNC_PRODUCT. Each command is recorded in the ajt_license_commands table with its payload, status, and result. Failed commands can be retried from the admin.

The product registry defines every AJT product's plans, pricing, and activation limits. These are synced to Stripe Pro via SYNC_PRODUCT commands, which creates the Stripe Price objects and links them to the subscription portal.

Architecture by Layer

Stripe Pro owns wp_ajt_stripe_invoices, the canonical invoice table. MSP Hub creates 8 additional tables for Autotask sync, contract templates, service changes, and quote caching. The licensing backend has 7 tables including site registrations, license keys, event logs, command queues, and nonce replay protection. All tables use $wpdb->prepare() exclusively. Amounts are stored in pence/cents (integers) to avoid floating-point precision errors. Encrypted fields use dedicated columns, the hash column for lookups, the encrypted column for storage.

Every AJAX handler uses check_ajax_referer(). Every admin function gates on current_user_can('manage_options'). Every form uses wp_nonce_field(). All inputs pass through sanitize_text_field(), sanitize_email(), or intval(). Prices are always looked up server-side from the product catalogue, never trusted from client-submitted values. Stripe webhooks are verified via HMAC-SHA256 with 5-minute timestamp tolerance. Contract signing uses 64-character random tokens with expiry limits.

14 scheduled tasks across the ecosystem: daily autopay processing (2am), overdue invoice reminders, subscription renewals (3am), hourly Autotask data sync, periodic accounting bridge sync, contract expiry checks, license expiry processing (per-slug independent), audit log cleanup (heartbeats pruned at 30 days, others at 180 days), nonce table pruning, and command queue housekeeping. Each cron hook is properly registered on activation and cleared on uninstall.

Inter-plugin communication is hook-based: ajt_stripe_portal_nav_tabs and ajt_stripe_portal_tab_content let MSP Hub inject portal tabs. ajt_stripe_portal_before_invoices is the autopay injection point. ajt_payments/command is the local command bus for inter-plugin communication. ajt_mfa_redirect_url lets MSP Hub redirect MFA challenges to the branded login page. ajt_stripe_sa_invoice_paid triggers license activation on payment. glass_register_app registers any plugin as a GLASS app.

Want to Work Together?

I'm always interested in challenging WordPress architecture problems. If you need a plugin built properly, let's talk.

Get in Touch