<p>I ran into the same requirement a while ago. Not 100% sure if this is still necessary, but at the time I needed to do it via custom code in a module. It looks like this:</p>
<pre class="lang-php prettyprint-override"><code>use Craft;
use craft\services\Elements;
use craft\commerce\models\Address as AddressModel;
use craft\commerce\records\Customer as CustomerRecord;
use craft\commerce\records\CustomerAddress as CustomerAddressRecord;
use craft\commerce\Plugin as CommercePlugin;
use yii\base\Event;

// --------------------------------------------
// SAVE COMMERCE CUSTOMER ADDRESS AFTER REGISTRATION
// --------------------------------------------

Event::on(
    Elements::class,
    Elements::EVENT_AFTER_SAVE_ELEMENT,
    function(Event $e) {
        // Bail out on console requests
        if (Craft::$app-&gt;request-&gt;isConsoleRequest) { return; }

        // Bail out if it's not a User element being saved
        if (!$e-&gt;element instanceof \craft\elements\User) { return; }

        // Bail out on CP requests
        if (Craft::$app-&gt;request-&gt;isCpRequest) { return; }

        // get the address fields from the POST data...
        $add1 = Craft::$app-&gt;request-&gt;getBodyParam('address');

        $userId = $e-&gt;element-&gt;id;
        $address = new AddressModel();

        $address-&gt;attention = '';
        $address-&gt;title = '';
        $address-&gt;firstName = '';
        $address-&gt;lastName = '';
        $address-&gt;fullName = '';
        $address-&gt;address1 = $add1['address1'];
        $address-&gt;address2 = $add1['address2'];
        $address-&gt;address3 = '';
        $address-&gt;city = $add1['city'];
        $address-&gt;zipCode = $add1['zipCode'];
        $address-&gt;phone = '';
        $address-&gt;alternativePhone = '';
        $address-&gt;label = '';
        $address-&gt;notes = '';
        $address-&gt;businessName = '';
        $address-&gt;businessTaxId = '';
        $address-&gt;businessId = '';
        $address-&gt;countryId = 77;
        $address-&gt;stateName = $add1['stateValue'];
        $address-&gt;custom1 = '';
        $address-&gt;custom2 = '';
        $address-&gt;custom3 = '';
        $address-&gt;custom4 = '';
        $address-&gt;id = 0;

        // Save it
        $addressSaved = CommercePlugin::getInstance()-&gt;getAddresses()-&gt;saveAddress($address);

        // now tie it to a new record in craft_commerce_customers_addresses
        if ($addressSaved) {
            $customer = (new \craft\commerce\services\Customers)-&gt;getCustomerByUserId($userId);

            $customerAddressRecord = new CustomerAddressRecord();
            $customerAddressRecord-&gt;customerId = $customer-&gt;id;
            $customerAddressRecord-&gt;addressId = $address-&gt;id;
            $customerAddressSaved = $customerAddressRecord-&gt;save();

            $customerRecord = CustomerRecord::findOne($customer-&gt;id);
            $customerRecord-&gt;primaryShippingAddressId = $address-&gt;id;
            $customerRecord-&gt;save();
        }        
    }
);
</code></pre>
<p>EDIT TO ADD: now updated this for Craft 4 / Commerce 4 as follows:</p>
<pre class="lang-php prettyprint-override"><code>use Craft;
use craft\services\Elements;
use craft\services\Users;
use yii\base\Event;

...

Event::on(
    Elements::class,
    Elements::EVENT_AFTER_SAVE_ELEMENT,
    function(Event $e) {
        // bail out on console requests
        if (Craft::$app-&gt;request-&gt;isConsoleRequest){ return; }

        // bail out on CP requests
        if (Craft::$app-&gt;request-&gt;isCpRequest) { return; }

        // bail out if this isn't coming from our registration form (this is a hidden field on the registration form)
        if (Craft::$app-&gt;request-&gt;post('saveAddress') != '1'){ return; }

        // bail out if it's not a user element being saved, just to triple check ourselves
        if (!$e-&gt;element instanceof \craft\elements\User){ return; }

        // else continue...
        $add1 = Craft::$app-&gt;request-&gt;getBodyParam('address');

        $address = new Address();

        $address-&gt;ownerId = $e-&gt;element-&gt;id;
        $address-&gt;title = 'Address';
        $address-&gt;fullName = '';
        $address-&gt;addressLine1 = $add1['addressLine1'];
        $address-&gt;addressLine2 = $add1['addressLine2'];
        $address-&gt;locality = $add1['locality'];
        $address-&gt;postalCode = $add1['postalCode'];
        $address-&gt;countryCode = 'GB';
        $address-&gt;administrativeArea = $add1['administrativeArea'];

        // save it
        Craft::$app-&gt;getElements()-&gt;saveElement($address);
    }
);
</code></pre>

CC BY-SA 4.0
2021-12-21T11:37:35.237Z
Thanks James, I've also found a way to do it as below
Mark
CC BY-SA 4.0
2021-12-20T20:09:16.697Z
2024-04-19T16:12:38.647Z
2024-04-19T16:12:38.647Z
James Smith
<p>As well as James answer above, the following should do it:</p>
<pre><code>{% set isPrimaryBilling = cart.customer.primaryBillingAddressId == addressId %}
{% set isPrimaryShipping = cart.customer.primaryShippingAddressId == addressId %}

&lt;label for=&quot;makePrimaryShippingAddress&quot;&gt;
    &lt;input id=&quot;makePrimaryShippingAddress&quot;name=&quot;makePrimaryShippingAddress&quot; type=&quot;checkbox&quot; {{ isPrimaryShipping ? 'checked' :'' }}/&gt;
    &lt;span&gt;Make this the primary shipping address&lt;/span&gt;
&lt;/label&gt;
&lt;label for=&quot;makePrimaryBillingAddress&quot;&gt;
    &lt;input id=&quot;makePrimaryBillingAddress&quot; name=&quot;makePrimaryBillingAddress&quot; type=&quot;checkbox&quot; {{ isPrimaryBilling ? 'checked' :'' }}/&gt;
    &lt;span&gt;Make this the primary billing address&lt;/span&gt;
&lt;/label&gt;
                        
</code></pre>

CC BY-SA 4.0
2021-12-21T12:06:15.240Z
But doesn't that only work from a commerce form action, such as `commerce/cart/update-cart`? Didn't you want it to happen from the user registration form?
James Smith
CC BY-SA 4.0
2022-01-07T09:53:12.703Z
HI James, I tested this and can confirm this works to set the options.  You also have to set the cart object using something like: {% if cart is not defined %}
  {% set cart = craft.commerce.carts.cart %}
{% endif %}
Mark
CC BY-SA 4.0
2022-01-07T10:31:34.437Z
Are you saying this works from a submission of the user registration form?? That would be surprising.
James Smith
CC BY-SA 4.0
2022-01-14T10:29:39.910Z
Hi James, that's right, I've tested it and it does work.  You have to set the cart object as above, but this does work.
Mark
CC BY-SA 4.0
2021-12-21T11:37:10.713Z
2022-01-04T17:21:24.527Z
2022-01-04T17:21:24.527Z
Mark
<p>We have a site using Craft 3.6.11 and Commerce 3.3.5.1</p>
<p>We give users the options to create and account enter an address.  Is there anyway to also have this address set as the Primary Billing Address and Primary Shipping Address when they do this?</p>

<plugin-craftcommerce3>
Set Primary Billing Address and Primary Shipping Address
# Set Primary Billing Address and Primary Shipping Address

(Asked by: username_0 on 2021-12-20)

We have a site using Craft 3.6.11 and Commerce 3.3.5.1

We give users the options to create and account enter an address. Is there anyway to also have this address set as the Primary Billing Address and Primary Shipping Address when they do this?

**Tags:** plugin-craftcommerce3


---

## 2 answers

### Answer by username_1 on 2021-12-20. Score: 2 | Accepted answer

I ran into the same requirement a while ago. Not 100% sure if this is still necessary, but at the time I needed to do it via custom code in a module. It looks like this:
use Craft;
use craft\services\Elements;
use craft\commerce\models\Address as AddressModel;
use craft\commerce\records\Customer as CustomerRecord;
use craft\commerce\records\CustomerAddress as CustomerAddressRecord;
use craft\commerce\Plugin as CommercePlugin;
use yii\base\Event;

// --------------------------------------------
// SAVE COMMERCE CUSTOMER ADDRESS AFTER REGISTRATION
// --------------------------------------------

Event::on(
    Elements::class,
    Elements::EVENT_AFTER_SAVE_ELEMENT,
    function(Event $e) {
        // Bail out on console requests
        if (Craft::$app->request->isConsoleRequest) { return; }

        // Bail out if it's not a User element being saved
        if (!$e->element instanceof \craft\elements\User) { return; }

        // Bail out on CP requests
        if (Craft::$app->request->isCpRequest) { return; }

        // get the address fields from the POST data...
        $add1 = Craft::$app->request->getBodyParam('address');

        $userId = $e->element->id;
        $address = new AddressModel();

        $address->attention = '';
        $address->title = '';
        $address->firstName = '';
        $address->lastName = '';
        $address->fullName = '';
        $address->address1 = $add1['address1'];
        $address->address2 = $add1['address2'];
        $address->address3 = '';
        $address->city = $add1['city'];
        $address->zipCode = $add1['zipCode'];
        $address->phone = '';
        $address->alternativePhone = '';
        $address->label = '';
        $address->notes = '';
        $address->businessName = '';
        $address->businessTaxId = '';
        $address->businessId = '';
        $address->countryId = 77;
        $address->stateName = $add1['stateValue'];
        $address->custom1 = '';
        $address->custom2 = '';
        $address->custom3 = '';
        $address->custom4 = '';
        $address->id = 0;

        // Save it
        $addressSaved = CommercePlugin::getInstance()->getAddresses()->saveAddress($address);

        // now tie it to a new record in craft_commerce_customers_addresses
        if ($addressSaved) {
            $customer = (new \craft\commerce\services\Customers)->getCustomerByUserId($userId);

            $customerAddressRecord = new CustomerAddressRecord();
            $customerAddressRecord->customerId = $customer->id;
            $customerAddressRecord->addressId = $address->id;
            $customerAddressSaved = $customerAddressRecord->save();

            $customerRecord = CustomerRecord::findOne($customer->id);
            $customerRecord->primaryShippingAddressId = $address->id;
            $customerRecord->save();
        }        
    }
);

EDIT TO ADD: now updated this for Craft 4 / Commerce 4 as follows:
use Craft;
use craft\services\Elements;
use craft\services\Users;
use yii\base\Event;

...

Event::on(
    Elements::class,
    Elements::EVENT_AFTER_SAVE_ELEMENT,
    function(Event $e) {
        // bail out on console requests
        if (Craft::$app->request->isConsoleRequest){ return; }

        // bail out on CP requests
        if (Craft::$app->request->isCpRequest) { return; }

        // bail out if this isn't coming from our registration form (this is a hidden field on the registration form)
        if (Craft::$app->request->post('saveAddress') != '1'){ return; }

        // bail out if it's not a user element being saved, just to triple check ourselves
        if (!$e->element instanceof \craft\elements\User){ return; }

        // else continue...
        $add1 = Craft::$app->request->getBodyParam('address');

        $address = new Address();

        $address->ownerId = $e->element->id;
        $address->title = 'Address';
        $address->fullName = '';
        $address->addressLine1 = $add1['addressLine1'];
        $address->addressLine2 = $add1['addressLine2'];
        $address->locality = $add1['locality'];
        $address->postalCode = $add1['postalCode'];
        $address->countryCode = 'GB';
        $address->administrativeArea = $add1['administrativeArea'];

        // save it
        Craft::$app->getElements()->saveElement($address);
    }
);

> **Comments:**
> **username_0**: Thanks James, I've also found a way to do it as below  

---

### Answer by username_0 on 2021-12-21. Score: 1

As well as James answer above, the following should do it:
{% set isPrimaryBilling = cart.customer.primaryBillingAddressId == addressId %}
{% set isPrimaryShipping = cart.customer.primaryShippingAddressId == addressId %}


    
    Make this the primary shipping address


    
    Make this the primary billing address

> **Comments:**
> **username_1**: But doesn't that only work from a commerce form action, such as `commerce/cart/update-cart`? Didn't you want it to happen from the user registration form?  
> **username_0**: HI James, I tested this and can confirm this works to set the options.  You also have to set the cart object using something like: {% if cart is not defined %}   {% set cart = craft.commerce.carts.cart %} {% endif %}  
> **username_1**: Are you saying this works from a submission of the user registration form?? That would be surprising.  
> **username_0**: Hi James, that's right, I've tested it and it does work.  You have to set the cart object as above, but this does work.  

---

