Home>Blog>How I Built a WooCommerce Store with 3 Custom API Integrations
WooCommerce
9 min read

How I Built a WooCommerce Store with 3 Custom API Integrations

August 15, 2026
·By Haris Maqsood

    The Project Brief

    Patio Life is a UK-based outdoor living retailer that sells products from multiple suppliers including garden furniture, outdoor heating, and accessories. When I took on the project, the team was manually exporting CSV files from three suppliers every morning and importing them into WooCommerce. This process took roughly two hours daily and was prone to errors.

    The goal was simple: automate the entire product catalog sync so the WooCommerce store is always up to date, without any manual intervention.

    The three integrations were:

    Gardeco, a garden furniture and outdoor decor supplier with a REST API returning JSON.

    Beefeater, an outdoor heating brand with an XML-based product feed.

    Norfolk Brandfolder, a digital asset platform that manages product imagery for multiple brands.

    Architecture Decisions Before Writing a Single Line

    Before touching any code, I spent time mapping out the data flow and deciding where each integration would live.

    I built each integration as a separate custom WordPress plugin rather than one monolithic plugin. This has a few advantages: each integration can be activated or deactivated independently, debugging is simpler because you isolate the failure point, and future developers can understand each piece without needing to read everything at once.

    All three plugins share a common base class that handles logging, error notifications, and the WooCommerce product update logic. This prevents code duplication and means improvements to the update mechanism apply to all three integrations at once.

    Integration One: The Gardeco REST API

    Gardeco provides a straightforward REST API with token-based authentication. Products are returned as a JSON array with fields for SKU, name, description, price, stock quantity, and image URLs.

    The sync process works like this:

    First, I fetch the full product list from the Gardeco API. Then, for each product, I check whether it already exists in WooCommerce by searching for the SKU. If it exists, I update the price, stock quantity, and any changed metadata. If it does not exist, I create a new WooCommerce product. Finally, any WooCommerce products that are no longer in the Gardeco feed are marked as out of stock rather than deleted, to preserve order history.

    The tricky part was handling product images. Gardeco returns image URLs hosted on their CDN. I wrote a function that downloads each image, uploads it to the WordPress media library, and attaches it to the product only if the image has actually changed. This avoids re-downloading hundreds of images on every sync run.

    php
    function maybe_update_product_image( $product_id, $remote_url ) {
        $existing_url = get_post_meta( $product_id, '_gardeco_image_url', true );
        if ( $existing_url === $remote_url ) {
            return; // Image has not changed, skip
        }
        $attachment_id = upload_image_from_url( $remote_url );
        if ( $attachment_id ) {
            set_post_thumbnail( $product_id, $attachment_id );
            update_post_meta( $product_id, '_gardeco_image_url', $remote_url );
        }
    }

    Integration Two: The Beefeater XML Feed

    Beefeater does not have a modern REST API. They provide a URL that returns an XML product feed, similar to a sitemap. PHP's built-in SimpleXML extension handles parsing this cleanly.

    The challenge with the Beefeater integration was data mapping. Their XML structure uses different field names than what WooCommerce expects, and some fields like dimensions are embedded in a product description string rather than structured fields.

    I wrote a parser class that maps Beefeater's XML structure to a normalized array format that matches what my shared base class expects. This means the base class handles all WooCommerce updates identically regardless of the source.

    One specific issue: Beefeater's feed sometimes includes products marked as discontinued but still present in the feed. I handle this by checking a custom status field in the XML and setting those products to draft in WooCommerce rather than keeping them published.

    Integration Three: The Norfolk Brandfolder Asset API

    Brandfolder is a digital asset management platform. Norfolk uses it to store and organize all product imagery across multiple brands. The Brandfolder API returns assets tagged by product SKU, which I use to match images to the correct WooCommerce products.

    This integration runs on a different schedule than the product sync. Product data changes maybe once a week, but imagery can be updated more frequently as brands refresh their photography. I run the Brandfolder sync independently, twice daily.

    The key challenge here was rate limiting. Brandfolder's API has request limits per minute. I implemented a simple throttle using transients:

    php
    function fetch_with_throttle( $endpoint ) {
        $transient_key = 'brandfolder_last_request';
        $last = get_transient( $transient_key );
        if ( $last ) {
            usleep( 250000 ); // Wait 250ms between requests
        }
        set_transient( $transient_key, time(), 5 );
        return wp_remote_get( $endpoint, [ 'headers' => $this->get_auth_headers() ] );
    }

    Scheduling and Monitoring

    All three integrations run on WP-Cron schedules. Gardeco syncs every two hours. Beefeater runs nightly since their catalog updates less frequently. Brandfolder runs twice daily.

    Each sync run writes a log entry to a custom database table that records how many products were updated, created, or skipped, how long the sync took, and whether any errors occurred. I built a simple admin page that shows the last 30 sync results for each integration, so the client can see at a glance that everything is working.

    I also added email alerts: if a sync fails three consecutive times, the client receives an email with the error details.

    Results

    Before the integrations were built, the team spent two hours every morning on manual imports. After deployment, the WooCommerce catalog updates automatically throughout the day without any manual work.

    Product accuracy improved significantly because manual CSV imports occasionally produced price or stock errors. Those errors stopped entirely.

    The client can now add a new product by simply adding it in the supplier's system. Within two hours, it appears on the WooCommerce store with the correct price, description, and imagery.


    Need a similar WooCommerce integration for your store? I build custom API integrations that keep your catalog accurate and your team focused on selling rather than data management. Get in touch.

H

Haris Maqsood

Senior Full Stack Web Developer

WordPress Developer for Hire with 6+ years of experience. Specialising in custom plugins, WooCommerce, Laravel APIs, and React for clients in the 20+ countries worldwide.

Chat on WhatsAppGet a Free Quote
← View All Posts