Magento – Help connecting Magento to a third-party REST API

apigoogle apijavascriptmagento-1.7MySQL

I need to update Magento products using a third party API. What is the best method of doing so. Should I trigger an API call when an event/observer hits on product detail page? There is no OAuth yet, just normal hard coded token.

I see alot of documentation for using MAGENTO's API, but not a third-party API.

Best Answer

first of all you should know working with APIs using PHP, sending requests and parsing responses. And every API has own structure, signature and methods, see your third party API documentation. Using PHP you can call api methods with curl or standard http requests. Here is some tips.
Here is scenario how to update your products data using standard Magento approach:
1. Create custom local module
2. Write your updater model, it uses curl or http request to call to third party api. In this model you should implement all methods which is required to interconnect the api. To optimal develop architecture of your updater you should know how to use your third party api, read its documentation. For example documentation:

a. api url: http://www.some.web.url/api
b. api returns JSON (or XML) compliant data
c. api secure key sends over http header **ApiKey**
c. method **products_list**: `<api_url>/products/list/`
   result:

    {
        "count":2,
        "items":[
            {
                "name":"Product Name",
                "sku":"pn_123",
                "price":10,
                "qty":20,
            },
            {
                "name":"Another Product",
                "sku":"ap_1234",
                "price":14,
                "qty":60,
            }
        ]
    }

d. method **product_detail**: `<api_url>/product/detail/sku/<product_sku>/`
result:

    {
        "name":"Another Product",
        "sku":"ap_1234",
        "price":14,
        "qty":60,
    }

And so on. API documentation gives full scheme of using methods.

Methods of api given above are implemented in the your custom Model:

class Ssd_Interconnect_Model_Updater
{
    const USP = '/';
    private $_url = "http://www.some.web.url/api";

    private $_apiKey = "Some secure api key/token here";
    private $_command;
    private $_subCommand;
    private $_params;

    public function getUrl()
    {
        $url = $this->_url . self::USP . $this->_command . self::USP . $this->_subCommand;
        if (count($this->_params)) {
            foreach ($this->_params as $key=> $value) {
                $url = $url . self::USP . $key . self::USP . $value;
            }
        }
        return $url;
    }


    protected function call()
    {
        if ($curl = curl_init()) {
            $result = false;
            $header = array('Content-Type: text/json', 'ApiKey: ' . $this->_apiKey, 'Accept: application/json');

            curl_setopt($curl, CURLOPT_URL, $this->getUrl());
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
            curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);

            try {
                $response = curl_exec($curl);
                $result   = $this->parseResult($response, $curl);
            } catch (Exception $e) {
                Mage::logException($e);
            }

            return $result;
        }
        return false;
    }

    protected function parseResult($response, &$curl)
    {
        try {
            $info = curl_getinfo($curl);
            $code = $info['http_code'];
            switch ($code) {
                case 401:
                    throw new Exception('The API Key was missing or invalid');
                    break;
                case 500:
                    throw new Exception('An unhandled exception occured on the server');
                    break;
            }
            $data = Mage::helper('core')->jsonDecode($response);
            if (isset($data['ErrorCode'])) {
                throw new Exception($data['Message'], $data['ErrorCode']);
            }
            return $data;
        } catch (Exception $e) {
            $this->_errorCode    = $e->getCode();
            $this->_errorMessage = $e->getMessage();
        }
        curl_close($curl);
        return false;
    }

    public function getProductList()
    {
        $this->_command    = 'products';
        $this->_subCommand = 'list';
        return $this->call();
    }

    public function getProductDetail($product)
    {
        $this->_command    = 'product';
        $this->_subCommand = 'detail';
        $this->_params     = array('sku'=> $product->getSku());
        return $this->call();
    }

    public function updateProducts()
    {
        $apiProducts = $this->getProductList();
        if ($apiProducts && isset($apiProducts['items'])) {
            foreach ($apiProducts['items'] as $p) {
                if ($product = Mage::getModel('catalog/product')->loadBySku($p['sku'])) {
                    $product->setPrice($p['price'])->setName($p['name']);
                    $qty = $p['qty'];
                    $product->setStockData(array(
                        'is_in_stock' => $qty > 0,
                        'qty'         => $qty
                    ));
                    try {
                        $product->save();
                    } catch (Exception $e) {
                        //some error handler logic here
                    }
                }
            }
        }
    }
}

And finally you should schedule some cronjob to update products every x time in your config.xml:

    <crontab>
        <jobs>
            <ssd_interconnect_customjobs_15m>
                <schedule>
                    <cron_expr>*/15 * * * *</cron_expr>
                </schedule>
                <run>
                    <model>interconnect/updater::updateProducts</model>
                </run>
            </ssd_interconnect_customjobs_15m>
        </jobs>
    </crontab>

P.S I didn't test the code given above, I try to describe how to using API to update products. Thanks.

Related Topic