<p>If I am reading you right you are wanting to update the shipping address on the order rather than create a new one. </p>

<p>You should be able to do that right now:</p>

<pre><code>{% set cart = craft.commerce.carts.cart %}

{% set flashNotice = craft.app.session.getFlash('notice') %}

{% if flashNotice %}
    &lt;div class="bg-blue-500 text-white"&gt;
        &lt;div class="flash container mx-auto px-6 py-4"&gt;
            {{ flashNotice }}
        &lt;/div&gt;
    &lt;/div&gt;
{% endif %}

{% set flashError = craft.app.session.getFlash('error') %}

{% if flashError %}
&lt;div class="bg-red-500 text-white"&gt;
  &lt;div class="flash container mx-auto px-6 py-4"&gt;
    {{ flashError }}
  &lt;/div&gt;
&lt;/div&gt;
{% endif %}


//meat and potatoes:


{{ cart.number }}&lt;br&gt;

Shipping Address ID: {{ cart.shippingAddressId }}

&lt;form method="post"&gt;
  &lt;input type="hidden" name="action" value="commerce/cart/update-cart"/&gt;
  &lt;input type="hidden" name="cartUpdatedNotice" value="The address was updated."&gt;
  {{ redirectInput('shop/address') }}
  {{ csrfInput() }}

  &lt;!-- THIS IS WHAT WILL UPDATE THE ADDRESS VS ADDING A NEW ONE --&gt;
  {% if cart.shippingAddress.id %}
  &lt;input type="hidden" name="shippingAddress[id]" value="{{cart.shippingAddress.id}}"/&gt;
  {% endif %}

  First Name:
  &lt;input name="shippingAddress[firstName]" value="{{cart.shippingAddress.firstName ?? ''}}"/&gt;

  &lt;button type="submit"&gt;Update&lt;/button&gt;
&lt;/form&gt;
</code></pre>

<p>As demonstrated above, using an input with <code>name="shippingAddress[id]"</code> with the address ID set as the value will update the address with that ID on the <code>commerce/cart/update-cart</code> controller action just fine.</p>

<p>You would only use <code>name="shippingAddressId"</code> if you wanted to let the user select an existing one. </p>

CC BY-SA 4.0
2020-04-08T11:31:49.917Z
Let me know if I am not understanding.
Luke Holder
CC BY-SA 4.0
2020-04-08T12:11:10.850Z
Thanks Luke. Appreciate it’s perhaps not that common but there’s a situation (at least in our checkout process) where a duplicate address is more likely. For example, in our simple form rather than display previous addresses and give the option to add a new one. It just asks for the billingAddress[countryId]. That’s it. So that form opens up the likelihood of duplicates if they’ve checked out before, or have to go back a step in the process and submit the same form twice. Therefore, I’m trying to check against existing  addresses on the plugin side.
James
CC BY-SA 4.0
2020-04-08T12:13:10.993Z
Also, less likely to happen but even with radio buttons to select a saved address, they could still opt to enter a new one and input a duplicate. Or maybe I’m missing something?
James
CC BY-SA 4.0
2020-04-09T10:11:12.703Z
I’ve updated the question to hopefully make it clearer. I still think there’s a need to catch duplicates.
James
CC BY-SA 4.0
2020-04-08T11:26:51.070Z
2020-04-08T11:26:51.070Z
Luke Holder
<p>I want to try and stop Commerce 3 creating a new customer address if it’s a duplicate of an existing one.</p>

<p>As an example, a store selling digital products has a checkout form that simply asks for the customer’s country, no other address info is required. All we need is one select field for the country (pre-checked if we already have that info). We <em>could</em> add radio buttons to select any previously saved addresses as well as a field to select a (new) country. However, even if we do that, there’s still a chance the user opts to enter a new address and actually submits a duplicate.</p>

<p>I’ve created a plugin that catches a duplicate address and then tries to set the cart’s billingAddressId so a new address isn’t created. What I have so far though doesn’t work. It doesn’t successfully update the <code>billingAddressId</code>. If I use <code>Craft::$app-&gt;getElements()-&gt;saveElement($cart)</code> it results in a loop in this case.</p>

<p>How can I complete this to update the cart, or perhaps the post data in this case, with the matched <code>billingAddressId</code>?</p>

<pre><code>Event::on(Address::class, Address::EVENT_BEFORE_VALIDATE, function (Event $e) {

    $sentCountryId = $e-&gt;sender-&gt;countryId;
    $currentUser = Craft::$app-&gt;user;
    $cart = craft\commerce\Plugin::getInstance()-&gt;getCarts()-&gt;getCart();
    $addresses = $cart-&gt;customer-&gt;addresses;
    $match = 0;

    // Only check against saved addresses if currentUser has any
    if ($currentUser and $addresses) {

        // If true, loop saved address to check for a country match
        foreach($addresses as $address) {

            // Loop until a match is found
            if ($match == 0) {

                $savedCountryId = $address-&gt;countryId;

                if ($sentCountryId == $savedCountryId) {
                    $match = $address-&gt;id;
                }

            }

        };

        // If there’s a match set the cart’s billingAddressId
        // to stop a new address being created:
        if ($match) {

            $cart-&gt;billingAddressId = $match; // This doesn’t work on it’s own
            // Craft::$app-&gt;getElements()-&gt;saveElement($cart); // Results in a loop
            $e-&gt;handled = true;

        }

    }

});
</code></pre>

<craft3><plugin-craftcommerce><plugin-craftcommerce3>
Update Cart’s address ID from plugin
# Update Cart’s address ID from plugin

(Asked by: username_0 on 2020-04-08)

I want to try and stop Commerce 3 creating a new customer address if it’s a duplicate of an existing one.
As an example, a store selling digital products has a checkout form that simply asks for the customer’s country, no other address info is required. All we need is one select field for the country (pre-checked if we already have that info). We could add radio buttons to select any previously saved addresses as well as a field to select a (new) country. However, even if we do that, there’s still a chance the user opts to enter a new address and actually submits a duplicate.
I’ve created a plugin that catches a duplicate address and then tries to set the cart’s billingAddressId so a new address isn’t created. What I have so far though doesn’t work. It doesn’t successfully update the billingAddressId. If I use Craft::$app->getElements()->saveElement($cart) it results in a loop in this case.
How can I complete this to update the cart, or perhaps the post data in this case, with the matched billingAddressId?
Event::on(Address::class, Address::EVENT_BEFORE_VALIDATE, function (Event $e) {

    $sentCountryId = $e->sender->countryId;
    $currentUser = Craft::$app->user;
    $cart = craft\commerce\Plugin::getInstance()->getCarts()->getCart();
    $addresses = $cart->customer->addresses;
    $match = 0;

    // Only check against saved addresses if currentUser has any
    if ($currentUser and $addresses) {

        // If true, loop saved address to check for a country match
        foreach($addresses as $address) {

            // Loop until a match is found
            if ($match == 0) {

                $savedCountryId = $address->countryId;

                if ($sentCountryId == $savedCountryId) {
                    $match = $address->id;
                }

            }

        };

        // If there’s a match set the cart’s billingAddressId
        // to stop a new address being created:
        if ($match) {

            $cart->billingAddressId = $match; // This doesn’t work on it’s own
            // Craft::$app->getElements()->saveElement($cart); // Results in a loop
            $e->handled = true;

        }

    }

});

**Tags:** craft3, plugin-craftcommerce, plugin-craftcommerce3

---

## 1 answers

### Answer by username_1 on 2020-04-08. Score: 0

If I am reading you right you are wanting to update the shipping address on the order rather than create a new one. 
You should be able to do that right now:
{% set cart = craft.commerce.carts.cart %}

{% set flashNotice = craft.app.session.getFlash('notice') %}

{% if flashNotice %}
    
        
            {{ flashNotice }}
        
    
{% endif %}

{% set flashError = craft.app.session.getFlash('error') %}

{% if flashError %}

  
    {{ flashError }}
  

{% endif %}


//meat and potatoes:


{{ cart.number }}

Shipping Address ID: {{ cart.shippingAddressId }}


  
  
  {{ redirectInput('shop/address') }}
  {{ csrfInput() }}

  
  {% if cart.shippingAddress.id %}
  
  {% endif %}

  First Name:
  

  Update


As demonstrated above, using an input with name="shippingAddress[id]" with the address ID set as the value will update the address with that ID on the commerce/cart/update-cart controller action just fine.
You would only use name="shippingAddressId" if you wanted to let the user select an existing one.

> **Comments:**
> **username_1**: Let me know if I am not understanding.  
> **username_0**: Thanks Luke. Appreciate it’s perhaps not that common but there’s a situation (at least in our checkout process) where a duplicate address is more likely. For example, in our simple form rather than display previous addresses and give the option to add a new one. It just asks for the billingAddress[countryId]. That’s it. So that form opens up the likelihood of duplicates if they’ve checked out before, or have to go back a step in the process and submit the same form twice. Therefore, I’m trying to check against existing  addresses on the plugin side.  
> **username_0**: Also, less likely to happen but even with radio buttons to select a saved address, they could still opt to enter a new one and input a duplicate. Or maybe I’m missing something?  
> **username_0**: I’ve updated the question to hopefully make it clearer. I still think there’s a need to catch duplicates.  

---

