Magento 1.9 – How to Create and Retrieve Default Billing Address Programmatically

billing-addressce-1.9.0.1customer-addressmagento-1.9

Our site imports customers from external data sources. Part of this import is creating a default billing address from external data if none exists.

I have followed advice from other questions, as wells as tutorials, all of which seem to say the same thing for creating/saving a default billing address.
This seems to work at least partially.

// $c is the customer
$data_source  = array(
    'street'   => '',
    'city'     => '',
    'postcode' => '',
);

$a = $c->getPrimaryBillingAddress();

// Create a new default billing if none found
if (!$a)
{
  $a = Mage::getModel("customer/address");
  $a->setCustomerId($c->getId())
    ->setIsDefaultBilling('1')
    ->setSaveInAddressBook('1');
}

foreach ($data_source as $k => $d) $a->setData($k, $d);

$a->save();

After this code has been run, the address is visible on the customer's page in the backend and is marked as the default billing.

However, the following time data is fetched from our external source and the code is run,
the address that was saved is not retrieved (getPrimaryBillingAddress returns false).
This results in a new address being created every time this code is run.

The exception is when a customer has a default billing address set by magento.
In this case, getPrimaryBillingAddress correctly finds the address and the address data is updated and saved.

How can I programatically create a default billing address in such a way that I can retrieve it with $customer->getPrimaryBillingAddress()?

UPDATE

After receiving a possible answer, I have adjusted to code to set customer's default_billing.
The main problem persists with the changes.

$a = $c->getPrimaryBillingAddress();

// Create a new default billing if none found
if (!$a)
{
  $a = Mage::getModel("customer/address");
  $a->setCustomerId($c->getId())            // <-- variations of customer/customerID 
    ->setCustomer($c)                       //     don't seem to affect
    ->setIsDefaultBilling('1')
    ->setSaveInAddressBook('1')
    ->save();                               // <--- SAVE SO WE CAN ACCESS ID

  $c->addAddress($a)                        // <--|
    ->setDefaultBilling($a->getId())        // <--+ SAVE default_billing IN CUSTOMER
    ->save();                               // <--|

}

foreach ($data_source as $k => $d) $a->setData($k, $d);

$a->save();

// ---------------- SUBSEQUENT RUNS --------------

$c->getDefaultBilling();                    // null
$c->getPrimaryBillingAddress();             // false

References

Variations on this method for creating/setting a customer default address were found at these locations:

Best Answer

You need to set it the other way around. The default_billing for the customer.

$customerId = 1234; // Customer id
$data = array(); // Address data

$customer = Mage::getModel('customer/customer');

// Load customer
$customer->load($customerId);

// Get current address
$address = $customer->getPrimaryBillingAddress();

// Do we add a new address
$isNewAddress = false;
if (!$address) {
    $address = Mage::getModel('customer/address');

    $address->setCustomer($customer);
    $isNewAddress = true;
}

// Append data
$address->addData($data);
$address->save();

if ($isNewAddress) {
    // Add address to customer and save
    $customer->addAddress($address)
        ->setDefaultBilling($address->getId())
        ->save();
}
Related Topic