Magento 2 Payment Adapter Configuration

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.


Posted

in

,

by

Comments

Leave a Reply