Skip to main content

WordPress Proxy

The WordPress plugin acts as a reverse proxy between the browser and the NestJS Platform. All tracker data (errors, pageviews, leads, visitor events) passes through your WordPress server before reaching the Platform.

How the Proxy Works

The plugin registers a WordPress REST API endpoint:

POST /wp-json/wpel/v1/ingest

Requests to this endpoint are:

  1. Validated (nonce check for authenticated actions, origin check)
  2. Enriched (server-side data added)
  3. Forwarded to the Platform via wp_remote_post()

Client-Side Configuration Object

The tracker script reads its configuration from a global JavaScript object injected by PHP:

<script>
window.StorePilot = {
apiBase: "https://api.store-pilot.net",
siteKey: "5f3a2b1c-8e4d-4f9a-b7c6-...",
proxyUrl: "https://mysite.com/wp-json/wpel/v1/ingest",
features: {
errorTracking: true,
recordings: true,
pageviews: true,
leads: false
},
recordingSampleRate: 100
};
</script>

This object is generated by PHP and output in wp_head. It uses the API key and settings stored in the WordPress database (configured in StorePilot → Settings).


Server-Side Enrichment

When a lead or error payload arrives at the proxy, PHP adds:

// Added by the WordPress proxy before forwarding
$enrichment = [
'wp_user_id' => get_current_user_id(), // 0 if not logged in
'wc_cart' => [],
'wc_cart_total' => '0.00',
];

if ( function_exists('WC') && WC()->cart ) {
foreach ( WC()->cart->get_cart() as $item ) {
$enrichment['wc_cart'][] = [
'product_id' => $item['product_id'],
'name' => get_the_title( $item['product_id'] ),
'qty' => $item['quantity'],
'line_total' => $item['line_total'],
];
}
$enrichment['wc_cart_total'] = WC()->cart->get_cart_total();
}

This enrichment is merged into the payload JSON before it is forwarded to the Platform.


Security

  • Nonce validation: WordPress nonce (wp_create_nonce('wpel-ingest')) is required for lead submissions
  • Origin check: The proxy validates that requests originate from the same domain
  • API key not exposed: The API key is added by PHP to the X-StorePilot-Key header when forwarding — it is not included in the JavaScript config object visible in page source

Wait — in the default configuration, the siteKey IS included in window.StorePilot for direct browser → Platform requests (recordings, pageviews). The key is write-only (cannot read data) so this is acceptable. See API Key Security.


Proxy Request Forwarding

$response = wp_remote_post( $platform_url . '/ingest/' . $endpoint, [
'headers' => [
'Content-Type' => 'application/json',
'X-StorePilot-Key' => $api_key,
'X-Forwarded-For' => $_SERVER['REMOTE_ADDR'],
],
'body' => wp_json_encode( $payload ),
'timeout' => 5,
] );

The X-Forwarded-For header passes the visitor's real IP address to the Platform for geolocation. The Platform resolves country/city and discards the raw IP immediately.


Handling Proxy Failures

If wp_remote_post() fails (network error, Platform down), the error is logged to the WordPress error log but not re-tried. The event is lost silently to avoid blocking page rendering.

For guaranteed delivery, use the BullMQ queue path (errors are queued on the Platform side, so the proxy just needs to deliver the job to the queue — not wait for processing).