0

I have two Magento sites:

Site A : has a set of customers.

Site B is a new Magento installation, and I need to copy the missing customers from Site A into Site B.

Magento Version is the same 2.4.5.

I want the following to happen:

Copy all the customers who are missing in Site B from Site A, including all necessary customer information such as email, password hash, and other attributes.

Ensure that when a customer from Site A logs in on Site B using the same email and password, the login process works seamlessly.

I have already tried importing the customers by copying data directly into the customer_entity table, but I’m facing issues with the password hash and login functionality. When I use the same hashed password from Site A in Site B, the login fails, and I have to reset the password for the customer manually for it to work.

How can I ensure that the customer data, including the password hash, is correctly migrated, and the customer can log in seamlessly on Site B with the same credentials from Site A?

2 Answers 2

0

It will work if you keep the Crypt key (from the env) for Site B is the same as the Site A. Using same crypt key will make it work as per your requirement.

0

You can try below script for the move customer one side to another

<?php use Magento\Framework\App\Bootstrap; require __DIR__ . '/app/bootstrap.php'; $params = $_SERVER; $bootstrap = Bootstrap::create(BP, $params); $obj = $bootstrap->getObjectManager(); // Area code setup $state = $obj->get(\Magento\Framework\App\State::class); try { $state->setAreaCode('adminhtml'); } catch (\Magento\Framework\Exception\LocalizedException $e) {} // DB connection to Site A $sourcePdo = new PDO( "mysql:host=SOURCE_DB_HOST;dbname=SOURCE_DB_NAME;charset=utf8", "SOURCE_DB_USER", "SOURCE_DB_PASSWORD" ); // Magento services $customerFactory = $obj->get(\Magento\Customer\Model\CustomerFactory::class); $customerRepository = $obj->get(\Magento\Customer\Api\CustomerRepositoryInterface::class); $storeManager = $obj->get(\Magento\Store\Model\StoreManagerInterface::class); $addressFactory = $obj->get(\Magento\Customer\Api\Data\AddressInterfaceFactory::class); $addressRepository = $obj->get(\Magento\Customer\Api\AddressRepositoryInterface::class); $websiteId = $storeManager->getWebsite()->getId(); // Get customers $customerQuery = $sourcePdo->query("SELECT * FROM customer_entity"); $customers = $customerQuery->fetchAll(PDO::FETCH_ASSOC); foreach ($customers as $cust) { $email = $cust['email']; $entityId = $cust['entity_id']; // Check if already exists in Site B try { $customerRepository->get($email, $websiteId); echo "[SKIP] Customer exists: $email\n"; continue; } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {} // Create customer object $customer = $customerFactory->create(); $customer->setWebsiteId($websiteId) ->setEmail($email) ->setFirstname($cust['firstname']) ->setLastname($cust['lastname']) ->setGroupId($cust['group_id']) ->setCreatedAt($cust['created_at']) ->setData('password_hash', $cust['password_hash']); // Preserve password // Load EAV attributes $eavQuery = $sourcePdo->prepare("SELECT attribute_code, value FROM customer_entity_varchar cev JOIN eav_attribute ea ON cev.attribute_id = ea.attribute_id WHERE entity_id = ?"); $eavQuery->execute([$entityId]); foreach ($eavQuery->fetchAll(PDO::FETCH_ASSOC) as $attr) { $customer->setData($attr['attribute_code'], $attr['value']); } $eavQueryText = $sourcePdo->prepare("SELECT attribute_code, value FROM customer_entity_text cet JOIN eav_attribute ea ON cet.attribute_id = ea.attribute_id WHERE entity_id = ?"); $eavQueryText->execute([$entityId]); foreach ($eavQueryText->fetchAll(PDO::FETCH_ASSOC) as $attr) { $customer->setData($attr['attribute_code'], $attr['value']); } $eavQueryInt = $sourcePdo->prepare("SELECT attribute_code, value FROM customer_entity_int cei JOIN eav_attribute ea ON cei.attribute_id = ea.attribute_id WHERE entity_id = ?"); $eavQueryInt->execute([$entityId]); foreach ($eavQueryInt->fetchAll(PDO::FETCH_ASSOC) as $attr) { $customer->setData($attr['attribute_code'], $attr['value']); } try { $savedCustomer = $customerRepository->save($customer); echo "[IMPORTED] $email\n"; } catch (\Exception $e) { echo "[ERROR] $email => " . $e->getMessage() . "\n"; continue; } // Now get default address for this customer $addrQuery = $sourcePdo->prepare("SELECT * FROM customer_address_entity WHERE parent_id = ?"); $addrQuery->execute([$entityId]); $addresses = $addrQuery->fetchAll(PDO::FETCH_ASSOC); foreach ($addresses as $addr) { $addressId = $addr['entity_id']; $address = $addressFactory->create(); $address->setCustomerId($savedCustomer->getId()); $address->setFirstname($addr['firstname']); $address->setLastname($addr['lastname']); $address->setStreet([$addr['street']]); $address->setCity($addr['city']); $address->setPostcode($addr['postcode']); $address->setTelephone($addr['telephone']); $address->setCountryId($addr['country_id']); $address->setRegionId($addr['region_id']); $address->setIsDefaultBilling((bool)$addr['is_default_billing']); $address->setIsDefaultShipping((bool)$addr['is_default_shipping']); try { $addressRepository->save($address); echo " └ Imported address for $email\n"; } catch (\Exception $e) { echo "[ADDR ERROR] $email => " . $e->getMessage() . "\n"; } } } 

The following customer data has been migrated: Email, First Name, Last Name, Group ID, Creation Date, all EAV fields (such as DOB, Gender, Tax/VAT, etc.), Password Hash for seamless login, and Billing/Shipping address details.

Make sure your website_id is same (usually 1) Test first with a few customers using a LIMIT in the SQL query Always backup both site database before running

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.