In this article we will go through configuration for the Payment Method Adapter class. Also, we are going to review the class dependencies (validators, commands, value handlers and etc.) for Payment Service Provider integration. I am going to use Realex Payments Provider as an example for the article.
Introduction
In the previous article we have reviewed Command Interfaces and Service Classes from the Payment Gateway API (Magento/Payment/Gateway directory). Also, we know how to configure Payment Commands in the custom di.xml
configuration file in order to handle and prepare request data. Once prepared, the request data has been sent to the Payment Service Provider.
In order to deal with request/response calls Magento 2 has introduced Magento\Payment\Model\Method\Adapter
(further in this article I am going to use Adapter
) class. The class is an alternative and right way of configuring custom Payment integration.
Dmitro Kvashnin (Magento 2 developer), one of the Payment Gateway API authors, mentioned below the Magento 2 Payment Gateway API article:+
Pronko\Realex\Model\Remote implementation is not required, as a typical payment gateway can be configured through \Magento\Payment\Model\Method\Adapter instance (as a virtual type), as it already contains all the required arguments
This great news means that custom Payment Method class (typically extends Magento\Payment\Model\Method\AbstractMethod
class) is no longer needed.
Further, in this article we are going to cover 3 main questions:
- What is Payment Adapter class?
- How to configure Payment Adapter class?
- Why it’s important to know this?
Payment Adapter Class
The Payment Adapter class is a typical Facade class (you may also like to find more information about Facade Design Pattern
) introduced for Payment Service Provider communications. The Payment Adapter class delegates almost all its public calls to its configured sub-commands or classes. And, there are no more $_canCheckout, $_canCapture, $_canFetchTransactionInfo and other class variables exists compare to its neighbor Magento\Payment\Model\Method\AbstractMethod
class.
Here I should put my statement into the big box:
All features of the Payment Service Provider integration are now configurable via di.xml and
config.xml
files.
In order to configure the Adapter
class let’s overview its class dependencies.
Class Dependencies
In order to understand class dependencies it is always a good idea to look into __construct()
method arguments:
[php]
namespace Magento\Payment\Model\Method;
use Magento\Framework\Event\ManagerInterface;
use Magento\Payment\Gateway\Command\CommandPoolInterface;
use Magento\Payment\Gateway\Config\ValueHandlerPoolInterface;
use Magento\Payment\Gateway\Data\PaymentDataObjectFactory;
use Magento\Payment\Gateway\Validator\ValidatorPoolInterface;
use Magento\Payment\Model\MethodInterface;
/* more uses */
class Adapter implements MethodInterface
{
/* CODE */
public function __construct(
ManagerInterface $eventManager,
ValueHandlerPoolInterface $valueHandlerPool,
ValidatorPoolInterface $validatorPool,
CommandPoolInterface $commandPool,
PaymentDataObjectFactory $paymentDataObjectFactory,
$code,
$formBlockType,
$infoBlockType
) {
/* CODE */
}
/* Even more CODE */
}
[/php]
And here is a table with the Adapter
class dependencies:
Dependency | Description |
---|---|
ManagerInterface | The dependency is used to notify listeners about the payment_method_is_active event. This is an extension point for Adapter::isAvailable() method. |
ValueHandlerPoolInterface | Used to provide Magento\Payment\Gateway\Config\ValueHandlerInterface implementation for getting configuration data. |
ValidatorPoolInterface | Used to provide Magento\Payment\Gateway\Validator\ValidatorInterface implementation for further validation of the Payment Adapter |
CommandPoolInterface | Used to provide Magento\Payment\Gateway\CommandInterface implementation for requests/response processing. Refer to Command Interfaces for more information. |
PaymentDataObjectFactory | Used to create PaymentDataObject class. The class is used as a Data provider in ValueHandlerInterface , ValidatorInterface and CommandInterface related classes. |
Once the ValidatorPoolInterface
dependency is passed into the Adapter
class, the class expects to have validator classes for country (Adapter::canUseForCountry()
method), currency (Adapter::canUseForCurrency()
method) and global (Adapter::validate()
method).
All calls to the ValidatorPoolInterface are wrapped with try/catch block, so even if any of the validators mentioned above are missing, it means that validation has been successfully passed.
[php]
try {
$validator = $this->validatorPool->get(‘country’);
} catch (NotFoundException $e) {
return true;
}
[/php]
Configuration in Details
The Payment Adapter class configuration might look huge from first glance. In order to configure Adapter
class the realexRemoteMethodAdapter virtual type that extends Adapter
class. This configuration should be located in the di.xml
configuration file.
Payment Method Adapter Main Configuration
Here is a declaration for the realexRemoteMethodAdapter virtual type:
[php]
<virtualType name="realexRemoteMethodAdapter" type="Magento\Payment\Model\Method\Adapter">
<arguments>
<argument name="code" xsi:type="const">Pronko\Realex\Model\Remote::METHOD_CODE</argument>
<argument name="valueHandlerPool" xsi:type="object">RealexValueHandlerPool</argument>
<argument name="validatorPool" xsi:type="object">RealexValidatorPool</argument>
<argument name="commandPool" xsi:type="object">RealexCommandPool</argument>
<argument name="formBlockType" xsi:type="object">Magento\Payment\Block\Form\Cc</argument>
<argument name="infoBlockType" xsi:type="object">Magento\Payment\Block\Info\Cc</argument>
</arguments>
</virtualType>
[/php]
The realexRemoteMethodAdapter virtual type is configured with 3 (valueHandlerPool, validatorPool, commandPool) virtual types. In addition to these parameters code should be set (according to the Payment integration). The formBlockType and infoBlockType arguments are also set.
Value Handler Pool Configuration
The RealexValueHandlerPool declaration might look like the following:
[php]
<virtualType name="RealexConfig" type="Magento\Payment\Gateway\Config\Config">
<arguments>
<argument name="methodCode" xsi:type="const">Pronko\Realex\Model\Remote::METHOD_CODE</argument>
</arguments>
</virtualType>
<virtualType name="RealexConfigValueHandler" type="Magento\Payment\Gateway\Config\ConfigValueHandler">
<arguments>
<argument name="configInterface" xsi:type="object">RealexConfig</argument>
</arguments>
</virtualType>
<virtualType name="RealexValueHandlerPool" type="Magento\Payment\Gateway\Config\ValueHandlerPool">
<arguments>
<argument name="handlers" xsi:type="array">
<item name="default" xsi:type="string">RealexConfigValueHandler</item>
</argument>
</arguments>
</virtualType>
[/php]
Since the Magento\Payment\Gateway\Config\ValueHandlerPool
class expects at least default handler is configured, the RealexConfigValueHandler virtual type is used with the RealexConfig virtual type as default handler.
Validator Pool Configuration
When it comes to RealexValidatorPool virtual type the configuration for global validator (Adapter::validate()
method) might look like the following:
[php]
<virtualType name="CountryValidator" type="Magento\Payment\Gateway\Validator\CountryValidator">
<arguments>
<argument name="config" xsi:type="object">RealexConfig</argument>
</arguments>
</virtualType>
<virtualType name="RealexGlobalValidator" type="Magento\Payment\Gateway\Validator\ValidatorComposite">
<arguments>
<argument name="validators" xsi:type="array">
<item name="country" xsi:type="string">CountryValidator</item>
</argument>
</arguments>
</virtualType>
<virtualType name="RealexValidatorPool" type="Magento\Payment\Gateway\Validator\ValidatorPool">
<arguments>
<argument name="validators" xsi:type="array">
<item name="global" xsi:type="string">RealexGlobalValidator</item>
</argument>
</arguments>
</virtualType>
[/php]
In this case the RealexGlobalValidator virtual type extends the Magento\Payment\Gateway\Validator\ValidatorComposite
class. The ValidatorComposite
class allows to extend global validators with more than 1 validator. As for sake of example only country validator is configured.
Command Pool Configuration
And finally the RealexCommandPool virtual type is configured with one capture command.
[php]
<virtualType name="RealexCaptureGatewayCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
<arguments>
<argument name="requestBuilder" xsi:type="object">Pronko\Realex\Model\Remote\Request\Capture</argument>
<argument name="handler" xsi:type="object">Pronko\Realex\Model\Remote\Response\Capture</argument>
<argument name="transferFactory" xsi:type="object">Pronko\Realex\Gateway\Http\TransferFactory</argument>
</arguments>
</virtualType>
<virtualType name="RealexCommandPool" type="Magento\Payment\Gateway\Command\CommandPool">
<arguments>
<argument name="commands" xsi:type="array">
<item name="capture" xsi:type="string">RealexCaptureGatewayCommand</item>
</argument>
</arguments>
</virtualType>
[/php]
The RealexCaptureGatewayCommand virtual type extends the Magento\Payment\Gateway\Command\GatewayCommand
class and enables an encapsulated infrastructure during capture command execution.
Payment Gateway Configuration File
The Magento\Payment\Model\Method\Adapter
class also allows you to store all your Payment Gateway “cans” and “is” features in the configuration. Compare to the Magento\Payment\Model\Method\AbstractMethod
where every single child Method class should list all these ($_canCapture, $_isGateway, etc.) variables again and again, Payment Service Provider related features should be listed in the config.xml
file.
Here is an example of the Payment configuration:
[php]
Here is an example of the Payment configuration:
<default>
<payment>
<realex>
<title>Credit or Debit Card (Realex)</title>
<cgi_url>https://payment-gateway-url/</cgi_url>
<model>realexRemoteMethodAdapter</model>
<is_gateway>1</is_gateway>
<can_order>1</can_order>
<can_use_checkout>1</can_use_checkout>
<can_capture>1</can_capture>
<can_use_for_multishipping>1</can_use_for_multishipping>
<!– more settings –>
</realex>
</payment>
</default>
[/php]
Do you really should know it?
The short answer is Yes. First of all, once you will start integration with the Payment Service Provider you should definitely check for the out-of-box features and frameworks in Magento 2. Since Magento 2 has Payment Gateway API, it will help to implement payment integration faster (of course it depends on various factors, e.g. covering Payment integration with Unit and other Tests, enabling all set of Payment Gateway features, etc.).
Going forward, Payment-related modules in the Magento 2 Community Edition are going to be refactored. The Payment Gateway API and Magento\Payment\Model\Method\Adapter
class will be used instead of old-fashioned Magento\Payment\Model\Method\AbstractMethod
and Magento\Payment\Model\Method\Cc
classes. It means that sometime later these old-fashioned classes might be removed in future Magento 2.x releases.
Summary
In this article we reviewed Payment Adapter Class and its dependencies from the Magento\Payment module. The class allows to configure different validators, commands and value handlers for proper integration with Payment Service Providers. In addition to this, we went through configuration of custom (by using virtual types) Payment Adapter class. For this article I was using Realex Payment Provider, however these examples allow you to work with other Payment Providers.
I also recommend to read Magento 2 Payment Gateway API article where I go through Payment Service Contracts/API of the Magento/Payment module.
Best of luck.
I am looking forward for your feedback and any comments on how I can share more valuable to you information.
Leave a Reply
You must be logged in to post a comment.