Question

I want to pass the custom REFERENCE_NUMBER to CyberSource So, I tried to override the class Magento\Cybersource\Gateway\Request\SilentOrder\TransactionDataBuilder using below steps

etc/di.xml

<preference for="Magento\Cybersource\Gateway\Request\SilentOrder\TransactionDataBuilder" type="<vendor>\<module>\Gateway\Request\SilentOrder\TransactionDataBuilder" />

vendor\module\Gateway\Request\SilentOrder\TransactionDataBuilder

<?php

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vender\Module\Gateway\Request\SilentOrder;

use Magento\Framework\Math\Random;
use Magento\Payment\Gateway\Helper\SubjectReader;
use Magento\Payment\Model\InfoInterface;

/**
 * Class TransactionDataBuilder
 */
class TransactionDataBuilder extends \Magento\Cybersource\Gateway\Request\SilentOrder\TransactionDataBuilder {

    /**
     * Builds ENV request
     *
     * @param array $buildSubject
     * @return array
     * @throws \InvalidArgumentException
     */
    public function build(array $buildSubject) {
        $paymentDO = SubjectReader::readPayment($buildSubject);

        return [
            self::TRANSACTION_UUID => $this->random->getRandomString(
                    self::RANDOM_LENGTH,
                    Random::CHARS_DIGITS
            ),
            self::REFERENCE_NUMBER => $this->getReferenceNumber($paymentDO->getPayment()),
            self::TRANSACTION_TYPE => $this->transactionType,
            self::AMOUNT => sprintf('%.2F', SubjectReader::readAmount($buildSubject)),
            self::CURRENCY => $paymentDO->getOrder()->getCurrencyCode(),
            self::LOCALE => substr($this->localeResolver->getLocale(), 0, 2)
        ];
    }

    /**
     * Returns reference number
     *
     * @param InfoInterface $payment
     * @return string
     */
    private function getReferenceNumber(InfoInterface $payment) {
        return 123456789;
    }

}

But it's not working in my case, I also tried to add code in etc/frontend/di.xml but, still the same result. Can anyone help me out?

Thanks in Advance.

No correct solution

OTHER TIPS

The first of all, you should not use preferences to override classes, the preferences should be used only for interfaces https://devdocs.magento.com/guides/v2.3/ext-best-practices/extension-coding/working-with-arch-bp.html.

There multiple ways of how to add custom Reference Number to request without using preference for TransactionDataBuilder class.

  1. Implement custom Reference Number Data Builder and use Magento TransactionDataBuilder as a composition to override the Reference Number. And you need to override di.xml configurations for all classes which use this builder.
  2. Implement custom Reference Number Data Builder and add it to all builder lists which are using Reference Number. As all builders return an array of data, the Reference Number value from Magento TransactionDataBuilder will be overwritten by your custom builder.

The second option is preferable as it easy to implement. You just need to create own custom builder:

namespace Vendor\Cybersource\Gateway\Request\SilentOrder;

use Magento\Payment\Gateway\Request\BuilderInterface;

class ReferenceNumberDataBuilder implements BuilderInterface
{
    private const REFERENCE_NUMBER = 'reference_number';

    public function build(array $buildSubject)
    {
        return [
            self::REFERENCE_NUMBER => 'Your custom reference number'
        ];
    }
}

And add it to all classes, which use existing Magento\Cybersource\Gateway\Request\SilentOrder\TransactionDataBuilder:

<type name="CybersourcePaymentTokenRequest">
    <arguments>
        <argument name="builders">
            <item name="billing_address" xsi:type="string">Magento\Cybersource\Gateway\Request\SilentOrder\BillingAddressDataBuilder</item>
            <item name="merchant" xsi:type="string">Magento\Cybersource\Gateway\Request\SilentOrder\MerchantDataBuilder</item>
            <item name="cc" xsi:type="string">Magento\Cybersource\Gateway\Request\SilentOrder\CcDataBuilder</item>
            <item name="token" xsi:type="string">CybersourceTokenTransactionBuilder</item>
            <item name="quote_data" xsi:type="string">Magento\Cybersource\Gateway\Request\SilentOrder\MerchantSecureDataBuilder</item>
            <item name="reference_number" xsi:type="string">Vendor\Cybersource\Gateway\Request\SilentOrder\ReferenceNumber</item>
        </argument>
    </arguments>
</type>

<type name="CybersourcePaymentSaleRequest">
    <arguments>
        <argument name="builders">
            <item name="merchant" xsi:type="string">Magento\Cybersource\Gateway\Request\SilentOrder\MerchantDataBuilder</item>
            <item name="payment_token" xsi:type="string">Magento\Cybersource\Gateway\Request\SilentOrder\PaymentTokenBuilder</item>
            <item name="sale" xsi:type="string">CybersourceSaleTransactionBuilder</item>
            <item name="reference_number" xsi:type="string">Vendor\Cybersource\Gateway\Request\SilentOrder\ReferenceNumber</item>
        </argument>
    </arguments>
</type>

<type name="CybersourcePaymentAuthorizeRequest">
    <arguments>
        <argument name="builders">
            <item name="merchant" xsi:type="string">Magento\Cybersource\Gateway\Request\SilentOrder\MerchantDataBuilder</item>
            <item name="payment_token" xsi:type="string">Magento\Cybersource\Gateway\Request\SilentOrder\PaymentTokenBuilder</item>
            <item name="authorize" xsi:type="string">CybersourceAuthorizeTransactionBuilder</item>
            <item name="reference_number" xsi:type="string">Vendor\Cybersource\Gateway\Request\SilentOrder\ReferenceNumber</item>
        </argument>
    </arguments>
</type>

The mentioned classes use virtual types based on Magento\Cybersource\Gateway\Request\SilentOrder\TransactionDataBuilder that's why you need to re-configure them.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top