WordPress engineering for ambitious agenciesLooking for a delivery partner?

CASE STUDY

Condixia REST Gateway

A custom-built WordPress and WooCommerce REST API gateway engineered for secure, scalable third-party integrations. Featuring hashed API credentials, granular access permissions, dynamic endpoint registration, controlled content operations, HPOS-compatible WooCommerce data access, and intelligent rate limiting—all within a modular, extensible architecture.

← All case studies
Custom WordPress Plugin / API InfrastructureDevelopment case study

Condixia REST Gateway.

An independent authentication and resource-access layer for WordPress and WooCommerce, built for external dashboards, headless applications, and backend integrations that need secure, predictable API access.

Request architecture
External App→Bearer Authentication→Scope + Policy Checks→Resource Adapter→JSON Response

The engineering challenge. Expose carefully selected WordPress and WooCommerce data to external systems without giving those systems WordPress login access, unrestricted post metadata, or blanket read/write privileges.

Screenshot 01Plugin dashboard — detected resources, client counts, WooCommerce status, and REST base URL.
01 / 06

Custom API authentication & credential security

A standalone machine-to-machine identity system, separate from normal WordPress accounts.

Purpose-built Bearer credentials

Every integration receives an independent client identity and a versioned cxi_v1_<client-id>.<secret> token format, without needing WordPress passwords, login cookies, JWT, or OAuth dependencies.

Cryptographically generated, hashed secrets

Secrets are generated from random_bytes(32), encoded into URL-safe credentials, hashed with password_hash(), and checked using password_verify(); reusable plaintext secrets are not stored.

One-time reveal and lifecycle control

The initial credential is shown only at creation. Clients can be enabled, disabled, or revoked; the service layer also contains a secret-rotation method that invalidates the previous secret.

Dedicated client database and upgrades

A custom, indexed client table holds a unique client ID, hash, scopes, status, expiration, last-used timestamp, and creation/update timestamps. Schema installation and version checks use WordPress dbDelta().

Expiry and usage-state enforcement

Expiration input is normalized to UTC, evaluated during authentication, and rejected when expired. Successful authentication updates the last-used timestamp with a one-minute write throttle.

HTTPS enforcement and header handling

HTTPS is required by default, with an explicit extension filter. Bearer headers are read from REST requests and common server forwarded-header variables to handle different hosting configurations.

Screenshot 02API Keys — client creator with searchable scope selection, expiration field, and client management table.
02 / 06

Granular permissions & guarded content writes

Authentication alone does not grant operations. Read, create, and update permissions are independently evaluated.

Resource-specific permission scopes

Scopes follow a structured pattern such as posts:read, posts:create, and posts:update. The permission engine evaluates the requesting client for each resource and HTTP operation.

Two-layer authorization for writes

Creating or updating content requires both an assigned client scope and a separately enabled resource-level write setting. All WordPress resource writes are disabled by default.

Controlled POST/PATCH implementation

Supported post types can be created through POST and updated through PATCH using wp_insert_post() and wp_update_post(). No DELETE endpoint is registered.

Schema-driven validation and sanitization

Writable fields are explicitly declared per resource, checked for expected types, and sanitized by field: text, slugs, permitted post HTML, parent IDs, and menu order are handled differently.

Post-state and hierarchy safeguards

New content defaults to draft. Status updates are constrained to approved values; parent IDs must refer to the same post type, and a post cannot be its own parent. Protected or disallowed post states are excluded from reads or updates.

Bounded request-body processing

Write requests have a configurable default size ceiling of 1 MiB. Invalid JSON, non-array payloads, unsupported fields, and empty writes receive explicit API errors rather than reaching WordPress writes.

Screenshot 03Settings — per-resource write switches alongside the required create/update scopes.
03 / 06

Dynamic resources & extensible architecture

One generic API surface powers multiple WordPress content types and pluggable data providers.

Automatic public post-type discovery

The gateway inspects registered public post types and creates resource adapters for eligible types, including posts, pages, and supported custom post types, while skipping attachments and avoiding WooCommerce product conflicts.

Resource and provider registries

Typed resource contracts separate readable and writable capabilities. Distinct registries handle resources and providers; unsupported methods are not exposed just because a resource exists.

Schema and capability introspection

Authorized clients can request GET /resources to inspect only resources within their read scopes, including schemas, operations, sortable fields, filterable fields, and current write-enable status.

Versioned, reusable REST routing

The condixia/v1 namespace maps generic collection and item routes to resource adapters, allowing new supported post types without a separate controller for each one.

Extension hooks at key boundaries

Registration, authentication, scope evaluation, query arguments, serialized data, create/update events, and response handling have WordPress hooks for future provider integrations and customization.

Generated endpoint reference

An internal endpoint catalog is assembled from live registered resources, showing GET/POST/PATCH routes, required scopes, enablement state, and sample cURL commands.

Screenshot 04Endpoints — generated route catalog showing resources, methods, authentication, scopes, and cURL examples.
04 / 06

WooCommerce data adapters & HPOS compatibility

Commerce records are read through supported WooCommerce objects, not assumptions about WordPress database storage.

Conditional WooCommerce provider

When WooCommerce functions are available, dedicated product and order resources are registered under the same gateway and permission model. Both resources remain read-only.

Product-specific serialization

A curated product schema exposes catalog and inventory details such as SKUs, prices, sale state, stock status, variation IDs, categories, primary image, and gallery image IDs.

Commerce-aware product filters

Product listing queries support relevant filters including publish status, product type, SKU, category, stock status, and parent product, using WooCommerce product-query APIs.

HPOS-aware order retrieval

Order queries use wc_get_orders() and wc_get_order() rather than reading shop_order posts directly, supporting WooCommerce High-Performance Order Storage.

Controlled order reporting fields

Orders are serialized into explicitly selected operational details: status, currency, totals, tax, payment method, product line items, and shipping lines. Raw customer records and full WooCommerce objects are not returned.

Scoped and filtered order access

The orders:read scope guards order endpoints. Listings can filter by valid order status, currency, payment method, and creation source, with paginated totals.

Screenshot 05API response — Postman or Insomnia showing a redacted products or orders GET request with JSON output.
05 / 06

Query handling, serialization & API reliability

A consistent response layer makes the gateway practical for dashboards and integrations—not just individual API calls.

Bounded pagination with metadata

Collections default to 20 records per page, enforce a configurable default maximum of 100, and return page, per_page, total, and total_pages.

Resource-aware querying

Sortable and filterable fields are defined per adapter rather than exposing arbitrary query arguments. Unsupported sort fields and invalid filter values are rejected; generic free-text searching of orders is explicitly unsupported.

Sparse-field selection

Clients can request a comma-separated fields list. Field names are checked against each resource’s readable schema and responses are projected down to the requested fields.

Published-content protections

Post collections read published, non-password-protected content by default; product endpoints limit access to published products. Sensitive post metadata is not included in default resource serialization.

Standard response and error contracts

Successful operations use consistent success, data, and meta structures. Gateway errors are normalized to machine-readable codes, messages, and appropriate HTTP status codes.

Per-client rate protection

A transient-backed limiter tracks requests per client (default: 120 requests per 60 seconds). Excess traffic returns HTTP 429 with Retry-After; limit and window can be customized through filters.

06 / 06

Developer-focused administration & maintainability

The plugin includes its own operating interface and is structured for future development.

Four focused administration screens

Dashboard, Endpoints, API Keys, and Settings divide system visibility, integration documentation, credential operations, and write policies into separate areas.

Practical API client management

Admins can create clients, assign searchable multi-select scopes with Select2, set expiration dates, view usage timestamps, paginate client records, and update, disable, re-enable, or revoke active credentials.

Admin authorization and request integrity

Management routes require manage_options; sensitive form submissions use WordPress nonces, with submitted scopes intersected against the available scope registry.

Screen-specific asset loading

Administrative CSS loads only on the plugin’s pages, while the searchable scope selector’s JS and CSS are loaded only where the API client manager needs them.

Decoupled service construction

A lightweight service container and singleton boot process assemble discovery, repositories, authentication, permissions, resource providers, API handlers, and administration concerns.

Controlled lifecycle cleanup

The plugin installs and version-checks its dedicated table and settings, and its uninstall routine removes plugin-owned options and the client table.

Example integration routes
GET   /wp-json/condixia/v1/resources
GET   /wp-json/condixia/v1/resources/posts?per_page=20&fields=id,title,slug
POST  /wp-json/condixia/v1/resources/posts
PATCH /wp-json/condixia/v1/resources/posts/123
GET   /wp-json/condixia/v1/resources/products
GET   /wp-json/condixia/v1/resources/orders

Built as infrastructure, not a simple endpoint wrapper.

Condixia REST Gateway combines a dedicated credential database, authorization policies, schema-backed content operations, reusable provider architecture, and WooCommerce-compatible adapters into one controlled integration layer. The result is a codebase designed for carefully scoped third-party access and future extension.

WordPress REST APIPHPMySQL / dbDeltaWooCommerce CRUDHPOS-awareBearer AuthenticationWP Hooks

HAVE A PROJECT IN MIND?

Let's turn “can we do this?”
into “here's the plan.”

Start with a quick, no-obligation project conversation. Tell us what you're trying to solve.

Start the conversation ↗