PayPal网关拒绝了请求。 购物车项目金额的总数与订单金额不匹配。 Magento1.9

问题遇到的现象和发生背景
问题相关代码,请勿粘贴截图
<?php
class Gw_Commonn_Model_Sales_Quote_Address_Total_Card extends Mage_Sales_Model_Quote_Address_Total_Abstract{
    protected $_code = 'card';
    protected $_money = 0;
    protected $_base_money = 0;
    protected $_point = '';
    //protected $_product_id = 0;
    protected $_set = 1;

    public function collect(Mage_Sales_Model_Quote_Address $address)
    {
        parent::collect($address);
        $this->_setAmount(0);
        $this->_setBaseAmount(0);
        $items = $this->_getAddressItems($address);
        if (!count($items)) {
            return $this; //this makes only address type shipping to come through
        }
        $quote = $address->getQuote();
        $this->getAllProductId($quote);
        if ($this->_set) {
            $this->getPointValue();
        }
        $address->setFeeAmount($this->_money);
        $address->setBaseFeeAmount($this->_base_money);
        $address->setPointCode($this->_point);
        $quote->setFeeAmount($this->_money);
        $quote->setBaseFeeAmount($this->_base_money);
        $quote->setPointCode($this->_point);
        $address->setGrandTotal($address->getGrandTotal() - $address->getFeeAmount());
        $address->setBaseGrandTotal($address->getBaseGrandTotal() - $address->getBaseFeeAmount());
        return;
    }
 
    public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
        if ($this->_point) {
            $address->addTotal(array(
                'code'=> $this->getCode(),
                'title'=> 'gift card ('. $this->_point .')',
                'value'=> - $this->_money / 2
            ));
        }
        return $this;
    }

    /**
     * 获取积分金额
     */
    public function getPointValue()
    {
        $customer_id = Mage::getSingleton("customer/session")->getCustomer()->getId();
        $data = Mage::getModel('rewardpoints/discountgift')->getCollection()
            ->addFieldToFilter('customer_id', $customer_id)
            ->addFieldToFilter('type', MW_RewardPoints_Model_Discountgift::POINT)//
            ->addFieldToFilter('used', 1)//未使用
            ->addFieldToFilter('style', 1)
            ->setOrder('value', 'DESC')
            ->getData();
        if ($data) {
            $_money = Mage::helper('directory')->currencyConvert(
                $data[0]['value'],
                'USD',
                Mage::app()->getStore()->getCurrentCurrencyCode()
            );
            $this->_money = number_format($_money, 2);
            $this->_base_money = number_format($data[0]['value'], 2);
            $this->_point = $data[0]['code'];
            //$this->_product_id = $data[0]['product_id'];
        }
    }

    /**
     * 判断商品是否在当前购物车中
     * @param $products
     */
    public function getProduct($quote)
    {
        $items = $quote->getAllItems();
        $products = [];
        foreach($items as $item) {
            array_push($products, $item->getProductId());
        }
        if (!empty($this->_product_id) && !in_array($this->_product_id, $products)) {
            $this->_money = 0;
            $this->_point = '';
            $this->_base_money = 0;
        }
    }

    /**
     * 获取最大金额的产品
     * @param $quote
     * @throws Mage_Core_Model_Store_Exception
     */
    public function getAllProductId($quote)
    {
        $items = $quote->getAllItems();
        $products = [];
        foreach($items as $item) {
            array_push($products, $item->getProductId());
        }
        $customer_id = Mage::getSingleton("customer/session")->getCustomer()->getId();
        $data = Mage::getModel('rewardpoints/discountgift')->getCollection()
            ->addFieldToFilter('customer_id', $customer_id)
            ->addFieldToFilter('type', MW_RewardPoints_Model_Discountgift::POINT)//
            ->addFieldToFilter('product_id', array('in' => $products))//
            ->addFieldToFilter('used', 1)//未使用
            ->addFieldToFilter('style', 2)
            ->setOrder('value', 'DESC')
            ->getData();
        if ($data) {
           $_money = Mage::helper('directory')->currencyConvert(
                $data[0]['value'],
                'USD',
                Mage::app()->getStore()->getCurrentCurrencyCode()
            );
            $this->_money = number_format($_money, 2);
            $this->_base_money = number_format($data[0]['value'], 2);
            $this->_point = $data[0]['code'];
            //$this->_product_id = $data[0]['product_id'];
            $this->_set = 0;
        }
    }

}


<!--自定义 费用展示的-->
        <sales>
            <quote>
                <totals>
                    <card>
                        <class>commonn/sales_quote_address_total_card</class>
                        <before>subtotal</before>
                        <after>grand_total</after>
                    </card>
                </totals>
            </quote>
       </sales>


运行结果及报错内容

paypal购物车金额和订单金额不匹配。
但是把 $address->setBaseGrandTotal($address->getBaseGrandTotal() - $address->getBaseFeeAmount());注释掉就好了,关键是setBaseGrandTotal不能注释掉

我的解答思路和尝试过的方法
我想要达到的结果

看下如图所示括号中的赋值是否正确

img

这两行
$address->setGrandTotal($address->getGrandTotal() - $address->getFeeAmount());
$address->setBaseGrandTotal($address->getBaseGrandTotal() - $address->getBaseFeeAmount());
改成
$grandTotal = $address->getGrandTotal();
$feeAmount = $address->getFeeAmount();
$grandTotal -= $feeAmount;
$address->setGrandTotal( $grandTotal );
$baseGrandTotal = $address->getBaseGrandTotal();
$baseFeeAmount = $address->getBaseFeeAmount();
$baseGrandTotal -= $baseFeeAmount;
$address->setBaseGrandTotal( $baseGrandTotal );
如果不对,就可以一步一步调试找到原因了

断点或打印日志,对比购物车金额和总金额,是不是真的不相等,分别是多少?然后一步步定位问题原因。


pdItem[0] = new PaymentDetailsItemType() 
{ 
    Name = "xyz", 
    Amount = new BasicAmountType() { currencyID = CurrencyCodeType.USD, Value = "10.00" }, 
    Tax = new BasicAmountType() { currencyID = CurrencyCodeType.USD, Value = "2.00" }, 
    Quantity = "1" 
}; 

PaymentDetailsType pdt = new PaymentDetailsType() 
{ 
    OrderDescription = orderDescription, 
    PaymentDetailsItem = pdItem, 
    OrderTotal = new BasicAmountType() { currencyID = CurrencyCodeType.USD, Value = "10.00" }, 
    TaxTotal = new BasicAmountType() { currencyID = CurrencyCodeType.USD, Value = "2.00" } 
}; 

在您的示例中,您需要包含ItemTotal,并确保包括包含税款和交货的订单总额。

ItemTotal = 10
将TaxTotal = 2
的OrderTotal = 12
但是我会离开税出来把事情简单化。

如果你计算出每件商品的税率和总订单价值的税额,那么你很容易受到小的舍入误差,这两个误差使得两个总计相距1美分。

您不需要将税务信息发送到PayPal,所以除非您的客户绝对需要它,否则我会退出单独的税务信息并发送包括税款在内的所有总计。