Uzyskiwanie wyjątku „Proszę określić metodę wysyłki” podczas realizacji transakcji

18

Dostaję dzienniki wyjątków dla tego błędu w produkcji, ale nie jestem w stanie odtworzyć problemu w moim środowisku lokalnym lub przejściowym, więc bardzo trudno było go rozwiązać.

Błąd pochodzi, Mage_Sales_Model_Service_Quote::_validate()ponieważ $ratezwrócony przez $rate = $address->getShippingRateByCode($method)jest pusty.

Dodałem trochę logowania, aby spróbować lepiej zrozumieć, co się dzieje, i widzę, że $methodzawiera prawidłową metodę wysyłki.

Domyślam się, że w pewnym momencie procesu koszty wysyłki są usuwane przed, kiedy powinny.

Zauważyłem, że za każdym razem, gdy wystąpi ten wyjątek, dzieje się to natychmiast po uzasadnionym wyjątku, takim jak nieważna karta kredytowa. Próbowałem odtworzyć problem, używając nieważnej, a następnie ważnej karty kredytowej, ale dla mnie nie jest ona reprodukowana - na etapie inscenizacji, produkcji ani lokalnym.

Moje początkowe przeczucie było takie, że być może metoda wysyłki gubiła się gdzieś po pierwszym ważnym wyjątku, ale tak nie jest, ponieważ widzę, że $methodma ona prawidłową wartość w momencie zgłoszenia tego wyjątku.

Moduł kasy, którego używam, jest AwesomeCheckout - tak naprawdę według mojej wiedzy nie ma żadnej niestandardowej logiki podczas tworzenia zamówień, które powinny powodować problemy tutaj, ale mogą być powiązane.

AKTUALIZACJA: Dodałem jakiś kod, aby spróbować przypomnieć stawki, jeśli ich brakuje.

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
źródło
Czy korzystasz z rozszerzenia dostawy innej firmy? Testowanie przy użyciu natywnej metody Magento, takiej jak flatrate, może dać pewien wgląd, czy jest to rozszerzenie kasy, czy rozszerzenie wysyłki
Sander Mangel
1
Widziałem też sklep, w którym dzieje się to w produkcji, często wiele razy z rzędu. Nigdy nie byliśmy w stanie się rozmnażać w żadnym środowisku.
Peter O'Callaghan,
@ Sander, Tak, używamy rozszerzenia zewnętrznego. Jestem prawie pewien, że nie jest to podstawowa przyczyna, ponieważ dobrze zwraca stawki w stosunku do metody collectRates (), a nawet w przypadkach, w których to się nie udaje, widzę, że stawki były zwracane przez interfejs API w porządku.
kalenjordan
@ Tagi, naprawdę ??! Dobrze wiedzieć, może będziemy musieli oznaczyć to zespołem. Jest to jedna z tych rzeczy, które są ważne, ale ponieważ bardzo rzadko się rozmnaża, nie jest to główny priorytet.
kalenjordan
@SanderMangel, niestety wypróbowanie tego z flatrate nie jest opcją, ponieważ nie możemy po prostu przestać podawać właściwych stawek wysyłkowych setkom klientów w produkcji, aby spróbować odtworzyć problem. Gdybym mógł to odtworzyć w moim lokalnym środowisku, na pewno testowanie przy użyciu waniliowej metody wysyłki byłoby jedną z pierwszych rzeczy, które spróbowałem.
kalenjordan

Odpowiedzi:

8

Musisz zrozumieć, jak działają stawki i jak są wymagane. Zasadniczo stawki są wymagane, gdy ->setCollectShippingRates(true)są ustawione na obiekcie shippinAddress, a stawki wynikowe są gromadzone i przechowywane w tabeli stawek. Tabela ta jest następnie opróżniana i ponownie wypełniana na żądanie nowej stawki.

w twoim przypadku generowany jest błąd i żądanie jest powtarzane, a stawki nie są wymagane, ale oczekuje się, że tam będą. Spróbuj więc wymusić zbieranie stawek

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

a następnie spróbuj również przypomnieć sobie sumy, jeśli to nie działa

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

ostrzegamy, że wielokrotne wywoływanie funkcji collectTotals może zepsuć sumy, jeśli jakieś rozszerzenie nie implementuje poprawnie obiektów sum (powszechna wada)

Anton S.
źródło
Dzięki, to ma sens. Masz pojęcie, dlaczego tak rzadko się to zdarza? Jeśli błąd płatności resetuje stawki, spodziewam się, że wystąpi za każdym razem, gdy wystąpi błąd płatności.
kalenjordan
zależy to od flag, a jeśli zostanie wywołane lub nie, czy można to powtórzyć po błędzie, łatwo jest prześledzić za pomocą debuggera. Jednak jeśli błąd metody płatności nie powoduje pełnego przejścia do serwera i po prostu przerywa żądanie przy wyjściu, może po prostu przerwać wykonywanie wszystkich zależnych obserwatorów itp.
Anton S
Dodane w jakimś kodzie i nadal nie działa. Ale zapomniałem o $this->getQuote()->getShippingAddress()->setCollectShippingRates(true)linii, więc spróbuję teraz.
kalenjordan
Problem wystąpił ponownie, a kod, który wprowadziłem, zapobiegał wystąpieniu wyjątku. Ale transakcja nadal nie powiodła się, ponieważ RÓWNIEŻ braintree nie działał przez kilka minut. Nie do wiary.
kalenjordan
1
Dobra, podrap to. Powodem, dla którego się to wydarzyło, były zupełnie inne przyczyny. Próbowano wygenerować zamówienie subskrypcji dla adresu, na którym faktycznie nie było dostępnych stawek wysyłki, więc komunikat o błędzie był prawidłowy. @ProxiBlue
kalenjordan
3

Może to rozgryzłem. Miałem pokrewny wyjątek, który był zgłaszany z taką samą częstotliwością jak ten, który brzmiał: „Żądana metoda płatności nie jest dostępna”.

Okazuje się, że powodem tego było to, że jeden z moich obserwatorów nie sales_place_order_afterstworzył obiektu wyceny (i zapisał go) w celu wygenerowania cen subskrypcji.

Udało mi się go odtworzyć, najpierw sprawdzając przy użyciu złej karty kredytowej jako nowy klient (niezalogowany), a następnie wracając, naprawiając kartę kredytową i próbując ponownie dokonać płatności.

Wyjątek został zgłoszony, ponieważ loadCustomerQuoteobserwator customer_loginpołączy swoje oferty razem, jeśli masz więcej niż jedną ofertę, a tym samym traci część informacji o metodzie płatności w ofercie.

Rozwiązaniem było usunięcie nowej wyceny, którą tworzyłem w moim obserwatorze subskrypcji.

AKTUALIZACJA: Nie, poprawka „Żądana metoda płatności nie jest dostępna” nie rozwiązała tego problemu, nadal występuje.

kalenjordan
źródło
Dość późno, ale właśnie dlatego nie używam już tego wydarzenia (zamówienia sprzedaży). Jeśli potrzebuję, aby coś się wydarzyło po zamówieniu, ściągam do kolejki.
philwinkle,
Podobnie pomożesz mi rozwiązać problem „Proszę podać metodę wysyłki” w błędzie strony kasy: magento.stackexchange.com/q/225297/57334
zus
0

Wystarczy zauważyć, że czasami PayPal Express wyświetli komunikat o błędzie „Nie zidentyfikowano płatnika” przy składaniu zamówienia. Ten błąd wynika z tego samego wyjątku „Proszę podać metodę wysyłki”. W Magento 1.8.1.0 można to łatwo odtworzyć, powodując „scalenie wyceny” lub „scalanie koszyka” podczas składania zamówienia. Scalanie ofert lub koszyków spowoduje, że stawki wysyłki zostaną usunięte, ale nie zostaną ponownie obliczone. W rzeczywistości nie chcesz tego naprawiać, ponieważ wtedy klient może płacić więcej niż uzgodniono! Zamiast tego będziesz chciał usunąć funkcję scalania - lub zaktualizować Magento.

Zostało to naprawione w 1.9; klienci muszą najpierw się zalogować, zanim zostaną przekierowani do PayPal.

Erfan
źródło
0

W moim przypadku błąd ten pochodzi z nullwartości w $methodi$rate

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

więc ustaliłem z tego stawkę. w metodzie i stawce dostępnej w twoim Magento

$quote = Mage::getSingleton('checkout/session')->getQuote();
$address = $quote->getShippingAddress();
$shippingMethod = 'amtable_amtable5';
$shippingMethod = 'flatrate_flatrate';
$address->setCollectShippingRates(true)->collectShippingRates()->setShippingMethod($shippingMethod);
May Noppadol
źródło