In this blog post, I have provided a complete solution to dynamically change billing address in Magento 2.
The billing address defines a physical location/address where the invoices or bills of the online orders are sent to the customers. In special cases, you may require to dynamically change the billing address of specific customers after placing the orders on your Magento 2 store.
Suppose you are running an online store on Magento 2 and have tied up with another company to deliver some essential products to their employees. In that case, you may require to dynamically change the shipping address of such orders to that of the company where you want to send the invoices. This process can be made easier if your e-commerce platform allows for the management of multiple shipping addresses, as you can easily add and switch between different addresses for your orders
To do that, you might need to define customers’ attributes and change the billing addresses of customers having specific attributes. You can refer to the programmatic solution provided here for that.
app/code/Vendor/Module/registration.php <?php use Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register( ComponentRegistrar::MODULE, 'Vendor_Module', __DIR__ );
After registering and creating the module, you need to create a custom event that can be dispatched when the customer places an order. Create an events.xml file at app/code/Vendor/Extension/etc/ with the following code:
app/code/Vendor/Module/etc/module.xml <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Vendor_Module" setup_version="1.0.0"> </module> </config>
Finally, you need to add an obersever that dynamically changes the customer’s billing address once the order is placed. Create a AfterPlaceOrder.php file at app/code/Vendor/Extension/Observer/ directory with the following code:
app/code/Vendor/Extension/etc/events.xml <event name="checkout_onepage_controller_success_action"> <observer name="vendor_extension_order_place_after " instance="Vendor\Extension\Observer\AfterPlaceOrder"/> </event> 4) app/code/Vendor/Extension/Observer/AfterPlaceOrder.php <?php namespace Vendor\Extension\Observer; use Exception; use Magento\Framework\DataObject; use Magento\Framework\Event\Observer as EventObserver; use Magento\Framework\Event\ObserverInterface; use Magento\Framework\Exception\AlreadyExistsException; use Magento\Framework\Message\ManagerInterface; use Magento\Sales\Model\Order; use Magento\Sales\Model\OrderFactory; use Magento\Sales\Model\ResourceModel\OrderFactory as OrderResourceModelFactory; use Magento\Directory\Model\ResourceModel\Region\CollectionFactory as RegionCollectionFactory; /** * Class AfterPlaceOrder */ class AfterPlaceOrder implements ObserverInterface { /** * @var RegionCollectionFactory */ private $regionCollectionFactory; /** * @var OrderResourceModelFactory */ private $orderResourceModelFactory; /** * @var OrderFactory */ protected $orderModel; /** * @var ManagerInterface */ private $messageManager; /** * PlaceOrder constructor. * @param ManagerInterface $messageManager * @param OrderResourceModelFactory $orderResourceModelFactory * @param RegionCollectionFactory $regionCollectionFactory * @param OrderFactory $orderModel */ public function __construct( ManagerInterface $messageManager, OrderResourceModelFactory $orderResourceModelFactory, RegionCollectionFactory $regionCollectionFactory, OrderFactory $orderModel ) { $this->regionCollectionFactory = $regionCollectionFactory; $this->orderResourceModelFactory = $orderResourceModelFactory; $this->orderModel = $orderModel; $this->messageManager = $messageManager; } /** * @param EventObserver $observer * @throws Exception */ public function execute(EventObserver $observer) { try { /** * @var Order $order */ $order = $observer->getEvent()->getOrder(); if ($order == null) { $orders = $observer->getEvent()->getOrders(); foreach ($orders as $order) { $this->setBillingAddress($order); } } else { $this->setBillingAddress($order); } } catch (Exception $e) { $this->messageManager->addErrorMessage($e->getMessage()); } } /** * @param $order * @throws AlreadyExistsException */ public function setBillingAddress($order) { $regionInfo = $this->getRegionInfo('South Australia'); $order->getBillingAddress()->setStreet('street line'); $order->getBillingAddress()->setCity('melbourne'); $order->getBillingAddress()->setPostcode('3002'); $order->getBillingAddress()->setCountryId('AU'); $order->getBillingAddress()->setRegionId($regionInfo->getRegionId()); $order->getBillingAddress()->setRegionCode($regionInfo->getRegionCode()); $order->getBillingAddress()->setRegion('South Australia'); $order->getBillingAddress()->setTelephone('12456465'); $this->orderResourceModelFactory->create()->save($order); } /** * @param string $regionName * @return DataObject */ public function getRegionInfo(string $regionName) { return $this->regionCollectionFactory->create() ->addRegionNameFilter($regionName) ->getFirstItem(); } }
You can change the edit the observer file as per your requirements to dynamically change billing address in Magento 2.
Magento 2 store owners can use this programmatic solution to change the billing address of orders dynamically as per their requirements.
Also read:
- How to Add or Remove Address Field from PDF in Magento 2
- How to Change Shipping Price on Address Field Change in Magento 2 Custom Shipping Method
- How to Change Number of Lines in Street Address in Magento 2
Also, do not forget to share this Magento 2 solution with your Magento friends via social media.
Thanks for reading.