Why this is the right answer for most WordPress MLMs
WordPress is a strong content and commerce platform. It's a weak MLM platform. The headless pattern lets each side do what it's good at: WordPress handles the storefront, replicated distributor sites, content marketing, and customer-facing pages. The SaaS MLM platform handles members, commissions, genealogy, KYC, and payouts. A REST plus webhook bridge keeps the two synchronized.
The architectural goals are simple: WordPress doesn't try to calculate commissions, the SaaS platform doesn't try to render product pages, and neither side breaks when the other is updated. In practice, this pattern scales from $500K GMV to well past $50M with the same architecture, just with proportionally bigger hosting under the WordPress side.
The architecture
┌──────────────────┐ REST ┌──────────────────┐
│ WordPress │ ──────►│ SaaS MLM │
│ Content │ │ Members │
│ WooCommerce │ ◄──────│ Commissions │
│ Distributor │ webhook │ Genealogy │
│ replicated │ │ E-wallet │
│ storefronts │ │ KYC │
└──────────────────┘ └──────────────────┘
Data flow, WordPress to SaaS:
- New distributor signup,
user_registerhook → POST/api/membersto the SaaS platform - WooCommerce order completion,
woocommerce_order_status_completed→ POST/api/orders - KYC document upload through WordPress → POST
/api/members/{id}/kyc-documents
Data flow, SaaS to WordPress:
- Commission calculated → webhook → update WordPress user meta with current earnings
- Distributor rank advancement → webhook → trigger WordPress notification
- KYC verification status change → webhook → update profile flags
The minimal WordPress code
A small must-use plugin in wp-content/mu-plugins/mlm-bridge.php:
<?php
/**
* Bridge new distributor signups and WooCommerce orders
* to the SaaS MLM platform.
*/
// Distributor signup: WordPress user → SaaS member
add_action( 'user_register', function( $user_id ) {
$user = get_userdata( $user_id );
$sponsor_id = get_user_meta( $user_id, 'sponsor_id', true );
wp_remote_post( MLM_API_URL . '/api/members', [
'headers' => [
'Authorization' => 'Bearer ' . MLM_API_TOKEN,
'Content-Type' => 'application/json',
'X-Idempotency-Key' => 'wp-user-' . $user_id,
],
'body' => wp_json_encode( [
'external_id' => (string) $user_id,
'email' => $user->user_email,
'name' => $user->display_name,
'sponsor_external_id' => $sponsor_id ? (string) $sponsor_id : null,
] ),
'timeout' => 8,
] );
} );
// Order completion: WC order → SaaS commission calculation
add_action( 'woocommerce_order_status_completed', function( $order_id ) {
$order = wc_get_order( $order_id );
$customer_id = $order->get_customer_id();
wp_remote_post( MLM_API_URL . '/api/orders', [
'headers' => [
'Authorization' => 'Bearer ' . MLM_API_TOKEN,
'Content-Type' => 'application/json',
'X-Idempotency-Key' => 'wp-order-' . $order_id,
],
'body' => wp_json_encode( [
'external_id' => (string) $order_id,
'distributor_external_id' => (string) $customer_id,
'amount' => (float) $order->get_total(),
'currency' => $order->get_currency(),
'completed_at' => $order->get_date_completed()->format( 'c' ),
] ),
'timeout' => 8,
] );
}, 20 );
Webhook receiver
Register a REST route that the SaaS platform posts to:
add_action( 'rest_api_init', function() {
register_rest_route( 'mlm-bridge/v1', '/webhooks', [
'methods' => 'POST',
'callback' => 'mlm_bridge_webhook',
'permission_callback' => '__return_true', // signature verified inside
] );
} );
function mlm_bridge_webhook( $request ) {
// Verify HMAC signature before trusting the payload
$payload = $request->get_body();
$signature = $request->get_header( 'x-mlm-signature' );
$expected = hash_hmac( 'sha256', $payload, MLM_WEBHOOK_SECRET );
if ( ! hash_equals( $expected, $signature ) ) {
return new WP_Error( 'invalid_signature', 'Invalid webhook signature', [ 'status' => 401 ] );
}
$event = json_decode( $payload, true );
switch ( $event['type'] ) {
case 'commission.calculated':
// Update user meta with latest commission earnings
update_user_meta(
(int) $event['data']['distributor_external_id'],
'lifetime_commissions',
$event['data']['lifetime_total']
);
break;
case 'rank.advanced':
// Trigger a notification or transactional email
do_action( 'mlm_rank_advanced', $event['data'] );
break;
}
return rest_ensure_response( [ 'received' => true ] );
}
What to verify in the vendor demo
Before signing with a SaaS MLM vendor for the headless path, verify five specifics during the demo. First, that the REST API covers every CRUD operation in their admin UI; the test is to ask them to walk through five admin operations through the API. Second, that webhooks are signed with HMAC-SHA256 and retried with exponential backoff for at least 24 hours. Third, that idempotency keys are honored on the inbound side so retries don't double-process. Fourth, that a sandbox environment exists for testing the webhook flow before going live. Fifth, that a PHP SDK or at least documented curl examples exist; the WP-side code should not require building HTTP plumbing from scratch.
CloudMLM Software passes these tests cleanly and ships with a PHP SDK that handles the boilerplate. Business MLM Software passes them functionally with slightly less polished SDK ergonomics. Other vendors in the broader MLM directory vary; the demo conversation surfaces it quickly.
What this scales to
The bridge architecture above scales to $50M GMV with no architectural changes. The constraints become hosting (move to managed WP at Kinsta or WP Engine class infrastructure), database (consider HyperDB or a managed MySQL beyond shared hosting), and observability (add structured logging on both sides of the bridge). At $50M+, the question becomes whether to leave WordPress entirely (Path 3, full migration), but for most networks staying on WordPress headless through that scale is fine.