How to Sync WooCommerce Products Between Sites

In this tutorial you will find two ways how you can use WooCommerce API to perform the product sync with multiple WooCommerce stores.

  1. Updating a product with the same SKU on another WooCommerce store automatically when it has been edited by a shop manager on the “Main store”. You can decide whether you would like to update a specific product data or all product data. And it is what we are going to do in this tutorial with code or with my WooCommerce product sync plugin.
  2. Updating product stock statuses and quantities on other WooCommerce stores not only when this product has been updated by shop managers but also when the product has been purchased (and its quantity was descreased, obviously). We are going to talk a little bit about it in this tutorial as well, but I recommend you to take a look at my another plugin which is intended to help you with that.

In case you decided to sync products between sites with the help of my plugin, a metabox “Publish on” will appear on your product pages in WordPress admin, just like this:

WooCommerce API product sync with multiple stores
This is how my WooCommerce product sync plugin works but you can also use the code option from this tutorial.

Using WooCommerce REST API to Sync Products Between Sites

1. Prepare stores authentication data

I assume you would like to perform the product sync with multiple stores (not only with a single one), so for each of them we have to prepare a set of data:

I am going to use an array for that.

// an array of multiple WooCommerce stores you would like to sync products between
$stores = array(
	// store 1
	array(
		'url' => '', // store URL goes here with https://
		'login' => '',
		'pwd' => '',
	),
	// store 2
	array(
		'url' => '',
		'login' => '',
		'pwd' => '',
	),
	// store 3 etc
);

It is fully up to you how you would like to process and store this data, but we are going to use $stores array in the next chapter of this tutorial.

2. Sync products between sites using REST API

In this chapter we are going to create multiple WooCommerce REST API requests in order to sync (publish or update) a product on connected stores automatically when it is published or updated on the main store.

class Misha_Sync_Woo_Products {

	public function __construct() {

		add_action( 'save_post_product', array( $this, 'sync' ), 99, 2 );

	}

	public function sync( $product_id, $post ) {

		// do nothing if WooCommerce is not installed
		if( ! function_exists( 'wc_get_product' ) ) {
			return;
		}

		// get product object
		$product = wc_get_product( $product_id );

		// do the sync for published products only
		if( 'publish' !== $product->get_status() ) {
			return;
		}

		// do the product sync with multiple WooCommerce stores from this array
		$stores = array( ... );

		// prepare product data before the loop
		$product_data = $product->get_data();
		// Fix: "Error 400. Bad Request. Cannot create existing product."
		unset( $product_data[ 'id' ] );
		// Fix: "Error 400 Bad Request low_stock_amount is not of type integer,null." error
		$product_data[ 'low_stock_amount' ] = (int) $product_data[ 'low_stock_amount' ];
		// In order to sync a product image we have to do some additional stuff
		if( $product_data[ 'image_id' ] ) {
			$product_data[ 'images' ] = array(
				array(
					'src' => wp_get_attachment_url( $product_data[ 'image_id' ] )
				)
			);
			unset( $product_data[ 'image_id' ] );
		}

		// let's loop through multiple stores and sync the product with each of them
		foreach( $stores as $store ) {

			$endpoint = "{$store[ 'url' ]}/wp-json/wc/v3/products";
			$method = 'POST';

			// let's check if the product with the same SKU already exists
			if( $product_id_2 = $this->product_exists( $product, $store ) ) {
				$endpoint = "{$endpoint}/{$product_id_2}";
				$method = 'PUT';
			}

			// WooCommerce API product sync request
			wp_remote_request(
				$endpoint,
				array(
					'method' => $method,
					'headers' => array(
						'Authorization' => 'Basic ' . base64_encode( "{$store[ 'login' ]}:{$store[ 'pwd' ]}" )
					),
					'body' => $product_data
				)
			);

		}

	}

	private function product_exists( $product, $store ) {

		$sku = $product->get_sku();

		$request = wp_remote_get(
			add_query_arg( 'sku', $sku, "{$store[ 'url' ]}/wp-json/wc/v3/products" ),
			array(
				'headers' => array(
					'Authorization' => 'Basic ' . base64_encode( "{$store[ 'login' ]}:{$store[ 'pwd' ]}" )
				)
			)
		);

		if( 'OK' === wp_remote_retrieve_response_message( $request ) ) {
			$products = json_decode( wp_remote_retrieve_body( $request ) );
			if( $products ) {
				$product = reset( $products );
				return $product->id;
			}
		}

		return false;

	}

}

new Misha_Sync_Woo_Products;

Please keep in mind the following:

  • Line 5. We have a choice to use either save_post or save_post_{post type} hook, I recommend the second one because it allows us to skip one more conditional statement.
  • Line 25. $stores = array( … ) that’s what we did in the previous step. You have to provide application passwords here.
  • Line 28. $product->get_data() is an amazing method of WC_Product class that allows to get all the product information and pass it almost without changes into a REST API request.
  • Lines 34-41. More about sending API requests with product images you can find in this tutorial or take a look at the plugin solution.
  • Lines 49-53. I am pretty sure you don’t want product duplicates to be created on other stores every time you hit “Update” button, so I created a method product_exists() that performs one more REST API request in order to check whether a product with the same SKU already exists or not. But it is also possible to do with product meta data (and faster).

WooCommerce Product Sync Plugin

If the above code doesn’t fit your needs, you can configure the product sync with the help of my Simple WordPress Crossposting plugin.

Example of WooCommerce API product sync with multiple stores using my plugin.

Some of the plugin features:

  • Product images and product gallery images are fully supported.
  • Easily add stores to sync products with in plugin settings.
  • Sync not only simple but also variable products with their variations.
  • Sync meta fields (ACF etc).
  • Exclude specific product data from the syncronisation (e.g. product stock information).

Please let me know in comments if you have any questions about the code or about my plugin.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X