Laravel Integration with WooCommerce REST API

Lokendra Lodha
4 min readOct 25, 2020

This tutorial Integrates Laravel & WooCommerce Auto REST API Keys generation flow for REST API integration and demonstrates a sample syncing of products from a WooCommerce store.

This tutorial presents various recipes for 3rd party integration with Laravel such as: Rest API consumption, Open Auth based REST API Keys generation, REST API with Basic Authentication, Calling 3rd part API with Guzzle way, and so on.

The screenshots below captures the logical flow of Laravel web application.

The Laravel and any Client Web application need to perform following changes in order to fetch the product listing from WooCommerce Rest API.

### Required steps:

- Customer should have WooCommerce 3.x plugin installed at their wordpress site.
- And enable the WooCommerce -> REST Integration support via the wordpress backend admin -> for wooCommerce plugin.

### Rest API integration works in 2 steps:

- r.a) Store owner Authorizes the client app to auto obtain the authentication keys/secret:

Reference: Auto generating API keys using our Application Authentication Endpoint

https://woocommerce.github.io/woocommerce-rest-api-docs/#rest-api-keys

On successful completion of the open auth flow the client app receives the API key/secret ,
which is then used for HTTP Basic Authentications for any REST API Calls.

  • r.b) Invoke the REST API for example /v3/products to get the products listing

Laravel Route Recipe — Kickstart the WooCommerce authorization flow as per r.a above:

Here remote_store is the name of woo-commerce endpoint URL: example — 'http://example.com';

Route::get(‘/woo/authorize’, function (Request $request) {
$data = $request->all();

$local_store = $data[‘local_store’];
$remote_store = $data[‘remote_store’];

$store = \App\Store::where([‘local_store’=>$local_store])->first();
if(!$store){
$store = new \App\Store();
}

$store->data = json_encode($data);
$store->local_store = $local_store;
$store->remote_store = $remote_store;
$store->status = ‘100’;
//$store->synced_at = now();
$store->save();

\Illuminate\Support\Facades\Log::debug(‘Store::redirect’,[$store->toArray()]);

$endpoint = ‘/wc-auth/v1/authorize’;
$params = [
‘app_name’ => ‘pasion’,
‘scope’ => ‘read’,
‘user_id’ => $local_store,
‘return_url’ => ‘https://passionindiatours.in/woo/connect/response/'.$local_store,
‘callback_url’ => ‘https://passionindiatours.in/woo/connect/callback/'.$local_store

];
$api = $remote_store.$endpoint.’?’.http_build_query( $params );
\Illuminate\Support\Facades\Log::debug(‘Store::redirect’,[$api]);

return Redirect::away($api);

});

Laravel Recipe — the return URL where the WooCommerce shall redirect the user once they approves or cancels the authorization flow.

Route::any(‘/woo/connect/response/{local_store}’, function ($local_store, Request $request) {

$data = $request->all();

\Illuminate\Support\Facades\Log::debug(‘/woo/connect/response ‘,$data);
$store = \App\Store::where([‘local_store’=>$local_store])->first();

return view(resolveTenant().’/woo_connect_response’
,[‘store’=>$store,’data’=>$data]);
});

Laravel Recipe: The final Callback API that WooCommerce shall invoke — This happens if end user was able to approve and authorize the flow.

This API is called with the response that includes the auth informations such as HTTP Basic Auth key and secrets.

Route::any(‘/woo/connect/callback/{local_store}’, function ($local_store, Request $request) {

$data = $request->all();

\Illuminate\Support\Facades\Log::debug(‘/woo/connect/callback ‘,[$data]);
$store = \App\Store::where([‘local_store’=>$data[‘user_id’]])->first();
if($store){
$store->data = json_encode($data);
$store->local_store = $data[‘user_id’];
$store->status = ‘200’;
$store->synced_at = now();
$store->save();

\Illuminate\Support\Facades\Log::debug(‘Store::connect.callback ‘,

[$store->toArray()]);

}

return [‘s’=>200];
});

Sample HTTP Basic Auth key and secrets and other auth information received as per the callback API:

{
“key_id”: 1,
“user_id”: 123,
“consumer_key”: “ck_xxxxxxxxxxxxxxxx”,
“consumer_secret”: “cs_xxxxxxxxxxxxxxxx”,
“key_permissions”: “read_write”
}

### At Laravel data modelling— 2 models are used:

A Store model — to store the integrated store credentials, local store name, woo store name, last synced date etc

Products model — to store the products listing

Laravel Recipe: REST API invocation with HTTP Basic Authentication

In the sample below We access the WooCommerce products API to fetch the products listing:

public function syncAllProducts($limit=10000){
$data = json_decode($this->data,true);

$client = new \GuzzleHttp\Client();
$options = [
’auth’ => [$data[‘consumer_key’], $data[‘consumer_secret’]],
‘headers’ => [

]];

$url = $this->getRemoteStoreUrl();
$url .= “/wp-json/wc/v3/products?per_page=100&consumer_key=”.$data[‘consumer_key’].”&consumer_secret=”.$data[‘consumer_secret’];

\Illuminate\Support\Facades\Log::debug(‘Store::syncAllProducts’,[‘url’,$url]);
$res = $client->get($url, $options);
$res->getStatusCode(); // 200

\Illuminate\Support\Facades\Log::debug(‘Store::syncAllProducts’
,[‘getStatusCode::’,$res->getStatusCode()]);

if($res->getStatusCode()==200){
$body = $res->getBody();
$products = json_decode($body,true);
return [‘s’=>$res->getStatusCode(), ‘products’=>$products,’body’=>$body, ‘url’=>$url];

}

return [[‘s’=>$res->getStatusCode(), ‘products’=>[]]];
}
}

Finally We can display products on store dashoard page using Laravel blade views:

The example recipe uses jquery datatable to render the tabular view of synced products:

<link href=”//cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css” rel=”stylesheet” >

<h2>Available products</h2>
<table id=”products” class=”display” width=”100%”></table>

<script src=”https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js" ></script>

<script type=”text/javascript”>
$(document).ready(function() {
$(‘#products’).DataTable( {
data: <?php echo json_encode($products);?>,
columns: [
{ data: “name” , title:’Title’},
{ data: “slug” , title:’Slug’},
{ data: “price” ,title:’Price’},
{ data: “description”, title:’Description’ }
]
} );
} );
</script>

--

--