Magento SOAP API

The Magento SOAP API allows the merchant and third parties to manage resources such as customers, categories, products, and sales orders. It also allows you to manage shopping carts and inventory.

Magento provides URLs to view the methods available.

  • SOAP v1 – http://www.yoursite.com/api/soap?wsdl=1
  • SOAP v2 – http://www.yoursite.com/api/v2_soap?wsdl=1

Existing API calls include but are not limited to:

  • catalog_product.list
  • catalog_product.info
  • catalog_product.create
  • catalog_product.update
  • catalog_category.info
  • catalog_category.tree
  • catalog_category.create
  • catalog_category.update
  • customer.list
  • customer.info
  • customer.create
  • customer.update
  • sales_order.list
  • sales_order.info
  • sales_order_invoice.create
  • sales_order_invoice.capture

API credentials must first be set up within the admin area to allow authentication to these resources. This can be done within System -> Web Services -> SOAP/XML-RPC - Users, and add a user.

The user will need to be added against a role, which can be done within System -> Web Services -> SOAP/XML-RPC - Roles, and add a role.

Then, head back into the users and select the role created.

We then then test our API connection by adding the following contents within a test PHP file.

<?php
$apiUrl = 'http://www.yoursite.com/api/soap?wsdl'; 
$apiUser = 'apiuser'; 
$apiKey = '123456'; 

$soap = new SoapClient($apiUrl); 
$sessionId = $soap->login($apiUser, $apiKey);

This should return a session ID should you be authenticated successfully. If you need to view the resource available to the API user, you can add the following and print out the content of the $resources variable.

$resources = $soap->resources($sessionId);

For SOAP v1, we can use the call() method of the SoapClient class, passing in the session ID and a string that contains the resource name and the method name.

The following will give us an array of the product catalog.

$products = $soap->call($sessionId, 'catalog_product.list');
print_r($products);

Where does this catalog_product.list come from and how does Magento return a list of products? If you view the contents of the api.xml file within the Mage_Catalog module, you see a lot of resources defined under a pair of resources nodes. We can actually pinpoint the catalog_product resource and its list method under a pair of method nodes.

<?xml version="1.0"?>
<config>
    <api>
        <resources>
            ....
            <catalog_product translate="title" module="catalog">
            <title>Product API</title>
                <model>catalog/product_api</model>
                <acl>catalog/product</acl>
                <methods>
                    <currentStore translate="title" module="catalog">
                        <title>Set/Get current store view</title>
                    </currentStore>
                    <list translate="title" module="catalog">
                        <title>Retrieve products list by filters</title>
                        <method>items</method>
                        <acl>catalog/product/info</acl>
                    </list>
                    ....
                </methods>
                ....
            </catalog>
        </resources>
        ....
    </api>
</config>

Interestingly, there are also resource aliases that can be defined within this api.xml file within a pair of resources_alias nodes.

<config>
    <api>
        <resources>
            ....
        </resources>
        <resources_alias>
            ....
            <product>catalog_product</product>
            ....
        </resources_alias>
    </api>
</config>

So here the Mage_Catalog module is giving the catalog_product resource a product alias name. So what does this mean? It means that instead of calling:

$soap->call($sessionId, 'catalog_product.list');

We can simply use the below.

$soap->call($sessionId, 'product.list');

As mentioned above, the call() method can be used for Magento SOAP API v1, but there is also a v2. We can use this line of code to get the product list using v2.

$soap->catalogProductList($sessionId);

If using SOAP API v2 calls, ensure that you also change your Magento API URL from http://www.yoursite.com/api/soap?wsdl to http://www.yoursite.com/api/v2_soap?wsdl.

The v2 methods are also defined in the api.xml file of the Mage_Catalog module, as seen under a pair of v2 nodes.

<config>
   <api>
        <resources>
            ....
        </resources>
        <resources_alias>
            ....
        </resources_alias>
        <v2>
            <resources_function_prefix>
                ....
                <product>catalogProduct</product>
                ....
            </resources_function_prefix>
        </v2>
        ....
    </api>
</config>

So we can see that within a pair of resources_function_prefix nodes, our product alias has a catalogProduct resource function prefix name.

This is coupled with our list method name to create catalogProductList.

If you either use SOAP v1 or v2, you’ll end up at the same items method that is defined within the list nodes.

<list translate="title" module="catalog">
    <title>Retrieve products list by filters</title>
    <method>items</method>
    <acl>catalog/product/info</acl>
</list>

The items() method is defined within the Mage_Catalog_Model_Product_Api class, as determined within the pair of model nodes under the catalog_product resource.

<catalog_product translate="title" module="catalog">
    <title>Product API</title>
    <model>catalog/product_api</model>
    ....
</catalog_product>
public function items($filters = null, $store = null)
{
    $collection = Mage::getModel('catalog/product')->getCollection()
         ->addStoreFilter($this->_getStoreId($store))
         ->addAttributeToSelect('name');

    /** @var $apiHelper Mage_Api_Helper_Data */
    $apiHelper = Mage::helper('api');
    $filters = $apiHelper->parseFilters($filters, $this->_filtersMap);
    try {
        foreach ($filters as $field => $value) {
            $collection->addFieldToFilter($field, $value);
        }
    } catch (Mage_Core_Exception $e) {
        $this->_fault('filters_invalid', $e->getMessage());
    }
    $result = array();
    foreach ($collection as $product) {
        $result[] = array(
            'product_id' => $product->getId(),
            'sku'        => $product->getSku(),
            'name'       => $product->getName(),
            'set'        => $product->getAttributeSetId(),
            'type'       => $product->getTypeId(),
            'category_ids' => $product->getCategoryIds(),
            'website_ids'  => $product->getWebsiteIds()
        );
    }
    return $result;
}

So if successful, an array of product data is returned to the user.

You’ll also notice that should the filters not be able to be applied successfully, we can use a $this->_fault() call. Faults are also set up within the api.xml file.

<?xml version="1.0"?>
<config>
    <api>
        <resources>
            ....
            <catalog_product translate="title" module="catalog">
                ....
                <methods>
                    ....
                </methods>
                <faults module="catalog">
                    <store_not_exists>
                        <code>100</code>
                        <message>Requested store view not found.</message>
                    </store_not_exists>
                    ....
                </faults>
                ....
            <catalog_product>
            ....
        </resources>
        ....
    </api>
</config>

Note: This article is based on Magento Community/Open Source version 1.9.