Obter uma exceção "Especifique um método de envio" durante a finalização da compra

18

Eu recebi logs de exceção para esse erro na produção, mas não consigo reproduzir o problema no meu ambiente local ou intermediário, por isso tem sido muito difícil solucionar problemas.

O erro se origina Mage_Sales_Model_Service_Quote::_validate()porque o $rateretornado por $rate = $address->getShippingRateByCode($method)está vazio.

Eu adicionei alguns logs para tentar ter uma idéia melhor do que estava acontecendo, e vejo que ele $methodcontém o método de envio correto.

Meu melhor palpite é que, em algum momento do processo, as taxas de remessa sejam excluídas antes de quando deveriam ser.

Percebi que toda vez que essa exceção ocorre, ocorre imediatamente após uma exceção legítima, como um cartão de crédito inválido. Tentei reproduzir o problema usando um cartão de crédito inválido e, em seguida, um válido, mas ele não é reproduzido para mim - na preparação, produção ou local.

Meu palpite inicial foi que talvez o método de envio estivesse se perdendo em algum lugar após a primeira exceção válida, mas esse não é o caso, porque vejo que $methodtem o valor correto no momento em que essa exceção é lançada.

O módulo de checkout que estou usando é o AwesomeCheckout - realmente não tenho nenhuma lógica personalizada ao criar pedidos que devem causar problemas aqui, mas podem estar relacionados.

ATUALIZAÇÃO: adicionei um código para tentar recuperar as taxas, caso estejam ausentes.

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
fonte
Você está usando uma extensão de remessa de terceiros? Testar com um método Magento nativo, como flatrate, talvez desse uma ideia, seja a extensão do checkout ou a extensão de remessa
Sander Mangel
11
Eu também vi uma loja com isso acontecendo na produção, muitas vezes várias vezes seguidas. Nunca fomos capazes de nos reproduzir em nenhum ambiente.
Peter O'Callaghan
@ Sander, sim, estamos usando uma extensão de terceiros. Tenho certeza de que não é a causa raiz, porque retorna as taxas pelo método collectRates () muito bem e, mesmo nos casos em que isso falha, posso ver que as taxas foram retornadas pela API muito bem.
kalenjordan
@ Cags, realmente ??! É bom saber que talvez tenhamos que marcar isso com a equipe. É uma daquelas coisas importantes, mas como se reproduz com pouca frequência, não é uma grande prioridade.
kalenjordan
@SanderMangel, infelizmente, tentar fazer isso com tarifa fixa não é uma opção, porque não podemos simplesmente parar de fornecer as taxas de remessa corretas para centenas de clientes em produção, a fim de tentar reproduzir o problema. Se eu pudesse reproduzir isso no meu ambiente local, com certeza testar contra um método de envio de baunilha seria uma das primeiras coisas que eu tentaria.
precisa saber é o seguinte

Respostas:

8

Você precisa entender como as taxas funcionam e como elas são solicitadas. Basicamente, as taxas são solicitadas quando ->setCollectShippingRates(true)definidas no objeto shippinAddress e resultam em taxas a serem coletadas e armazenadas na tabela de taxas. Esta tabela é esvaziada posteriormente e preenchida novamente na nova solicitação de tarifa.

o que está acontecendo no seu caso é que o erro é gerado e a solicitação é repetida e as taxas não são solicitadas, mas espera-se que elas estejam lá. Portanto, tente forçar a cobrança de taxas

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

e tente lembrar os totais também, se não funcionar

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

esteja avisado que a chamada collectTotals várias vezes pode atrapalhar seus totais se alguma extensão não implementar corretamente os objetos totais (uma falha comum)

Anton S
fonte
Obrigado, faz sentido. Alguma idéia de por que isso ocorreria tão raramente? Se o erro de pagamento estivesse redefinindo as taxas, esperaria que acontecesse toda vez que houvesse um erro de pagamento.
Kalenjordan #
isso depende dos sinalizadores e, se for chamado ou não, se você puder replicar isso com erro, será fácil rastrear com o depurador. No entanto, se o seu erro método de pagamento não faz uma ida e volta completa para o servidor e apenas quebra o pedido com saída ele pode apenas quebrar todos observador dependente execução etc
Anton S
Adicionado em algum código e ainda falhou. Mas eu esqueci a $this->getQuote()->getShippingAddress()->setCollectShippingRates(true)linha, então vou tentar isso agora.
precisa saber é o seguinte
O problema ocorreu novamente e o código existente impediu que a exceção ocorresse. Mas a transação ainda falhou porque SIMULTANEOUSLY braintree ficou inoperante por alguns minutos. Inacreditável.
precisa saber é o seguinte
11
Ok, arranhe isso. A razão pela qual ocorreu desta vez foi por razões totalmente diferentes. Um pedido de assinatura estava tentando ser gerado para um endereço onde realmente não havia taxas de remessa disponíveis; portanto, a mensagem de erro era válida. @ProxiBlue
kalenjordan
3

Pode ter descoberto isso. Eu tinha uma exceção relacionada que estava sendo lançada com a mesma frequência que esta, que era "O método de pagamento solicitado não está disponível".

Acontece que o motivo disso estava acontecendo porque um dos meus observadores sales_place_order_afterestava criando um objeto de cotação (e salvando-o) para gerar alguns preços de assinatura.

Consegui fazê-lo se reproduzir primeiro com um cartão de crédito inválido como novo cliente (não conectado), depois voltando e consertando o cartão de crédito e tentando fazer o checkout novamente.

A exceção foi lançada porque, no loadCustomerQuoteobservador de customer_login, ele mesclará suas cotações se você tiver mais de uma cotação e, ao fazer isso, perderá algumas das informações da forma de pagamento na cotação.

A correção foi excluir a nova cotação que eu estava criando no meu observador de assinaturas.

UPDATE: Não, a correção para "O método de pagamento solicitado não está disponível" não resolveu esse problema, ainda ocorrendo.

kalenjordan
fonte
Tarde demais, mas é por isso que não uso mais esse evento (depois da ordem do cliente). Se eu precisar que algo aconteça após um pedido, busco uma fila.
philwinkle
Da mesma forma, você me ajudará a resolver "Por favor, especifique um método de envio" no erro da página de checkout: magento.stackexchange.com/q/225297/57334
zus 18-18
0

Apenas observe que, algumas vezes, o PayPal Express apresenta um erro dizendo "Pagador não identificado" na realização do pedido. Este erro deriva da mesma exceção "Especifique um método de envio". No Magento 1.8.1.0, isso é facilmente reproduzível, causando uma "mesclagem de cotação" ou "mesclagem de carrinho" na colocação do pedido. A fusão de cotações ou carrinhos fará com que as taxas de remessa sejam limpas, mas não recalculadas. E, na verdade, você não deseja corrigir isso, porque o cliente pode estar pagando mais do que concordou! Em vez disso, você deseja remover a funcionalidade de mesclagem - ou atualizar o Magento.

Isso é corrigido em 1.9; primeiro, os clientes precisam fazer login antes de serem redirecionados para o PayPal.

Erfan
fonte
0

No meu caso, esse erro é originário do nullvalor em $methode$rate

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

então eu defino uma taxa a partir disso. no método e avalie o que está disponível no seu magento

$quote = Mage::getSingleton('checkout/session')->getQuote();
$address = $quote->getShippingAddress();
$shippingMethod = 'amtable_amtable5';
$shippingMethod = 'flatrate_flatrate';
$address->setCollectShippingRates(true)->collectShippingRates()->setShippingMethod($shippingMethod);
May Noppadol
fonte