I currently have WSDL caching enabled in the store to improve client API performance. However, is there a danger to it. If I change some aspect of the store that affects the WSDL, is the client going to be continuing using the wrong WSDL file or will he/get get an updated one?
Magento – Dangers of caching WSDL file
magento-1.9soap-api-v2wsdl
Related Solutions
Apparently I fell prey to a common Magento pitfall, so I'm posting the answer in case anyone else is searching this particular error. Basically, the error was coming from the Magento installation I was trying to call via the SOAP API.
Initially I thought the error was generated by the client being unable to locate this definitions result, however the real situation is as follows.
- The Magento installation which is acting as a SOAP server makes some SOAP client calls to itself.
- These calls lookup the same domain you are accessing in your client script, but originate from the sever on which that domain is hosted and loopback to said server.
- Therefor, you need to check your host file, usually at /etc/hosts for Linux distros and try to append
Your.IP.Address.Here Your.Magento.Domain
(i,e70.0.0.2 magentohost.com
) - Ensure that
iptables
allows loopback connections, especially if you try to run localhost instead of your external IP; but most likely you'll need to use the external IP address.
That's it; once I edited the file: /etc/hosts
and added this one line, everything worked fine.
If anyone has clearer insight or a generally better answer - please feel free to post and it will most likely be accepted over this answer.
I think the best approach would be to implement your own API method based on existing customer and address methods. You'll have to create a custom module.
Module structure:
-Foo/
--Bar/
---etc/
----api.xml
----config.xml
----wsdl.xml
---Model/
----Customer/
-----Api/
------V2.php
-----Api.php
etc/api.xml
<?xml version="1.0"?>
<config>
<api>
<resources>
<foo_bar translate="title" module="foo_bar">
<model>foo_bar/customer_api</model>
<title>Customer API</title>
<acl>foo_bar</acl>
<methods>
<create translate="title" module="foo_bar">
<title>Create customer</title>
<acl>foo_bar/create</acl>
</create>
</methods>
<faults module="foo_bar">
<data_invalid>
<code>100</code>
<message>Invalid customer data. Details in error message.</message>
</data_invalid>
</faults>
</foo_bar>
</resources>
<v2>
<resources_function_prefix>
<foo_bar>fooBar</foo_bar>
</resources_function_prefix>
</v2>
<acl>
<resources>
<foo_bar translate="title" module="foo_bar">
<title>Foo Bar</title>
<sort_order>3</sort_order>
<create translate="title" module="foo_bar">
<title>Create</title>
</create>
</foo_bar>
</resources>
</acl>
</api>
</config>
etc/wsdl.xml
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
<complexType name="fooBarCreateCustomerData">
<all>
<element name="customer_id" type="xsd:int" minOccurs="0" />
<element name="email" type="xsd:string" minOccurs="0" />
<element name="firstname" type="xsd:string" minOccurs="0" />
<element name="lastname" type="xsd:string" minOccurs="0" />
<element name="middlename" type="xsd:string" minOccurs="0" />
<element name="password" type="xsd:string" minOccurs="0" />
<element name="website_id" type="xsd:int" minOccurs="0" />
<element name="store_id" type="xsd:int" minOccurs="0" />
<element name="group_id" type="xsd:int" minOccurs="0" />
<element name="prefix" type="xsd:string" minOccurs="0" />
<element name="suffix" type="xsd:string" minOccurs="0" />
<element name="dob" type="xsd:string" minOccurs="0" />
<element name="taxvat" type="xsd:string" minOccurs="0" />
<element name="gender" type="xsd:int" minOccurs="0" />
</all>
</complexType>
<complexType name="fooBarCreateAddressData">
<all>
<element name="city" type="xsd:string" minOccurs="0" />
<element name="company" type="xsd:string" minOccurs="0" />
<element name="country_id" type="xsd:string" minOccurs="0" />
<element name="fax" type="xsd:string" minOccurs="0" />
<element name="firstname" type="xsd:string" minOccurs="0" />
<element name="lastname" type="xsd:string" minOccurs="0" />
<element name="middlename" type="xsd:string" minOccurs="0" />
<element name="postcode" type="xsd:string" minOccurs="0" />
<element name="prefix" type="xsd:string" minOccurs="0" />
<element name="region_id" type="xsd:int" minOccurs="0" />
<element name="region" type="xsd:string" minOccurs="0" />
<element name="street" type="typens:ArrayOfString" minOccurs="0" />
<element name="suffix" type="xsd:string" minOccurs="0" />
<element name="telephone" type="xsd:string" minOccurs="0" />
<element name="is_default_billing" type="xsd:boolean" minOccurs="0" />
<element name="is_default_shipping" type="xsd:boolean" minOccurs="0" />
</all>
</complexType>
</schema>
</types>
<message name="fooBarCreateRequest">
<part name="sessionId" type="xsd:string" />
<part name="customerData" type="typens:fooBarCreateCustomerData" />
<part name="addressData" type="typens:fooBarCreateAddressData" />
</message>
<message name="fooBarCreateResponse">
<part name="result" type="xsd:int" />
</message>
<portType name="{{var wsdl.handler}}PortType">
<operation name="fooBarCreate">
<documentation>Create customer</documentation>
<input message="typens:fooBarCreateRequest" />
<output message="typens:fooBarCreateResponse" />
</operation>
</portType>
<binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="fooBarCreate">
<soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
<input>
<soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
</binding>
</definitions>
Model/Customer/Api.php
<?php
class Foo_Bar_Model_Customer_Api extends Mage_Customer_Model_Customer_Api
{
public function create($customerData, $addressData)
{
$customer = Mage::getModel('customer/customer');
Mage::log($customerData, null, 'customerData.log', true);
try {
$customer->setData($this->_prepareData($customerData));
$address = Mage::getModel('customer/address');
foreach ($this->getAllowedAttributes($address) as $attributeCode=>$attribute) {
if (isset($addressData->$attributeCode)) {
$address->setData($attributeCode, $addressData->$attributeCode);
}
}
if (isset($addressData->is_default_billing)) {
$address->setIsDefaultBilling($addressData->is_default_billing);
}
if (isset($addressData->is_default_shipping)) {
$address->setIsDefaultShipping($addressData->is_default_shipping);
}
$customer->addAddress($address)
->save();
} catch (Mage_Core_Exception $e) {
$this->_fault('data_invalid', $e->getMessage());
}
return $customer->getId();
}
}
Model/Customer/Api/V2.php
<?php
class Foo_Bar_Model_Customer_Api_V2 extends Foo_Bar_Model_Customer_Api
{
protected function _prepareData($data)
{
if (null !== ($_data = get_object_vars($data))) {
return parent::_prepareData($_data);
}
return array();
}
}
And that's it. Code could use some minor tuning but it works. I did not include etc/config.xml
as it's already a long answer and you can easily figure it out on your own.
And finally the sample API call:
<?php
$client = new SoapClient('http://magento.local/api/v2_soap?wsdl=1');
$customer = array(
'email' => 'apicustomer@example.com',
'firstname' => 'Firstname',
'lastname' => 'Lastname',
'password' => 'password',
'website_id' => 1,
'store_id' => 1,
'group_id' => 1,
);
$address = array(
'firstname' => 'Firstname',
'lastname' => 'Lastname',
'create_address' => true,
'city' => 'City',
'company' => 'Company',
'country_id' => 'US',
'region_id' => 12,
'postcode' => '90210',
'street' => array('Street Line 1', 'Street Line 2'),
'telephone' => '1234567890',
'is_default_billing' => true,
'is_default_shipping' => true
);
try {
$session = $client->login('apiuser', 'apipassword');
$result = $client->fooBarCreate($session, $customer, $address);
} catch (SoapFault $fault) {
echo $fault->getMessage();
}
Best Answer
Typically you just need to log into the Magento store and flush the caches. That is by far the easiest method to ensure the latest changes are used. The cache wsdl will be a problem if you do not remember to flush the proper caches.