Получение исключения «Пожалуйста, укажите способ доставки» во время оформления заказа

18

Я получаю журналы исключений для этой ошибки в производственной среде, но я не могу воспроизвести проблему в моей локальной или промежуточной среде, поэтому ее довольно сложно устранить.

Ошибка возникает Mage_Sales_Model_Service_Quote::_validate()из-за того, что $rateвозвращается $rate = $address->getShippingRateByCode($method)пустым.

Я добавил некоторые записи в журнал, чтобы попытаться получить лучшее представление о том, что происходит, и я вижу, что в нем $methodуказан правильный способ доставки.

Мое лучшее предположение состоит в том, что в какой-то момент процесса тарифы на доставку удаляются до того времени, когда они должны быть.

Я заметил, что каждый раз, когда возникает это исключение, оно происходит сразу после законного исключения, такого как недействительная кредитная карта. Я пытался воспроизвести проблему, используя недействительную кредитную карту, а затем действительную, но она не воспроизводится для меня - при постановке, производстве или локальной.

Моя первоначальная догадка заключалась в том, что, возможно, метод доставки терялся где-то после первого допустимого исключения, но это не так, потому что я вижу, что оно $methodимеет правильное значение в момент, когда выбрасывается это исключение.

Модуль извлечения, который я использую, - AwesomeCheckout - насколько мне известно, он не имеет никакой собственной логики при создании заказов, которая должна вызывать проблемы здесь, но может быть связана.

ОБНОВЛЕНИЕ: я добавил в некоторый код, чтобы попытаться вспомнить ставки, если они отсутствуют.

protected function _validate()
{
    if (!$this->getQuote()->isVirtual()) {
        $address = $this->getQuote()->getShippingAddress();
        $addressValidation = $address->validate();
        if ($addressValidation !== true) {
            Mage::throwException(
                Mage::helper('sales')->__('Please check shipping address information. %s', implode(' ', $addressValidation))
            );
        }
        $method= $address->getShippingMethod();
        $rate  = $address->getShippingRateByCode($method);

        /**
         * Start Customization
         */
        if (!$this->getQuote()->isVirtual() && !$rate) {
            Mage::logException(new Exception("Rate was empty inside quote validate method, trying to forcefully recalculate"));
            $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
            $this->getQuote()->setTotalsCollectedFlag(false);
            $this->getQuote()->collectTotals();
            $rate  = $address->getShippingRateByCode($method);
        }
        /** End Customization **/             

        if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
            Mage::throwException(Mage::helper('sales')->__('Please specify a shipping method.'));
        }
    }
kalenjordan
источник
Используете ли вы стороннее расширение доставки? Тестирование с использованием родного метода Magento, такого как flatrate, возможно, дало бы некоторое представление о том, является ли это расширением оформления заказа или расширением доставки
Sander Mangel
1
Я также видел магазин с этим, происходящим в производстве, часто несколько раз подряд. Мы никогда не были в состоянии воспроизвести себя в любой среде.
Питер О'Каллаган
@ Сандер, да, мы используем стороннее расширение. Я почти уверен, что это не основная причина, потому что он возвращает ставки по методу collectRates () просто отлично, и даже в тех случаях, когда это не удается, я вижу, что ставки были возвращены через API просто отлично.
Календжордан
@ Кэгс, правда ??! Полезно знать, возможно, нам придется пометить команду этим. Это одна из тех вещей, которые важны, но поскольку они воспроизводятся очень редко, это не является основным приоритетом.
Календжордан
@SanderMangel, к сожалению, попробовать это с плоской скоростью не вариант, потому что мы не можем просто перестать обслуживать правильные тарифы доставки сотням клиентов в производстве, чтобы попытаться воспроизвести проблему. Если бы я мог воспроизвести это в моем местном окружении, то наверняка тестирование с использованием метода ванильной доставки было бы одной из первых вещей, которые я бы попробовал.
Календжордан

Ответы:

8

Вы должны понимать, как работают ставки и как они запрашиваются. В основном тарифы запрашиваются, когда они ->setCollectShippingRates(true)установлены для объекта shippinAddress, и это приводит к тому, что тарифы собираются и сохраняются в таблице тарифов. Эта таблица затем очищается и заполняется снова при запросе нового тарифа.

то, что происходит в вашем случае, это то, что выдается ошибка, и запрос повторяется, а ставки не запрашиваются, но, как ожидается, будут там. Так что попытайтесь форсировать сбор ставок

getQuote()->getShippingAddress()->setCollectShippingRates(true);

а затем попробуйте вспомнить итоги, если он не работает

getQuote()->setTotalsCollectedFlag(false)->collectTotals();

Имейте в виду, что многократный вызов collectTotals может испортить ваши итоги, если какое-то расширение неправильно реализует объекты итогов (общий недостаток)

Антон С
источник
Спасибо, имеет смысл. Есть идеи, почему это происходит так редко? Если бы ошибка платежа сбрасывала тарифы, я ожидал бы, что это произойдет каждый раз, когда есть ошибка оплаты.
Календжордан
это зависит от флагов, и если он вызывается или нет, если вы можете повторить это при ошибке, это легко отследить с помощью отладчика. Однако, если ошибка метода оплаты не приводит к полному обращению к серверу и просто прерывает запрос при выходе, он может просто прервать выполнение всех зависимых наблюдателей и т. Д.
Антон С
Добавил в некоторый код и все равно не получилось. Я забыл о $this->getQuote()->getShippingAddress()->setCollectShippingRates(true)линии, хотя сейчас попробую.
Календжордан
Проблема снова возникла, и код, который я установил, не допустил возникновения исключения. Но транзакция все-таки не удалась, потому что ОДНОВРЕМЕННО отсутствовал мозг в течение нескольких минут. Невероятно.
Календжордан
1
Хорошо, поцарапайте это. Причина, по которой это произошло в этот раз, была по совершенно другим причинам. Порядок подписки пытался сгенерировать для адреса, где фактически не было доступных тарифов доставки, поэтому сообщение об ошибке было действительным. @ProxiBlue
kalenjordan
3

Возможно, понял это. У меня было похожее исключение, которое генерировалось примерно с той же частотой, что и это, а именно: «Запрошенный способ оплаты недоступен».

Оказывается, причина, по которой это происходило, была в том, что один из моих наблюдателей sales_place_order_afterсоздал объект цитаты (и сохранил его), чтобы сгенерировать определенную цену подписки.

Мне удалось воспроизвести его, сначала проверив его с помощью плохой кредитной карты в качестве нового клиента (не вошедшего в систему), затем вернувшись назад и исправив кредитную карту, и снова попытавшись оформить заказ.

Исключение было вызвано тем, что в loadCustomerQuoteобозревателе customer_loginон объединит ваши кавычки, если у вас более одной кавычки, и при этом он потеряет часть информации о способе оплаты, указанной в цитате.

Исправление состояло в том, чтобы удалить новую цитату, которую я создал в моем наблюдателе подписки.

ОБНОВЛЕНИЕ: Нет, исправление «Запрошенный способ оплаты недоступен» не решило эту проблему, которая все еще возникает.

kalenjordan
источник
Довольно поздно, но именно поэтому я больше не использую это событие (место заказа после продажи). Если мне нужно, чтобы что-то произошло после заказа, я доставляю их в очередь.
Philwinkle
Точно так же вы поможете мне решить «Пожалуйста, укажите способ доставки» в ошибке на странице оформления заказа
zus
0

Просто отметив, что иногда PayPal Express выдает ошибку, говорящую «Плательщик не идентифицирован» при размещении заказа. Эта ошибка происходит из того же исключения «Пожалуйста, укажите способ доставки». В Magento 1.8.1.0 это легко воспроизвести, вызвав «слияние цитат» или «слияние корзины» при размещении заказа. Слияние котировок или корзин приведет к тому, что тарифы на доставку будут очищены, но не пересчитаны. И на самом деле, вы не хотите это исправлять, потому что тогда клиент может заплатить больше, чем они договорились! Вместо этого вы захотите удалить функциональность слияния или обновить Magento.

Это исправлено в 1.9; клиенты должны сначала войти в систему, прежде чем они будут перенаправлены в PayPal.

Erfan
источник
0

В моем случае эта ошибка происходит от nullзначения в $methodи$rate

$method= $address->getShippingMethod();
$rate  = $address->getShippingRateByCode($method);
    if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
Mage::throwException(Mage::helper('sales')->__('Please specify a 
shipping method.'));
}

поэтому я установил ставку от этого. в методе и скорости, которые доступны в вашем magento

$quote = Mage::getSingleton('checkout/session')->getQuote();
$address = $quote->getShippingAddress();
$shippingMethod = 'amtable_amtable5';
$shippingMethod = 'flatrate_flatrate';
$address->setCollectShippingRates(true)->collectShippingRates()->setShippingMethod($shippingMethod);
Май ноппадол
источник