18

I've been getting exception logs for this error in production, but I'm unable to reproduce the issue in my local or staging environment, so it's been pretty hard to troubleshoot.

The error originates in Mage_Sales_Model_Service_Quote::_validate() because the $rate returned by $rate = $address->getShippingRateByCode($method) is empty.

I've added in some logging to try and get a better idea of what was going on, and I can see that $method contains the correct shipping method.

My best guess is that at some point in the process, the shipping rates are being deleted prior to when they should be.

I've noticed that every time this exception occurs, it happens immediately after a legitimate exception, such as an invalid credit card. I've tried to reproduce the issue by using an invalid credit card, then a valid one, but it doesn't reproduce for me - in staging, production, or local.

My initial hunch was that maybe the shipping method was getting lost somewhere after the first valid exception, but that's not the case, because I see that $method has the correct value at the time that this exception is thrown.

The checkout module that I'm using is AwesomeCheckout - it doesn't really to my knowledge have any custom logic when creating orders that should cause problems here, but might be related.

UPDATE: I've added in some code to attempt to recollect the rates if they are missing.

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.'));
        }
    }
  • Are you using a 3th party shipping extension? Testing with a native Magento method like flatrate would perhaps give some insight whether it's the checkout extension or the shipping extension – Sander Mangel Sep 5 '13 at 17:24
  • 1
    I have also seen a store with this happening in production, often multiple times in succession. We've never been able to reproduce ourselves in any environment. – Peter O'Callaghan Sep 5 '13 at 17:51
  • @Sander, Yes we're using a 3rd party extension. I'm pretty sure it's not the root cause though because it returns rates over the collectRates() method just fine and even for the cases where this fails, I can see that rates were returned over the API just fine. – kalenjordan Sep 5 '13 at 17:52
  • @Cags, really??! Good to know, maybe we'll have to tag team this. It's one of those things that's important but because it reproduces very infrequently, it's not a major priority. – kalenjordan Sep 5 '13 at 17:53
  • @SanderMangel, unfortunately trying this out with flatrate isn't an option, because we can't just stop serving up the correct shipping rates to hundreds of customers in production in order to attempt to reproduce the problem. If I could reproduce this in my local environment, for sure testing against a vanilla shipping method would be one of the first things I'd try. – kalenjordan Sep 5 '13 at 17:54
8
+100

You have to understand how the rates work and how they are requested. Basically rates are requested when ->setCollectShippingRates(true) is set on shippinAddress object and it result rates to be collected and stored in rates table. This table is emptied afterwards and filled again on new rate request.

what is happening in your case is that error is thrown and request is repeated and rates are not requested but are expected to be there. So try and force the rates collection over

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

and then try to recollect totals as well if it does not work

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

be warned that calling collectTotals multiple times can mess up your totals if some extension does not implement totals objects correctly (a common flaw)

  • Thanks, makes sense. Any idea why this would occur so rarely though? If the payment error was resetting the rates, I'd expect it to happen every time there's a payment error. – kalenjordan Nov 1 '13 at 16:05
  • this depends on the flags and if it is called or not if you can replicate this on error then it is easy to trace with debugger. However if your payment method error does not do a full roundtrip to server and just breaks the request with exit it can just break all dependant observer etc execution – Anton S Nov 1 '13 at 18:59
  • Added in some code and it still failed. I did forget the $this->getQuote()->getShippingAddress()->setCollectShippingRates(true) line though so I'm going to try that now. – kalenjordan Nov 5 '13 at 18:46
  • The issue re-occurred, and the code I have in place did prevent the exception from occurring. But the transaction still failed because SIMULTANEOUSLY braintree was down for a few minutes. Unbelievable. – kalenjordan Nov 7 '13 at 0:34
  • 1
    Okay scratch that. The reason it occurred this time was for entirely different reasons. A subscription order was trying to be generated for an address where there actually were no shipping rates available, so the error message was valid. @ProxiBlue – kalenjordan Dec 11 '13 at 16:26
3

Might have figured this out. I had a related exception that was being thrown with about the same frequency as this one, which was "The requested Payment Method is not available".

Turns out that the reason it was happening was because one of my observers off of sales_place_order_after was creating a quote object (and saving it) in order to generate some subscription pricing.

I was able to get it to reproduce by first checking out with a bad credit card as a new customer (not logged in), then going back and fixing the credit card and attempting to checkout again.

The exception was throwing because in the loadCustomerQuote observer of customer_login, it will merge your quotes together if you have more than one quote, and in so doing it loses some of the payment method information on the quote.

The fix was to delete the new quote that I was creating in my subscription observer.

UPDATE: Nope, the fix for "The requested Payment Method is not available" didn't resolve this issue, still occurring.

  • Quite late, but this is why I don't use that event (sales order place after) at all anymore. If I need something to happen after an order I fetch into a queue. – philwinkle Nov 1 '13 at 19:47
  • Like same will you help me to solve “Please specify a shipping method” in checkout page error: magento.stackexchange.com/q/225297/57334 – zus May 18 '18 at 6:12
0

Just noting, sometimes PayPal Express will give an error saying "Payer not identified" upon order placement. This error stems from the same "Please specify a shipping method" exception. In Magento 1.8.1.0 this is easily reproducible by causing a "quote merge" or "cart merge" upon order placement. Merging quotes or carts will cause the shipping rates to be cleared but not recalculated. And actually, you don't want to fix this, because then the customer might be paying more than what they agreed on! Instead you'll want to remove the merging functionality - or upgrade Magento.

This is fixed in 1.9; customers first have to log in before they get redirected to PayPal .

0

In my case this error its originate from null value in $method and $rate

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

so i set a rate from this. in method and rate that available in your magento

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.