magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.57k stars 9.32k forks source link

Magento 2.4.6 Braintree Custom Discount not added in Total and customer charged total amount #39293

Closed rahuldambare closed 1 month ago

rahuldambare commented 1 month ago

Summary

I am working on custom discount for Magento using this blog https://meetanshi.com/blog/add-custom-discount-in-magento-2/, but it is not adding that custom discount while sending request to payment Braintree Request not adding custom discount and customer charged full amount .

For Paypal I have made adjustment as per https://github.com/magento/magento2/issues/5735 , which is working fine . module-paypal/Model/Apiu/Nvp.php function callSetExpressCheckout at Line 812 add before "$response = $this->call(self::SET_EXPRESS_CHECKOUT, $request);" this snipped: $request['ITEMAMT'] = $request['AMT'] - $request['TAXAMT'] - $request['SHIPPINGAMT'];

Only facing issue with Braintree payment where custom discount is applied .

Magento version 2.4.6p3 PHP 8

Please check and provide solution for this as its affecting production sales. ` <?php

namespace MyModule\CoreCredit\Model\Quote\Address\Total;

class CustomDiscount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal {

/**
* @var \Magento\Framework\Pricing\PriceCurrencyInterface
*/
protected $_priceCurrency;
protected $resourceConnection;
protected $helper;

/**
 * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency [description]
 */
public function __construct(
    \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
    \Magento\Framework\App\ResourceConnection $resourceConnection,
    \PartSimple\CoreCredit\Helper\Data $helper
) {
    $this->_priceCurrency = $priceCurrency;
    $this->resourceConnection = $resourceConnection;
    $this->helper = $helper;
}

public function collect(
    \Magento\Quote\Model\Quote $quote,
    \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
    \Magento\Quote\Model\Quote\Address\Total $total
) {
    parent::collect($quote, $shippingAssignment, $total);

    if($this->helper->isValidStore() && $this->helper->isRemanItemExistsInCart()){
        $address = $shippingAssignment->getShipping()->getAddress();
        if($address->getAddressType() == 'billing'){
            return $this;
        }

        $baseDiscount = (float)$this->helper->calculateCreditbalance();
        $discount = $this->_priceCurrency->convert($baseDiscount);

        $total->addTotalAmount('customdiscount', -$discount);
        $total->addBaseTotalAmount('customdiscount', -$baseDiscount);
        $quote->setCustomDiscount(-$discount);

        \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check AbstractTotal >>>  ' .  $baseDiscount); 
        \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check AbstractTotal >>>  ' . (print_r($total,true))); 

    }

    return $this;
}

/**
 * Assign subtotal amount and label to address object
 *
 * @param \Magento\Quote\Model\Quote $quote
 * @param Address\Total $total
 * @return array
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
{
    return [
        'code' => 'Custom_Discount',
        'title' => $this->getLabel(),
        'value' => -$this->helper->calculateCreditbalance()
    ];
}

/**
 * get label
 * @return string
 */
public function getLabel()
{
    return __('Custom Discount');
}

} `

Examples


<?php 

namespace PartSimple\CoreCredit\Model\Quote\Address\Total;

class CustomDiscount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
{

    /**
    * @var \Magento\Framework\Pricing\PriceCurrencyInterface
    */
    protected $_priceCurrency;
    protected $resourceConnection;
    protected $helper;

    /**
     * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency [description]
     */
    public function __construct(
        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
        \Magento\Framework\App\ResourceConnection $resourceConnection,
        \PartSimple\CoreCredit\Helper\Data $helper
    ) {
        $this->_priceCurrency = $priceCurrency;
        $this->resourceConnection = $resourceConnection;
        $this->helper = $helper;
    }

    public function collect(
        \Magento\Quote\Model\Quote $quote,
        \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
        \Magento\Quote\Model\Quote\Address\Total $total
    ) {
        parent::collect($quote, $shippingAssignment, $total);

        if($this->helper->isValidStore() && $this->helper->isRemanItemExistsInCart()){
            $address = $shippingAssignment->getShipping()->getAddress();
            if($address->getAddressType() == 'billing'){
                return $this;
            }

            $baseDiscount = (float)$this->helper->calculateCreditbalance();
            $discount = $this->_priceCurrency->convert($baseDiscount);

            $total->addTotalAmount('customdiscount', -$discount);
            $total->addBaseTotalAmount('customdiscount', -$baseDiscount);
            $quote->setCustomDiscount(-$discount);

            \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check AbstractTotal >>>  ' .  $baseDiscount); 
            \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check AbstractTotal >>>  ' . (print_r($total,true))); 

        }

        return $this;
    }

    /**
     * Assign subtotal amount and label to address object
     *
     * @param \Magento\Quote\Model\Quote $quote
     * @param Address\Total $total
     * @return array
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
    {
        return [
            'code' => 'Custom_Discount',
            'title' => $this->getLabel(),
            'value' => -$this->helper->calculateCreditbalance()
        ];
    }

    /**
     * get label
     * @return string
     */
    public function getLabel()
    {
        return __('Custom Discount');
    }
}

Briantree Request from payment log - 

'request' =>
  array (
    'customer' =>
    array (
      'firstName' => 'Rahul',
      'lastName' => 'Dambare',
      'company' => 'A-UNIVERSAL APPLIANCE SERVICE LLC',
      'phone' => '123-789-7889',
      'email' => 'john@test.com',
    ),
    'amount' => '151.98',
    'paymentMethodNonce' => 'tokencc_bh_v7b36gb_97fk8g_qb4vkf_qjsvwgv_pr3',
    'orderId' => '1000641943',
    'merchantAccountId' => 'johndoe',
    'channel' => 'Magento2GeneBT',
    'options' =>
    array (
      'skipAdvancedFraudChecking' => false,
      'submitForSettlement' => true,
    ),
    'customFields' =>
    array (
    ),
    'billing' =>
    array (
      'firstName' => 'TEST',
      'lastName' => 'TEST',
      'company' => '',
      'streetAddress' => '224120 NW 110th ST',
      'extendedAddress' => '',
      'locality' => 'GAINESVILLE ',
      'region' => 'FL',
      'postalCode' => '326w09',
      'countryCodeAlpha2' => 'US',
    ),
    'shipping' =>
    array (
      'firstName' => 'TEST',
      'lastName' => 'TEST',
      'company' => 'C',
      'streetAddress' => '224120 NW 110th ST',
      'extendedAddress' => '',
      'locality' => 'GAINESVILLE ',
      'region' => 'FL',
      'postalCode' => '32609',
      'countryCodeAlpha2' => 'US',
      'countryCodeAlpha3' => 'USA',
    ),
    'deviceData' => '{"correlation_id":"c419f951f95saf0f23072222dbc16b38de"}',
    'purchaseOrderNumber' => '1000641943',
    'taxAmount' => '0',
    'discountAmount' => '0',
    'lineItems' =>
    array (
      0 =>
      array (
        'name' => 'Kenmore  Frigidaire 807024701 Dish',
        'kind' => 'debit',
        'quantity' => '1',
        'unitAmount' => '126',
        'unitOfMeasure' => 'simple',
        'totalAmount' => '126',
        'taxAmount' => '0',
        'discountAmount' => '0',
        'productCode' => 'ken-80702470',
        'commodityCode' => 'ken-80702470',
        'description' => '',
      ),
      1 =>
      array (
        'name' => 'Optional Inbound Shipping',
        'kind' => 'debit',
        'quantity' => '1',
        'unitAmount' => '12',
        'unitOfMeasure' => 'virtual',
        'totalAmount' => '12',
        'taxAmount' => '0',
        'discountAmount' => '0',
        'productCode' => 'inbound-ship',
        'commodityCode' => 'inbound-ship',
        'description' => '',
      ),
    ),
    'shippingAmount' => '13.98',
    'shipsFromPostalCode' => '60188',
  ),

Proposed solution

Custom Discount should add in braintree request or in discount field for Braintree request and final total should be minus of that discount

Release note

No response

Triage and priority

m2-assistant[bot] commented 1 month ago

Hi @rahuldambare. Thank you for your report. To speed up processing of this issue, make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce.

rahuldambare commented 1 month ago

I have one observer which add this custom amount item in cart, I think that is not working for magento 2.4.6

<event name="payment_cart_collect_items_and_amounts">
            <observer name="paymentfee" instance="MyModule\CoreCredit\Observer\AddCustomAmountItem" />
        </event>

public function execute(Observer $observer)
    {
        /** @var \Magento\Payment\Model\Cart $cart */
        $cart = $observer->getEvent()->getCart();
        $customAmount = -(float)$this->helper->calculateCreditbalance();

        \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->debug('@@@ >>> Payment Check PartSimple\CoreCredit\Plugin >>>  ' .  $customAmount); 

        $cart->addCustomItem(__('Credit Amount'), 1, $customAmount, 'creditamount');
    }
m2-assistant[bot] commented 1 month ago

Hi @engcom-Hotel. Thank you for working on this issue. In order to make sure that issue has enough information and ready for development, please read and check the following instruction: :point_down:

engcom-Hotel commented 1 month ago

Hello @rahuldambare,

Thanks for the report and collaboration!

I need to tell you that, the Braintree module is not part of the bundled extension now in the Magento. Please take a look at this link for more details.

For versions of Adobe Commerce and Magento Open Source earlier than 2.4.0, it was recommended that merchants install and configure the official Braintree payment integration extension from the Commerce Marketplace to replace the core integration. As of 2.4.0, the extension is now included in the core release.

So we request you to please contact the Braintree developers.

Thanks