Answers.Body: <p>In Craft3 you can do it like this:</p>
  
  <pre><code>use Craft;
  use craft\base\Plugin;
  use craft\commerce\models\Address;
  use yii\base\Event;
  
  class Custom extends Plugin
  {
      public function init()
      {
          parent::init();
  
          Event::on(Address::class, Address::EVENT_BEFORE_VALIDATE, function (Event $event) {
              $address = $event-&gt;sender;
              if (empty($address-&gt;address1)) {
                  $address-&gt;addError('address1', Craft::t('app', 'Address Line 1 is required'));
                  $event-&gt;handled = true; // stop other handlers for this event
              }
          });
      }
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-09-30T15:54:27.350Z
Answers.Text: FYI this is now covered on the [Customer Address Management](https://craftcms.com/docs/commerce/3.x/customer-address-management.html#validating-addressses) page in the docs, and if anybody needs help setting up a custom module to use events there’s an example of that here: https://craftcms.com/knowledge-base/custom-module-events
Answers.UserDisplayName: Matt Stein
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-07-28T05:08:26.567Z
Answers.LastActivityDate: 2018-07-28T05:08:26.567Z
Answers.UserDisplayName: cornernote
Answers.Body: <p>You'll need to add some kind of validation query to the field first. Something along the lines of this would work:</p>
  
  <pre><code>craft()-&gt;on('commerce_addresses.onBeforeSaveAddress', function(Event $event){
     $address = $event-&gt;params['address'];
  
     if (empty($address-&gt;address1))
     {
       $address-&gt;addError('address1', Craft::t('Address Line 1 is required'));
       $event-&gt;performAction = false;
     }
  
     if ($address-&gt;city == 'London')
     {
       $address-&gt;addError('city', Craft::t('Sorry, you can\'t be from London'));
       $event-&gt;performAction = false;
     }
  });  
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-12-19T14:17:54.963Z
Answers.Text: Has someone got this to work? I can’t seem to. Using the business logic plugin and registering the action, the form submits but gets redirected to itself without throwing an errors. Has anything changed? Stil trying to find my way around regarding plugins.
Answers.UserDisplayName: Marcus Scheller
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-12-19T14:21:11.080Z
Answers.Text: You won't need to register an action for this to work. The event is triggered by commerce updating an address on an order/cart. Make sure the event is being triggered by debugging with a simple `Craft::dd('address about to be saved')`
Answers.UserDisplayName: Luke Pearce
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-12-19T14:26:30.653Z
Answers.Text: Alright, dumb question:: that goes into to businessLogicController.php in this case, right? Now it completes the step without validation.
Answers.UserDisplayName: Marcus Scheller
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-12-19T14:28:28.323Z
Answers.Text: The function in my original answer would go inside the `init()` function in `BusinessLogicPlugin.php`. A lot of the time errors happen due to filename formatting - using something like pluginfactory.io to generate your plugin will help avoid this.
Answers.UserDisplayName: Luke Pearce
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-07-13T16:10:30.817Z
Answers.LastActivityDate: 2017-08-22T13:47:04.427Z
Answers.LastEditDate: 2017-08-22T13:47:04.427Z
Answers.UserDisplayName: Luke Pearce
Answers.Body: <p>I've used the Business Logic plugin to check certain fields before payment processing rather than on regular validation. This way I can save the address while entering the address-data with JavaScript, but payments fail until these fields have been validated properly.</p>
  
  <p>Adding this to BusinessLogic.php</p>
  
  <pre><code>use craft\commerce\services\Payments;
  use craft\commerce\events\ProcessPaymentEvent;
  use craft\commerce\errors\PaymentException;
  </code></pre>
  
  <p>And this in the init() function</p>
  
  <pre><code>Event::on(Payments::class, Payments::EVENT_BEFORE_PROCESS_PAYMENT, function(ProcessPaymentEvent $event) {
    $shippingAddress = $event-&gt;order['shippingAddress'];
    if(empty($shippingAddress-&gt;address1) || empty($shippingAddress-&gt;zipCode) || empty($shippingAddress-&gt;city)) {
      throw new PaymentException(Craft::t('commerce', 'No valid address entered.'));
    }
  });
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-04-16T15:02:40.033Z
Answers.LastActivityDate: 2019-04-16T15:02:40.033Z
Answers.UserDisplayName: Fabian Hijlkema
Body: <p>Can someone break down how I should validate empty address fields as a plugin for Craft Commerce and take the <a href="https://craftcms.stackexchange.com/questions/14958/craft-commerce-custom-address-model-validations">following answer</a> further?</p>
  
  <p>The Craft Commerce documentation provides the following example for the name field - but I'm not sure what my next steps should be...</p>
  
  <pre><code>public function init()
  {
      craft()-&gt;on('commerce_addresses.onBeforeSaveAddress', function($event){
              $address = $event-&gt;params['address'];
              $address-&gt;addError('firstName','Not a cool name man.');
              $event-&gt;performAction = false;
      });
  }
  </code></pre>
  
Tags: <plugin-development><plugin-craftcommerce>
Title: Craft Commerce: Validation on Address Fields
ThreadText: # Craft Commerce: Validation on Address Fields
  
  (Asked by: username_0 on 2016-07-13)
  
  Can someone break down how I should validate empty address fields as a plugin for Craft Commerce and take the [following answer](https://craftcms.stackexchange.com/questions/14958/craft-commerce-custom-address-model-validations) further?
  
  The Craft Commerce documentation provides the following example for the name field - but I'm not sure what my next steps should be...
  
  ```
  public function init()
  {
      craft()->on('commerce_addresses.onBeforeSaveAddress', function($event){
              $address = $event->params['address'];
              $address->addError('firstName','Not a cool name man.');
              $event->performAction = false;
      });
  }
  
  ```
  
  **Tags:** plugin-development, plugin-craftcommerce
  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_1 on 2018-07-28. Score: 6
  
  In Craft3 you can do it like this:
  
  ```
  use Craft;
  use craft\base\Plugin;
  use craft\commerce\models\Address;
  use yii\base\Event;
  
  class Custom extends Plugin
  {
      public function init()
      {
          parent::init();
  
          Event::on(Address::class, Address::EVENT_BEFORE_VALIDATE, function (Event $event) {
              $address = $event->sender;
              if (empty($address->address1)) {
                  $address->addError('address1', Craft::t('app', 'Address Line 1 is required'));
                  $event->handled = true; // stop other handlers for this event
              }
          });
      }
  }
  
  ```
  
  > **Comments:**
  > **username_2**: FYI this is now covered on the [Customer Address Management](https://craftcms.com/docs/commerce/3.x/customer-address-management.html#validating-addressses) page in the docs, and if anybody needs help setting up a custom module to use events there’s an example of that here: https://craftcms.com/knowledge-base/custom-module-events  
  
  ---
  
  ### Answer by username_3 on 2016-07-13. Score: 5
  
  You'll need to add some kind of validation query to the field first. Something along the lines of this would work:
  
  ```
  craft()->on('commerce_addresses.onBeforeSaveAddress', function(Event $event){
     $address = $event->params['address'];
  
     if (empty($address->address1))
     {
       $address->addError('address1', Craft::t('Address Line 1 is required'));
       $event->performAction = false;
     }
  
     if ($address->city == 'London')
     {
       $address->addError('city', Craft::t('Sorry, you can\'t be from London'));
       $event->performAction = false;
     }
  });  
  
  ```
  
  > **Comments:**
  > **username_4**: Has someone got this to work? I can’t seem to. Using the business logic plugin and registering the action, the form submits but gets redirected to itself without throwing an errors. Has anything changed? Stil trying to find my way around regarding plugins.  
  > **username_3**: You won't need to register an action for this to work. The event is triggered by commerce updating an address on an order/cart. Make sure the event is being triggered by debugging with a simple `Craft::dd('address about to be saved')`  
  > **username_4**: Alright, dumb question:: that goes into to businessLogicController.php in this case, right? Now it completes the step without validation.  
  > **username_3**: The function in my original answer would go inside the `init()` function in `BusinessLogicPlugin.php`. A lot of the time errors happen due to filename formatting - using something like pluginfactory.io to generate your plugin will help avoid this.  
  
  ---
  
  ### Answer by username_5 on 2019-04-16. Score: 1
  
  I've used the Business Logic plugin to check certain fields before payment processing rather than on regular validation. This way I can save the address while entering the address-data with JavaScript, but payments fail until these fields have been validated properly.
  
  Adding this to BusinessLogic.php
  
  ```
  use craft\commerce\services\Payments;
  use craft\commerce\events\ProcessPaymentEvent;
  use craft\commerce\errors\PaymentException;
  
  ```
  
  And this in the init() function
  
  ```
  Event::on(Payments::class, Payments::EVENT_BEFORE_PROCESS_PAYMENT, function(ProcessPaymentEvent $event) {
    $shippingAddress = $event->order['shippingAddress'];
    if(empty($shippingAddress->address1) || empty($shippingAddress->zipCode) || empty($shippingAddress->city)) {
      throw new PaymentException(Craft::t('commerce', 'No valid address entered.'));
    }
  });
  
  ```
  
  
  ---
  
  