Magento 2: Create Customer Programmatically

This article shows how you can create customers programmatically (through code) in Magento 2.x.

I have also written a similar article on Creating Customer Programmatically in Magento 1.x.

In this example code, I will show how you can save a customer with general information like firstname, lastname, and email. I will also show how you can save the customer address (billing address and shipping address) as well.

I will show both ways of programming in Magento 2, i.e.

– through dependency injection
– through object manager

Create Customer using Dependency Injection

Please note that, in this example, my custom module “HelloWorld” path is: app/code/Chapagain/HelloWorld/

I have an Add controller file which can be browsed like: http://127.0.0.1/magento2/helloworld/customer/add

Browsing this path will show a form and its action is to the Addpost controller.

The Addpost controller file for this example is:

app/code/Chapagain/HelloWorld/Customer/Addpost.php


<?php
namespace Chapagain\HelloWorld\Controller\Customer;

use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Customer\Model\CustomerFactory;
use Magento\Customer\Model\AddressFactory;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Escaper;
use Magento\Framework\UrlFactory;
use Magento\Customer\Model\Session;
use Magento\Customer\Model\Registration;
use Magento\Framework\Data\Form\FormKey\Validator;
use Magento\Framework\App\ObjectManager;
 
class Addpost extends \Magento\Framework\App\Action\Action
{
    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var \Magento\Customer\Model\CustomerFactory
     */
    protected $customerFactory;

    /**
     * @var \Magento\Customer\Model\AddressFactory
     */
    protected $addressFactory;

    /**
     * @var \Magento\Framework\Message\ManagerInterface
     */
    protected $messageManager;

    /**
     * @var \Magento\Framework\Escaper
     */
    protected $escaper;

    /**
     * @var \Magento\Framework\UrlFactory
     */
    protected $urlFactory;

    /**
     * @var \Magento\Customer\Model\Session
     */
    protected $session;

    /**
     * @var Magento\Framework\Data\Form\FormKey\Validator
     */
    private $formKeyValidator;

    /**
     * @param Context $context
     * @param StoreManagerInterface $storeManager
     * @param CustomerFactory $customerFactory
     * @param AddressFactory $addressFactory
     * @param ManagerInterface $messageManager
     * @param Escaper $escaper
     * @param UrlFactory $urlFactory
     * @param Session $session
     * @param Validator $formKeyValidator
     */
    public function __construct(
        Context $context,
        StoreManagerInterface $storeManager,
        CustomerFactory $customerFactory,
        AddressFactory $addressFactory,
        ManagerInterface $messageManager,
        Escaper $escaper,
        UrlFactory $urlFactory,
        Session $session,
        Validator $formKeyValidator = null
    )
    {
        $this->storeManager     = $storeManager;
        $this->customerFactory  = $customerFactory;
        $this->addressFactory   = $addressFactory;
        $this->messageManager   = $messageManager;
        $this->escaper          = $escaper;
        $this->urlModel         = $urlFactory->create();
        $this->session          = $session;
        $this->formKeyValidator = $formKeyValidator ?: ObjectManager::getInstance()->get(Validator::class);
        
        // messageManager can also be set via $context
        // $this->messageManager   = $context->getMessageManager();

        parent::__construct($context);
    }

    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {
        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultRedirectFactory->create();
        // if ($this->session->isLoggedIn() || !$this->registration->isAllowed()) {
        //     $resultRedirect->setPath('*/*/');
        //     return $resultRedirect;
        // }
        
        // check if the form is actually posted and has the proper form key
        if (!$this->getRequest()->isPost() || !$this->formKeyValidator->validate($this->getRequest())) {
            $url = $this->urlModel->getUrl('*/*/add', ['_secure' => true]);
            $resultRedirect->setUrl($this->_redirect->error($url));
            return $resultRedirect;
        }

        $websiteId  = $this->storeManager->getWebsite()->getWebsiteId();

        $firstName = 'John';
        $lastName = 'Doe';
        $email = 'johndoe4@example.com';
        $password = 'Test1234';

        // instantiate customer object
        $customer = $this->customerFactory->create();
        $customer->setWebsiteId($websiteId);
        
        // check if customer is already present
        // if customer is already present, then show error message
        // else create new customer
        if ($customer->loadByEmail($email)->getId()) {
            //echo 'Customer with the email ' . $email . ' is already registered.';
            $message = __(
                'There is already an account with this email address "%1".',
                $email
            );
            // @codingStandardsIgnoreEnd
            $this->messageManager->addError($message);
        } else {
            try {
                // prepare customer data
                $customer->setEmail($email); 
                $customer->setFirstname($firstName);
                $customer->setLastname($lastName);

                // set null to auto-generate password
                $customer->setPassword($password); 

                // set the customer as confirmed
                // this is optional
                // comment out this line if you want to send confirmation email
                // to customer before finalizing his/her account creation
                $customer->setForceConfirmed(true);
                
                // save data
                $customer->save();
                
                // save customer address
                // this is optional
                // you can skip saving customer address while creating the customer
                $customerAddress = $this->addressFactory->create();                
                $customerAddress->setCustomerId($customer->getId())
                                ->setFirstname($firstName)
                                ->setLastname($lastName)
                                ->setCountryId('US')
                                ->setRegionId('12') // optional, depends upon Country, e.g. USA
                                ->setRegion('California') // optional, depends upon Country, e.g. USA
                                ->setPostcode('90232')
                                ->setCity('Culver City')
                                ->setTelephone('888-888-8888')
                                ->setFax('999')
                                ->setCompany('XYZ')
                                ->setStreet(array(
                                    '0' => 'Your Customer Address 1', // compulsory
                                    '1' => 'Your Customer Address 2' // optional
                                )) 
                                ->setIsDefaultBilling('1')
                                ->setIsDefaultShipping('1')
                                ->setSaveInAddressBook('1');
                
                try {
                    // save customer address
                    $customerAddress->save();
                } catch (Exception $e) {
                    $this->messageManager->addException($e, __('We can\'t save the customer address.'));
                }                

                // send welcome email to the customer
                $customer->sendNewAccountEmail();

                //echo 'Customer with the email ' . $email . ' is successfully created.';

                $this->messageManager->addSuccess(
                    __(
                        'Customer account with email %1 created successfully.',
                        $email
                    )
                );
                
                $url = $this->urlModel->getUrl('*/*/add', ['_secure' => true]);
                $resultRedirect->setUrl($this->_redirect->success($url));
                
                //$resultRedirect->setPath('*/*/');
                return $resultRedirect;
            } catch (StateException $e) {
                $url = $this->urlModel->getUrl('customer/account/forgotpassword');
                // @codingStandardsIgnoreStart
                $message = __(
                    'There is already an account with this email address. If you are sure that it is your email address, <a href="%1">click here</a> to get your password and access your account.',
                    $url
                );
                // @codingStandardsIgnoreEnd
                $this->messageManager->addError($message);
            } catch (InputException $e) {
                $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
                foreach ($e->getErrors() as $error) {
                    $this->messageManager->addError($this->escaper->escapeHtml($error->getMessage()));
                }
            } catch (LocalizedException $e) {
                $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
            } catch (\Exception $e) {
                $this->messageManager->addException($e, __('We can\'t save the customer.'));
            }
        }

        $this->session->setCustomerFormData($this->getRequest()->getPostValue());
        $defaultUrl = $this->urlModel->getUrl('*/*/add', ['_secure' => true]);
        $resultRedirect->setUrl($this->_redirect->error($defaultUrl));
        return $resultRedirect;
    }
}
?>

Create Customer using Object Manager

This code using object manager can be written in any file like in the controller file, block file, or even in the template (.phtml) file. However, using Object Manager is less recommended. Using dependency injection shown above is the recommended way of coding.


$objectManager =  \Magento\Framework\App\ObjectManager::getInstance();        
$appState = $objectManager->get('\Magento\Framework\App\State');
//$appState->setAreaCode('frontend'); // not needed if Area code is already set

$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$websiteId = $storeManager->getStore()->getWebsiteId();

$firstName = 'John';
$lastName = 'Doe';
$email = 'johndoe10@example.com';
$password = 'Test1234';

// instantiate customer object
$customer = $objectManager->get('\Magento\Customer\Model\CustomerFactory')->create();
$customer->setWebsiteId($websiteId);

// if customer is already created, show message
// else create customer
if ($customer->loadByEmail($email)->getId()) {
    echo 'Customer with email '.$email.' is already registered.';  
} else {
    try {        
        // prepare customer data
        $customer->setEmail($email); 
        $customer->setFirstname($firstName);
        $customer->setLastname($lastName);

        // set null to auto-generate password
        $customer->setPassword($password); 

        // set the customer as confirmed
        // this is optional
        // comment out this line if you want to send confirmation email
        // to customer before finalizing his/her account creation
        $customer->setForceConfirmed(true);
        
        // save data
        $customer->save();
        
        // save customer address
        // this is optional
        // you can skip saving customer address while creating the customer
        $customerAddress = $objectManager->get('\Magento\Customer\Model\AddressFactory')->create();
        $customerAddress->setCustomerId($customer->getId())
                        ->setFirstname($firstName)
                        ->setLastname($lastName)
                        ->setCountryId('US')
                        ->setRegionId('12') // optional, depends upon Country, e.g. USA
                        ->setRegion('California') // optional, depends upon Country, e.g. USA
                        ->setPostcode('90232')
                        ->setCity('Culver City')
                        ->setTelephone('888-888-8888')
                        ->setFax('999')
                        ->setCompany('XYZ')
                        ->setStreet(array(
                            '0' => 'Your Customer Address 1', // compulsory
                            '1' => 'Your Customer Address 2' // optional
                        )) 
                        ->setIsDefaultBilling('1')
                        ->setIsDefaultShipping('1')
                        ->setSaveInAddressBook('1');
        
        try {
            // save customer address
            $customerAddress->save();
        } catch (Exception $e) {
            echo 'Cannot save customer address.';
        }                

        // send welcome email to the customer
        $customer->sendNewAccountEmail();

        echo 'Customer with the email ' . $email . ' is successfully created.';

    } catch (Exception $e) {
        echo $e->getMessage();
    }
}

Hope this helps. Thanks.