Magento2: How to get guest email address in checkout?(PHP way)

All we need is an easy explanation of the problem, so here it is.

I develop a gateway module for magento 2 and when a customer who complete the registration process – i can get his email by :

$quote->getCustomerEmail()

but when i try to get a Guest email – i get a NULL value. There is a “Magento 2 way” to get it?

Javascript solution allready found:
Magento2: How to get guest email address in checkout?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

If we take a look:
vendor/magento/module-checkout/Model/Type/Onepage.php

 protected function _prepareGuestQuote()
 {
        $quote = $this->getQuote();
        $quote->setCustomerId(null)
            ->setCustomerEmail($quote->getBillingAddress()->getEmail())
            ->setCustomerIsGuest(true)
            ->setCustomerGroupId(GroupInterface::NOT_LOGGED_IN_ID);
        return $this;
 }

So, basically, we can get the guest email: $quote->getBillingAddress()->getEmail()

There are some other places:

vendor/magento/module-paypal/Model/Express/Checkout.php

vendor/magento/module-quote/Model/QuoteManagement.php

Method 2

  • In case of the Guest customer, magento didn’t map email id to
    shipping or billing address before place order.
  • In my case, I need guest email which is provided at the time of
    shipping page. To validate Guest email with Coupon code using this
    event ( salesrule_validator_process ) .

To Do that :
Step 1: Create di.xml to override core code.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <preference for="Magento\Customer\Model\AccountManagement" type="Custom\Couponfriend\Model\AccountManagement" />
</config>

Step 2: Override model in custom module, and set email to
Quote’s->shipping object. and get where you need it.

<?php

namespace Custom\Couponfriend\Model;

class AccountManagement extends \Magento\Customer\Model\AccountManagement {

    public function isEmailAvailable($customerEmail, $websiteId = null) {
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $cart = $objectManager->get('\Magento\Checkout\Model\Cart');
        $shippingAddress = $cart->getQuote()->getShippingAddress();

        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/guestFriendsFamily.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        $logger->info('------------');

        try {
            if ($shippingAddress) {
                $shippingAddress->setData('email', $customerEmail);
                $shippingAddress->save();
            }
        } catch (NoSuchEntityException $e) {
            $logger->info($e->getMessage());
        }

        try {
            if ($websiteId === null) {
                $websiteId = $this->storeManager->getStore()->getWebsiteId();
            }
            $this->customerRepository->get($customerEmail, $websiteId);
            return false;
        } catch (NoSuchEntityException $e) {
            return true;
        }
    }

}

?>

You can override constructor to create cart object using dependency injection

Method 3

This work for Magento 1

<?php class Exinent_Billingtax_Model_Observer { 
public function autoRegisterBilling($evt){
if(!Mage::helper('customer')->isLoggedIn()){
    $data =$evt->getEvent()->getControllerAction()->getRequest()->getPost('billing', array());
    echo "<pre>";
    print_r($data);
    $customer = Mage::getModel("customer/customer");
    $email = $data['email'];
    $websiteId = Mage::app()->getWebsite()->getId();
    $store = Mage::app()->getStore();
    $pwd = $data['customer_password'];
    $customer->setWebsiteId(Mage::app()->getStore()->getWebsiteId())->loadByEmail($email);

    if (!$customer->getId()) {
         //Code begins here for new customer registration
        $customer->website_id = $websiteId;
        $customer->setStore($store);
        $customer->firstname = $data['firstname'];
        $customer->lastname = $data['lastname'];
        $customer->setEmail($email);
        $customer->setPassword($pwd);
        $customer->sendNewAccountEmail('confirmed');  
        $customer->save();
           }
    Mage::getSingleton('customer/session')->loginById($customer->getId()); // to login that customer.
   }

}

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply