1

Due to business and technical requirements, all customers must have an associated billing address when they're first created. We've got this working great on the frontend and backend; however, there's currently no way to pass the address via the customerCustomerCreate v2 SOAP method.

Is it possible to somehow extend this method to accept the following billing address fields?

  • Street
  • City
  • State
  • Zip
  • Country

If so:

  1. How would I add these to the WSDL?
  2. How would I convert the submitted API data into an associated address? Is there some event I could observe?

Thanks!

4 Answers 4

2
+50

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.xmlas 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'             => '[email protected]',
    '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();
}
0

Take a look at Creating a Custom API or Extending the Core API

Then create you own api that create a customer/assign address

Example

public function create($customerData)
{
    try {
        $customer = Mage::getModel('customer/customer')
            ->setData($customerData)
            ->save();

           //get info below from $customerData
           $address = Mage::getModel("customer/address");
           $address->setCustomerId($customer->getId())
           ->setFirstname($customer->getFirstname())
           ->setMiddleName($customer->getMiddlename())
           ->setLastname($customer->getLastname())
           ->setCountryId('HR')
           //->setRegionId('1') //state/province, only needed if the country is USA
           ->setPostcode('31000')
           ->setCity('Osijek')
           ->setTelephone('0038511223344')
           ->setFax('0038511223355')
           ->setCompany('Inchoo')
           ->setStreet('Kersov')
           ->setIsDefaultBilling('1')
           ->setIsDefaultShipping('1')
           ->setSaveInAddressBook('1');
           $address->save();

    } catch (Mage_Core_Exception $e) {
        $this->_fault('data_invalid', $e->getMessage());
        // We cannot know all the possible exceptions,
        // so let's try to catch the ones that extend Mage_Core_Exception
    } catch (Exception $e) {
        $this->_fault('data_invalid', $e->getMessage());
    }
    return $customer->getId();
}
0

You need to create your own API custom method link and create customer and its address in single function, What I did some time back is create a method which create customer for social media plugins of mobile apps, if user login with facebook id first time create a customer else if login id already exists in system send authentication token and value as true(valid user)

Below is function to create customer and also create address for that matters..

public function createCustomer($email,$socialconnectid,$firstname,$lastname,$customerAddress)
        {
            $websiteId = "1"; //Mage::app()->getWebsite()->getId();
            Mage::app()->setCurrentStore(1);
            $store =  Mage::app()->getStore();

            //$store = $this->_getStore($websiteId);



            $customer = Mage::getModel("customer/customer");
            $customer->setWebsiteId($websiteId)
            ->setStore($store)
            ->setFirstname($firstname)
            ->setLastname($lastname)
            ->setEmail($emailAddress)
            ->setPassword('somepassword');

                try{
                    $customer->save();
                    $customer->getId(); 
                    //get info below from $customerData
       $address = Mage::getModel("customer/address");
       $address->setCustomerId($customer->getId())
       ->setFirstname($customer->getFirstname())
       ->setMiddleName($customer->getMiddlename())
       ->setLastname($customer->getLastname())
       ->setCountryId('IN')
       ->setPostcode('380009')
       ->setCity('ADI')
       ->setTelephone('1234566512')
       ->setCompany('EM')
       ->setStreet('Park street')
       ->setIsDefaultBilling('1')
       ->setIsDefaultShipping('1')
       ->setSaveInAddressBook('1');
       $address->save();

                }
                catch (Exception $e) {

                    Zend_Debug::dump($e->getMessage());
                    return $e->getMessage();
                }
        }
-2

You can use the customer_address.create feature.

http://www.magentocommerce.com/api/soap/customer/customerAddress/customer_address.create.html

You can get the customer ID from the first API call this way:

$result = $proxy->customerCustomerCreate(...
$customerId = $result->result;

As a note, you can also update, delete and fetch information about customer addresses.

2
  • Unfortunately this won't work because it requires a separate call after the customer is already created. We're looking to perform both actions within the same API call. Commented Feb 3, 2015 at 17:21
  • I am not sure why the down vote? This particularity should be included in your original question... Regarding your last comment, an address can only be created after the customer object is created. Ergo, there has to be two separate requests. You can bind them in a single one, but it involves some major customisation. Commented Feb 3, 2015 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.