3

I'm new to Magento and i'm implementing a custom payment method in magento2.1 but i'm completely lost. The needed flow of information is as follow:

  1. Customer goes to checkout and enters all information and goes to the payment method where he will select my custom method and press 'Place Order' button.

  2. After pressing the button i must capture the information of the order, the products, the amount, the shipping address and add other information like ('signature' - a hash for verification, 'urlResponse' and 'urlConfirmation' and some others) and then i need to send those parameters in a Post request to the Gateway Provider URL. I do not need to make validations of any kind, just grab the data, add some more and send it.

After reading the tutorials of Max Pronko

https://www.maxpronko.com/blog/magento-2-payment-gateway-api

(i couldn't copy the other link, because of lack of points, but at the end of this one there is a reference to the other one).

I tried to implement it but i haven't had luck. As i understand, after pressing 'Place Order' button the request is send to a capture method where i can perform the necessary logic and then create a TransferObject and then send it (how?).

This is the structure i have:

custom payment file structure

in Vendor/PayU/etc/frontend/di.xml i have:

<?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\Payment\Gateway\Command\CommandPoolInterface" type="Magento\Payment\Gateway\Command\CommandPool" />

    <virtualType name="Vendor\PayU\Model\Payment\Command\CaptureGateway" type="Magento\Payment\Gateway\Command\GatewayCommand">
        <arguments>
            <argument name="requestBuilder" xsi:type="object">Vendor\PayU\Model\Payment\Request\Capture</argument>
        </arguments>
    </virtualType>

    <virtualType name="Vendor\PayU\Gateway\Command\CommandPool" type="Magento\Payment\Gateway\Command\CommandPool">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="capture" xsi:type="string">Vendor\PayU\Model\Payment\Command\CaptureGateway</item>
            </argument>
        </arguments>
    </virtualType>

    <virtualType name="PayUPaymentMethodAdapter" type="Magento\Payment\Model\Method\Adapter">
        <arguments>
            <argument name="code" xsi:type="const">Vendor\PayU\Model\Payment::METHOD_CODE</argument>
            <argument name="valueHandlerPool" xsi:type="object">PayUValueHandlerPool</argument>
            <argument name="validatorPool" xsi:type="object">PayUValidatorPool</argument>
            <argument name="commandPool" xsi:type="object">PayUCommandPool</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>

    <virtualType name="PayUConfig" type="Magento\Payment\Gateway\Config\Config">
        <arguments>
            <argument name="methodCode" xsi:type="const">Vendor\PayU\Model\Payment::METHOD_CODE</argument>
        </arguments>
    </virtualType>

    <virtualType name="PayUConfigValueHandler" type="Magento\Payment\Gateway\Config\ConfigValueHandler">
        <arguments>
            <argument name="configInterface" xsi:type="object">PayUConfig</argument>
        </arguments>
    </virtualType>

    <virtualType name="PayUValueHandlerPool" type="Magento\Payment\Gateway\Config\ValueHandlerPool">
        <arguments>
            <argument name="handlers" xsi:type="array">
                <item name="default" xsi:type="string">PayUConfigValueHandler</item>
            </argument>
        </arguments>
    </virtualType>

    <virtualType name="CountryValidator" type="Magento\Payment\Gateway\Validator\CountryValidator">
        <arguments>
            <argument name="config" xsi:type="object">PayUConfig</argument>
        </arguments>
    </virtualType>

    <virtualType name="PayUGlobalValidator" 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="PayUValidatorPool" type="Magento\Payment\Gateway\Validator\ValidatorPool">
        <arguments>
            <argument name="validators" xsi:type="array">
                <item name="global" xsi:type="string">PayUGlobalValidator</item>
            </argument>
        </arguments>
    </virtualType>

    <virtualType name="PayUCaptureGatewayCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
        <arguments>
            <argument name="requestBuilder" xsi:type="object">Vendor\PayU\Model\Payment\Request\Capture</argument>
            <argument name="handler" xsi:type="object">Vendor\PayU\Model\Payment\Response\Capture</argument>
            <argument name="transferFactory" xsi:type="object">Vendor\PayU\Gateway\Http\TransferFactory</argument>
        </arguments>
    </virtualType>

    <virtualType name="PayUCommandPool" type="Magento\Payment\Gateway\Command\CommandPool">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="capture" xsi:type="string">PayUCaptureGatewayCommand</item>
            </argument>
        </arguments>
    </virtualType>

    <type name="Vendor\PayU\Model\Payment">
        <arguments>
            <argument name="commandPool" xsi:type="object">Vendor\PayU\Gateway\Command\CommandPool</argument>
        </arguments>
    </type>
</config>

In Vendor/PayU/Model/Payment.php i have:

<?php

namespace Vendor\PayU\Model;

use Magento\Payment\Model\InfoInterface;
use Magento\Payment\Gateway\Command\CommandPoolInterface;
use Magento\Payment\Gateway\CommandInterface;

class Payment implements MethodInterface, PaymentMethodInterface
{
    /**
     * @var \Magento\Payment\Gateway\Command\CommandPoolInterface
    */
    protected $commandPool;

    /**
     * @var CommandPoolInterface
    */
    public function __construct(CommandPoolInterface $commandPool) {
        $this->commandPool = $commandPool;
    }

    /**
     * @param InfoInterface $payment
     * @param float $amount
     * @return $this
     * @api
    */
    public function capture(InfoInterface $payment, $amount)
    {
        /** @var CommandInterface $captureGatewayCommand */
        $captureGatewayCommand = $this->commandPool->get('capture');

        $captureGatewayCommand->execute([
            'payment' => $payment,
            'amount' => $amount
        ]);
    }     
}

Am i implementing the right classes? What other files do i need? I'd be gratefull if anyone could point me in the right direction.

A. Martz
  • 191
  • 3
  • 5

2 Answers2

0

Firstly, look at magento 2 official samples of modules. https://github.com/magento/magento2-samples/tree/2.1/sample-module-payment-gateway As I know you shouldn't have the real payment model. You just created the payment model in the di.xml. By code:

<virtualType name="PayUPaymentMethodAdapter" type="Magento\Payment\Model\Method\Adapter">
    <arguments>
        <argument name="code" xsi:type="const">Vendor\PayU\Model\Payment::METHOD_CODE</argument>
        <argument name="valueHandlerPool" xsi:type="object">PayUValueHandlerPool</argument>
        <argument name="validatorPool" xsi:type="object">PayUValidatorPool</argument>
        <argument name="commandPool" xsi:type="object">PayUCommandPool</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>

The PayUPaymentMethodAdapter is your payment model, which contains all needed data, you should just put all neeeded stuff (commands, validators, etc) and Magento will call the automatically. So the Magento\Payment\Model\Method\Adapter is just Facade which contains all payment module functionality. Magento 2 team uses Command Design pattern for all the payment actions like (void, capture, authorize). You should identify appropriate commands and the Magento\Payment\Model\Method\Adapter will call they automatically. Please, inspect the magento-samples payment method.

Mistery
  • 43
  • 1
  • 8
  • Thank you for your reply. I've been looking the example you recommeded me, but i haven't been able to make it work. It's throwing me the error in the next link: http://imgur.com/xpsmPfs . I asume the problem is in the arguments that have xsi:type="const" because if i comment those lines (all of virtualType) the page loads without a problem ( the url of the code is: http://imgur.com/fOa1bjn ). Do you know what might be the problem? Thanks. – A. Martz Oct 26 '16 at 18:26
  • Can you show me the class I mean \Vender\PayUGateway\Model\ConfigProvider Have you created the class with the constant PAYMENT_METHOD_CODE? Please, also verify namespace. It seems, magento can't find the constant. Please make sure that all is correct. – Mistery Oct 26 '16 at 18:35
  • This is my ConfigProvider.php : http://imgur.com/fnadayV I have checked the namespace. You might see that i've changed the Vendor name for question's purpose in both screenshots but i have written them correctly in both files in my "working" version. – A. Martz Oct 26 '16 at 18:59
0

In my 17 payment extensions for Magento 2 I have implemented the redirection from the Magento payment page to a payment service provider or to the Magento «checkout success» page in the following way: https://github.com/mage2pro/core/blob/2.12.5/Payment/view/frontend/web/mixin.js#L350-L401

Dmitrii Fediuk
  • 434
  • 9
  • 11