Saltar al contenido principal

WooCommerce Integration — Technical Reference

026-ecommerce-integration — WooCommerce Adapter

FieldDetail
Module026-ecommerce-integration
AdapterWoocommerceAdapter
PortEcommerceProviderPort
API Versionwc/v3
DateMarch 28, 2026

The Biggest Difference from Shopify: No OAuth

This is the most important thing to internalize upfront. WooCommerce does not have an OAuth flow. Authentication is done via pre-generated API keys — a Consumer Key and Consumer Secret — which the client generates through their WordPress admin under WooCommerce → Settings → Advanced → REST API.

This means the connection UX in the PWA will be different: instead of a "Connect" button that redirects to an authorization screen, you need a form where the client pastes their store URL, Consumer Key, and Consumer Secret.


API

The current WooCommerce REST API version is wc/v3. Base URL structure:

https://client-store.com/wp-json/wc/v3/products
https://client-store.com/wp-json/wc/v3/orders
https://client-store.com/wp-json/wc/v3/products/{id}/stock

Authentication over HTTPS uses the Consumer Key as username and Consumer Secret as password via HTTP Basic Auth — this is the simplest and most secure method. Over plain HTTP, OAuth 1.0a is required, but HTTPS should always be required from clients.

⚠️ Prerequisite that will trip clients up: WordPress pretty permalinks must be enabled. Default permalinks will not work with the REST API. This must be in the client onboarding checklist.


Webhooks

Webhooks are configured under WooCommerce → Settings → Advanced → Webhooks. The first time a webhook is saved with Active status, WooCommerce sends a ping to the delivery URL to verify it is reachable.

Each webhook request includes a X-WC-Webhook-Signature header — a base64-encoded HMAC-SHA256 hash of the payload — which the handler uses to verify authenticity. This is equivalent to Shopify's X-Shopify-Hmac-SHA256, so the verification pattern in the adapter is identical.

Topics needed for v1

WooCommerce TopicShopify Equivalent
order.createdorders/create
product.updated
product.stock_updatedinventory_levels/update

⚠️ Retry behavior: WooCommerce disables webhooks automatically after 5 failed delivery retries. Unlike Shopify which retries for 48 hours, WooCommerce stops much sooner. The sync log and BullMQ polling fallback are even more critical here than with Shopify.


Key Differences vs. Shopify

ShopifyWooCommerce
Auth flowOAuth (redirect)Manual key entry (form)
Connection setupAutomatedClient must generate keys manually
Rate limits2–4 req/sec (enforced)Depends on client's hosting — no hard platform limit
Webhook retries19 retries over 48 hours5 retries, then disabled
API stabilityVersioned, quarterly deprecationsTied to WordPress/WooCommerce version — clients may run old versions
Store URLmyshop.myshopify.com (predictable)Any custom domain
HostingShopify-managedSelf-hosted — server config varies widely

The Hosting Wildcard: Biggest Operational Risk

With Shopify, every store runs on Shopify's infrastructure. With WooCommerce, clients are self-hosted — some on cheap shared hosting, some on managed WordPress, some on their own VPS. This introduces risks that cannot be controlled from the adapter side:

  • FastCGI configurations may not pass Authorization headers correctly. In that case, credentials need to be passed as query string parameters instead of the Authorization header.
  • ModSecurity (a common server security module) can block POST and PUT requests, causing silent failures on product pushes.
  • Outdated WooCommerce versions may not have wc/v3 available. Clients running WooCommerce below 3.5 need to update first.
  • Cheap shared hosting providers sometimes throttle outbound webhook delivery, causing delays in order ingestion.

The adapter needs to be defensive: good error messages, a connection test on setup, and detailed sync log entries that surface exactly what failed and why.


Credentials Storage

Unlike Shopify, there is no global app-level secret. Credentials are per-client store and live in the ecommerce_connection table alongside the shop URL. No new Doppler entries are needed — the Consumer Key and Consumer Secret are stored encrypted in the existing connection record, the same way Shopify access tokens are stored.


Webhook Registration — Automate It

The WooCommerce REST API exposes a /webhooks endpoint. Rather than asking clients to manually create webhooks in their WordPress admin, the adapter should register them programmatically immediately after the client saves their credentials. This removes step 6 from the client setup flow entirely and is worth building into v1.


Client Setup Flow

This is more involved than Shopify's 2-minute OAuth flow. Walk clients through it during onboarding.

  1. In WordPress admin: WooCommerce → Settings → Advanced → REST API → Add Key
  2. Set permissions to Read/Write
  3. Copy the Consumer Key and Consumer Secret — they are only shown once
  4. In FlowPOS PWA → Integraciones → Connect WooCommerce
  5. Enter the store URL, Consumer Key, and Consumer Secret
  6. FlowPOS registers the required webhooks automatically via the API

Steps 1–3 require the client to be in their WordPress admin. Steps 4–6 happen entirely inside FlowPOS.


Webhook Signature Verification

The verification logic is identical to Shopify's — only the header name differs:

// Shopify uses: X-Shopify-Hmac-SHA256
// WooCommerce uses: X-WC-Webhook-Signature

import * as crypto from 'crypto';

function verifyWooCommerceWebhook(
payload: Buffer,
signature: string,
secret: string
): boolean {
const hash = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('base64');
return hash === signature;
}

Adapter Implementation Notes

Following the existing EcommerceProviderPort contract, the WoocommerceAdapter maps to wc/v3 endpoints as follows:

Port MethodWooCommerce Endpoint
getAuthorizationUrl()N/A — replaced by credential form in PWA
exchangeCodeForToken()N/A — replaced by credential validation on save
revokeConnection()Delete registered webhooks via DELETE /wc/v3/webhooks/{id}
pushProduct()POST /wc/v3/products or PUT /wc/v3/products/{id}
updateInventoryLevel()PUT /wc/v3/products/{id} (stock quantity field)
pullOrders()GET /wc/v3/orders?after={since}&status=processing
acknowledgeOrder()PUT /wc/v3/orders/{id} → set status to on-hold or processing

Note: The getAuthorizationUrl and exchangeCodeForToken methods defined in the port are OAuth-specific. For WooCommerce, implement them as no-ops or throw a ProviderNotSupportedOperation exception, and handle the credential-based connection flow at the application service layer with a provider-aware branch.


Speckit Command (WooCommerce Adapter)

/speckit.specify Add WooCommerceAdapter to the existing ecommerce integration module (026). Implements EcommerceProviderPort using WooCommerce REST API wc/v3 with Basic Auth (Consumer Key + Consumer Secret). Connection flow is credential-based (no OAuth) — client enters store URL and keys in PWA form. Adapter programmatically registers required webhooks via the WooCommerce REST API on connect, and removes them on disconnect. Covers product push, inventory level sync, order pull, and HMAC-SHA256 webhook verification. Must handle self-hosted environment variability: FastCGI auth header fallback, outdated API version detection, and connection test on credential save. Zero changes to domain layer or application service — only a new infrastructure adapter and a WooCommerce branch in EcommerceProviderFactory.