Magento 2 Customer API: Create Custom API For Customer

Wishusucess Magento 2 Customer API helps Magento developers to generate an Application Programming Interface for their own use.

Magento 2 Customer API Address

By adding this customer API you will be able to change customer email, change the password by customer id and send the notification on mail after changing the further data.

Also, Magento customers can change address delete the address, and save the new address from other websites or servers using this Customer application programmable iinterface.

This Customer API is a set of routines, protocols, and other tools which helps developer to get and post the data from other application. Using this API also help application developer to initiate the program to perform the action from other websites successfully.

Wishuscess Magento Development has successfully developed a module to customize the Magento 2 customer.

 

Magento 2 Customer API Module Customization

In order to develop a custom customer API in Magento, we have to create a module and that module needs to create some files.

We need to create some model classes for Account Management and Resource Model for Address Repository which will help you to manage the customer address field.

app/code/Wishusucess/Customer/registration.php

app/code/Wishusucess/Customer/etc/module.xml

app/code/Wishusucess/Customer/etc/di.xml

app/code/Wishusucess/Customer/etc/webapi.xml

app/code/Wishusucess/Customer/Model/AccountManagement.php

app/code/Wishusucess/Customer/Model/ResourceModel/AddressRepository.php

app/code/Wishusucess/Customer/Api/AccountManagementInterface.php

app/code/Wishusucess/Customer/Api/AddressRepositoryInterface.php

 

Register Wishuscess Customer API

app/code/Wishusucess/Customer/registration.php

<?php
/**
*
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_Customer
* Website: http://www.wishusucess.com/
*/
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Wishusucess_Customer',
__DIR__
);

 

Create Wishuscess Module XML

app/code/Wishusucess/Customer/etc/module.xml

<?xml version="1.0"?>
/**
*
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_Customer
* Website: http://www.wishusucess.com/
*/
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Wishusucess_Customer" setup_version="1.0.0">
<sequence>
<module name="Wishusucess_Customer" />
</sequence>
</module>
</config>

 

Define Dependency Injection

app/code/Wishusucess/Customer/etc/di.xml

<?xml version="1.0"?>
/**
*
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_Customer
* Website: http://www.wishusucess.com/
*/
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Wishusucess\Customer\Api\AddressRepositoryInterface" type="Wishusucess\Customer\Model\ResourceModel\AddressRepository"/>
<preference for="Wishusucess\Customer\Api\AccountManagementInterface" type="Wishusucess\Customer\Model\AccountManagement"/>
<virtualType name="Wishusucess\Customer\Model\Api\Address\SearchCriteria\CollectionProcessor\CustomerSortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor">
<arguments>
<argument name="fieldMapping" xsi:type="array">
<item name="id" xsi:type="string">entity_id</item>
</argument>
<argument name="defaultOrders" xsi:type="array">
<item name="id" xsi:type="string">DESC</item>
</argument>
</arguments>
</virtualType>
<virtualType name="Wishusucess\Customer\Model\Api\Address\SearchCriteria\CustomerCollectionProcessor" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor">
<arguments>
<argument name="processors" xsi:type="array">
<item name="sorting" xsi:type="object">Wishusucess\Customer\Model\Api\Address\SearchCriteria\CollectionProcessor\CustomerSortingProcessor</item>
</argument>
</arguments>
</virtualType>
<type name="Wishusucess\Customer\Model\ResourceModel\AddressRepository">
<arguments>
<argument name="collectionProcessor" xsi:type="object">Wishusucess\Customer\Model\Api\Address\SearchCriteria\CustomerCollectionProcessor</argument>
</arguments>
</type>
</config>

 

Create Magento 2 Customer Web API

This file basically decides the route URL of your API, so here we have created route id is /V1/wishusucess/customers/me/address and this API using put method.

app/code/Wishusucess/Customer/etc/webapi.xml

<?xml version="1.0"?>
/**
*
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_Customer
* Website: http://www.wishusucess.com/
*/
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route url="/V1/wishusucess/customers/me/address" method="PUT">
<service class="Wishusucess\Customer\Api\AddressRepositoryInterface" method="save"/>
<resources>
<resource ref="self"/>
</resources>
<data>
<parameter name="customerId" force="true">%customer_id%</parameter>
</data>
</route>
<route url="/V1/wishusucess/customers/me/address/:addressId" method="DELETE">
<service class="Wishusucess\Customer\Api\AddressRepositoryInterface" method="deleteById"/>
<resources>
<resource ref="self"/>
</resources>
<data>
<parameter name="customerId" force="true">%customer_id%</parameter>
</data>
</route>
<route url="/V1/wishusucess/customers/me/address/:addressId" method="GET">
<service class="Wishusucess\Customer\Api\AddressRepositoryInterface" method="getById"/>
<resources>
<resource ref="self"/>
</resources>
<data>
<parameter name="customerId" force="true">%customer_id%</parameter>
</data>
</route>
<route url="/V1/wishusucess/customers/me/address/search" method="GET">
<service class="Wishusucess\Customer\Api\AddressRepositoryInterface" method="getList"/>
<resources>
<resource ref="self"/>
</resources>
<data>
<parameter name="customerId" force="true">%customer_id%</parameter>
</data>
</route>
<route url="/V1/wishusucess/customers/me/changeEmail" method="POST">
<service class="Wishusucess\Customer\Api\AccountManagementInterface" method="changeEmail"/>
<resources>
<resource ref="self"/>
</resources>
<data>
<parameter name="customerId" force="true">%customer_id%</parameter>
</data>
</route>
<route url="/V1/wishusucess/customers/me/changePassword" method="POST">
<service class="Wishusucess\Customer\Api\AccountManagementInterface" method="changePasswordById"/>
<resources>
<resource ref="self"/>
</resources>
<data>
<parameter name="customerId" force="true">%customer_id%</parameter>
</data>
</route>
</routes>

 

Create Model Account Management For API

Here, you have to decide what action you are going to perform so here we have created a method to change the email and change password by ID and then send email notification mail to the customer.

app/code/Wishusucess/Customer/Model/AccountManagement.php

<?php 
/**
*
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_Customer
* Website: http://www.wishusucess.com/
*/
declare(strict_types=1);

namespace Wishusucess\Customer\Model;

use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\AuthenticationInterface;
use Magento\Customer\Model\EmailNotificationInterface;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\LocalizedException;
use Wishusucess\Customer\Api\AccountManagementInterface;

class AccountManagement implements AccountManagementInterface
{
/**
* @var AuthenticationInterface
*/
private $authentication;

/**
* @var CustomerRepositoryInterface
*/
private $customerRepository;

/**
* @var EmailNotificationInterface
*/
private $emailNotification;

/**
* @var \Magento\Customer\Api\AccountManagementInterface
*/
private $accountManagement;

/**
* @param AuthenticationInterface $authentication
* @param CustomerRepositoryInterface $customerRepository
* @param \Magento\Customer\Api\AccountManagementInterface $accountManagement
* @param EmailNotificationInterface $emailNotification
*/
public function __construct(
AuthenticationInterface $authentication,
CustomerRepositoryInterface $customerRepository,
\Magento\Customer\Api\AccountManagementInterface $accountManagement,
EmailNotificationInterface $emailNotification
) {
$this->authentication = $authentication;
$this->customerRepository = $customerRepository;
$this->emailNotification = $emailNotification;
$this->accountManagement = $accountManagement;
}

/**
* @inheritDoc
*/
public function changeEmail($customerId, $newEmail, $currentPassword)
{
$this->authentication->authenticate($customerId, $currentPassword);
$customer = $this->customerRepository->getById($customerId);
$origEmail = $customer->getEmail();
if ($origEmail == $newEmail) {
throw new LocalizedException(__('Cannot change the same email.'));
}
$customer->setEmail($newEmail);
$savedCustomer = $this->customerRepository->save($customer);
//Sending notify email to customer
$this->sendEmailNotification($savedCustomer, $origEmail);
return true;
}

/**
* @inheritDoc
*/
public function changePasswordById($customerId, $currentPassword, $newPassword, $confirmPassword)
{
$customer = $this->customerRepository->getById($customerId);
if ($newPassword != $confirmPassword) {
throw new InputException(__('Password confirmation doesn\'t match entered password.'));
}
$this->accountManagement->changePasswordById($customerId, $currentPassword, $newPassword);
//Sending notify email to customer
$this->sendEmailNotification($customer, $customer->getEmail(), true);
return true;
}

/**
* @param $savedCustomer
* @param $origCustomerEmail
* @param bool $isPasswordChanged
*/
private function sendEmailNotification($savedCustomer, $origCustomerEmail, $isPasswordChanged = false)
{
$this->emailNotification->credentialsChanged(
$savedCustomer,
$origCustomerEmail,
$isPasswordChanged
);
}
}

 

Resource Model Class for Address Repository

Now, this resource model class will allow you to add the address edit the address, and delete the address using this Magento 2 customer application programmable interface from another websites.

app/code/Wishusucess/Customer/Model/ResourceModel/AddressRepository.php

<?php
/**
*
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_Customer
* Website: http://www.wishusucess.com/
*/
declare(strict_types=1);

namespace Wishusucess\Customer\Model\ResourceModel;

use Magento\Customer\Api\Data\AddressInterface;
use Magento\Customer\Api\Data\AddressSearchResultsInterfaceFactory;
use Magento\Customer\Model\AddressRegistry;
use Magento\Customer\Model\CustomerRegistry;
use Magento\Customer\Model\ResourceModel\Address;
use Magento\Customer\Model\ResourceModel\Address\Collection;
use Magento\Customer\Model\ResourceModel\Address\CollectionFactory;
use Magento\Customer\Model\ResourceModel\AddressRepository as MageAddressRepository;
use Magento\Customer\Model\ResourceModel\CustomerRepository;
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\StateException;
use Wishusucess\Customer\Api\AddressRepositoryInterface;

class AddressRepository implements AddressRepositoryInterface
{
/**
* @var CustomerRepository
*/
private $customerRepository;

/**
* @var MageAddressRepository
*/
private $mageAddressRepository;

/**
* @var AddressRegistry
*/
private $addressRegistry;

/**
* @var CustomerRegistry
*/
private $customerRegistry;

/**
* @var Address
*/
private $addressResourceModel;

/**
* @var AddressSearchResultsInterfaceFactory
*/
private $searchResultsFactory;

/**
* @var CollectionProcessorInterface
*/
private $collectionProcessor;

/**
* @var CollectionFactory
*/
private $addressCollectionFactory;

/**
* @var JoinProcessorInterface
*/
private $extensionAttributesJoinProcessor;

/**
* AddressRepository constructor.
* @param CustomerRepository $customerRepository
* @param MageAddressRepository $mageAddressRepository
* @param AddressRegistry $addressRegistry
* @param CustomerRegistry $customerRegistry
* @param Address $addressResourceModel
* @param AddressSearchResultsInterfaceFactory $searchResultsFactory
* @param CollectionProcessorInterface $collectionProcessor
* @param CollectionFactory $addressCollectionFactory
* @param JoinProcessorInterface $extensionAttributesJoinProcessor
*/
public function __construct(
CustomerRepository $customerRepository,
MageAddressRepository $mageAddressRepository,
AddressRegistry $addressRegistry,
CustomerRegistry $customerRegistry,
Address $addressResourceModel,
AddressSearchResultsInterfaceFactory $searchResultsFactory,
CollectionProcessorInterface $collectionProcessor,
CollectionFactory $addressCollectionFactory,
JoinProcessorInterface $extensionAttributesJoinProcessor
) {
$this->customerRepository = $customerRepository;
$this->mageAddressRepository = $mageAddressRepository;
$this->addressRegistry = $addressRegistry;
$this->customerRegistry = $customerRegistry;
$this->addressResourceModel = $addressResourceModel;
$this->searchResultsFactory = $searchResultsFactory;
$this->collectionProcessor = $collectionProcessor;
$this->addressCollectionFactory = $addressCollectionFactory;
$this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
}

/**
* @inheritDoc
*/
public function save($customerId, $address)
{
if ($address->getId()) {
if (!in_array($address->getId(), $this->getAddressCollectionByCustomerId($customerId)->getAllIds())) {
throw new NoSuchEntityException(__('The address does not belong to the current customer.'));
}
}

$address->setCustomerId($customerId)->setRegion($address->getRegion());
$this->validateData($address);

try {
$this->mageAddressRepository->save($address);
} catch (LocalizedException $e) {
throw new LocalizedException(__('Cannot save address.'));
}

return $address;
}

/**
* @inheritDoc
*/
public function deleteById($customerId, $addressId)
{
$addressCollection = $this->getAddressCollectionByCustomerId($customerId);

if (in_array($addressId, $addressCollection->getAllIds())) {
$address = $this->addressRegistry->retrieve($addressId);

try {
$addressCollection->removeItemByKey($addressId);
$this->addressResourceModel->delete($address);
$this->addressRegistry->remove($addressId);
return true;
} catch (\Exception $e) {
throw new StateException(__('Cannot remove the address.'));
}
} else {
throw new NoSuchEntityException(__('The address does not belong to the current customer.'));
}
}

/**
* @inheritDoc
*/
public function getById($customerId, $addressId)
{
if (in_array($addressId, $this->getAddressCollectionByCustomerId($customerId)->getAllIds())) {
$address = $this->addressRegistry->retrieve($addressId);
return $address->getDataModel();
} else {
throw new NoSuchEntityException(__('The address does not belong to the current customer.'));
}
}

/**
* @inheritDoc
*/
public function getList($customerId, \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
{
$searchResults = $this->searchResultsFactory->create();
$customerModel = $this->customerRegistry->retrieve($customerId);
$searchResults->setSearchCriteria($searchCriteria);
/** @var Collection $collection */
$collection = $this->addressCollectionFactory->create()->setCustomerFilter($customerModel);
$this->extensionAttributesJoinProcessor->process($collection, AddressInterface::class);
$this->collectionProcessor->process($searchCriteria, $collection);
$searchResults->setTotalCount($collection->getSize());
$addresses = [];
/** @var \Magento\Customer\Model\Address $addressModel */
foreach ($collection as $addressModel) {
$addresses[] = $addressModel->getDataModel();
}
$searchResults->setItems($addresses);
return $searchResults;
}

/**
* @param int $customerId
* @return Collection
* @throws NoSuchEntityException
*/
private function getAddressCollectionByCustomerId($customerId)
{
$customerModel = $this->customerRegistry->retrieve($customerId);
return $customerModel->getAddressesCollection();
}

/**
* @param AddressInterface $address
* @throws InputException
*/
private function validateData(AddressInterface $address)
{
if (empty($address->getFirstname())) {
$this->throwException(__('Please enter the first name.'));
}
if (empty($address->getLastname())) {
$this->throwException(__('Please enter the last name.'));
}
if (empty($address->getStreet())) {
$this->throwException(__('Please enter the street.'));
}
if (empty($address->getCity())) {
$this->throwException(__('Please enter the city.'));
}

if (empty($address->getTelephone())) {
$this->throwException(__('Please enter the phone number.'));
}

$countryId = $address->getCountryId();

if (empty($address->getPostcode())) {
$this->throwException(__('Please enter the zip/postal code.'));
}
if (empty($countryId)) {
$this->throwException(__('Please enter the country.'));
}
if (empty($address->getRegionId())) {
$this->throwException(__('Please enter the state/province.'));
}
}

/**
* @param $message
* @throws InputException
*/
private function throwException($message)
{
throw new InputException($message);
}
}

 

Magento 2 Customer API For Account Management

Now, this block class of customer API will help to coordinated and processed the data using the function of changeEmail() and changePasswordById() by passing the parameter of customer id, new email, current password, and confirm password.

app/code/Wishusucess/Customer/Api/AccountManagementInterface.php

<?php
/**
*
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_Customer
* Website: http://www.wishusucess.com/
*/
namespace Wishusucess\Customer\Api;

/**
* Interface AccountManagementInterface
* @package Wishusucess\Customer\Api
* @api
*/
interface AccountManagementInterface
{
/**
* @param int $customerId
* @param string $newEmail
* @param string $currentPassword
* @return bool true on success
* @throws \Magento\Framework\Exception\InputException
* @throws \Magento\Framework\Exception\InvalidEmailOrPasswordException
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\State\InputMismatchException
* @throws \Magento\Framework\Exception\State\UserLockedException
*/
public function changeEmail($customerId, $newEmail, $currentPassword);

/**
* Change customer password.
*
* @param int $customerId
* @param string $currentPassword
* @param string $newPassword
* @param string $confirmPassword
* @return bool true on success
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function changePasswordById($customerId, $currentPassword, $newPassword, $confirmPassword);
}

 

Magento 2 Customer API Address Repository

app/code/Wishusucess/Customer/Api/AddressRepositoryInterface.php

<?php
/**
*
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_Customer
* Website: http://www.wishusucess.com/
*/
namespace Wishusucess\Customer\Api;

/**
* Interface AddressRepositoryInterface
* @package Wishusucess\Customer\Api
* @api
*/
interface AddressRepositoryInterface
{
/**
* Update address for the given customerId.
*
* @param int $customerId
* @param \Magento\Customer\Api\Data\AddressInterface $address
* @return \Magento\Customer\Api\Data\AddressInterface
* @throws \Magento\Framework\Exception\InputException
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function save($customerId, $address);

/**
* Delete address by the given $addressId.
*
* @param int $customerId
* @param int $addressId
* @return bool true on success
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\StateException
*/
public function deleteById($customerId, $addressId);

/**
* Retrieve address by $addressId.
*
* @param int $customerId
* @param int $addressId
* @return \Magento\Customer\Api\Data\AddressInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getById($customerId, $addressId);

/**
* Retrieve address list
*
* @param int $customerId
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
* @return \Magento\Customer\Api\Data\AddressSearchResultsInterface
*/
public function getList($customerId, \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria);
}

 

Download Customer API

 

Related Post:

ContactUs REST API: Create Magento 2 Custom Contact Us REST API

Checkout REST API: Get Checkout Data Using REST API Key in Magento

Categories API Key: Get All Category List Through API Key in Magento 2

 

Recommended Post:

Magento 2.4 Installation Guide: How to Install Magento 2.4.2

SEO Packages: How Much Do SEO Packages Cost in India, SEO Pricing