チェックアウト中に「配送方法を指定してください」例外を取得する


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.'));
        }
    }

サードパーティの出荷拡張機能を使用していますか?flatrateのようなネイティブMagentoの方法でのテストは、おそらくそれは、チェックアウトの延長や出荷の拡張子のかどうか、いくつかの洞察を与えるだろう
サンダーMangel

1
私はこれが実稼働で起こっている店を見てきました。しばしば何度も連続して。どんな環境でも自分を再現することはできませんでした。
ピーターオキャラハン

@Sander、はい、サードパーティの拡張機能を使用しています。しかし、collectRates()メソッドでレートが正常に返されるため、これが失敗した場合でも、API経由でレートが正常に返されることがわかります。
カレンヨルダン

@Cags、本当に??!知っておくといいのですが、チームにこれをタグ付けする必要があるかもしれません。これは重要なことの1つですが、非常にまれにしか再生されないため、重要な優先事項ではありません。
kalenjordan

@SanderMangel、残念ながらフラットレートでこれを試すことは選択肢ではありません。問題を再現するために、実稼働中の何百人もの顧客に正しい配送料金を提供するのをやめることができないからです。ローカル環境でこれを再現できれば、バニラの配送方法に対するテストは、最初に試すことの1つになるでしょう。
カレンヨルダン

回答:


8

料金がどのように機能し、どのように要求されるかを理解する必要があります。基本的に->setCollectShippingRates(true)、shippinAddressオブジェクトにレートが設定されている場合、レートが要求され、レートがレートテーブルに収集および保存されます。このテーブルは、その後空になり、新しい料金リクエストで再び入力されます。

あなたのケースで起こっていることは、エラーがスローされ、リクエストが繰り返され、料金はリクエストされていないが、そこにあることが期待されているということです。そのため、料金の収集を強制して

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

そして、もしそれがうまくいかないなら、同様に合計を回収しようとします

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

いくつかの拡張機能が合計オブジェクトを正しく実装していない場合、collectTotalsを複数回呼び出すと合計が台無しになる可能性があることに注意してください(一般的な欠陥)


ありがとう、理にかなっています。なぜこれが非常にまれに発生するのでしょうか?支払いエラーがレートをリセットしていた場合、支払いエラーが発生するたびに発生すると予想されます。
kalenjordan

これはフラグに依存し、呼び出された場合、またはエラー時にこれを複製できる場合、デバッガで簡単にトレースできます。お支払い方法エラーがサーバーへの完全な往復をして、ちょうど終了して要求を壊していない場合は、それだけですべての依存オブザーバーなどの実行を破ることができます
アントン・S

いくつかのコードに追加しても、まだ失敗しました。$this->getQuote()->getShippingAddress()->setCollectShippingRates(true)ラインを忘れたので、今すぐ試してみることにします。
カレンヨルダン

問題が再発し、私が実施しているコードは例外の発生を防ぎました。しかし、同時にブレインツリーが数分間ダウンしたため、トランザクションは依然として失敗しました。信じられない。
kalenjordan

1
大丈夫です。今回発生した理由は、まったく異なる理由でした。実際に利用可能な配送料金がなかった住所に対してサブスクリプション注文を生成しようとしていたため、エラーメッセージは有効でした。@ProxiBlue
kalenjordan

3

これを理解したかもしれません。これとほぼ同じ頻度でスローされた関連する例外があり、それは「要求された支払い方法は利用できません」でした。

それが起こった理由は、私のオブザーバーの1人が、sales_place_order_afterサブスクリプション価格を生成するために引用オブジェクトを作成(および保存)したためであることがわかりました。

新しい顧客(ログインしていない)としてまず悪いクレジットカードでチェックアウトし、次に戻ってクレジットカードを修正し、再度チェックアウトを試みることで、それを再現することができました。

loadCustomerQuoteオブザーバーではcustomer_login、複数の見積もりがある場合は見積もりをマージするため、例外がスローされました。そのため、見積もりの​​支払い方法情報の一部が失われます。

修正は、サブスクリプションオブザーバーで作成していた新しい見積もりを削除することでした。

更新:いいえ、「リクエストされた支払い方法は利用できません」の修正はこの問題を解決せず、依然として発生しています。


かなり遅れていますが、これがそのイベント(販売注文後)をまったく使用しない理由です。注文後に何かする必要がある場合は、キューにフェッチします。
-philwinkle

:同じようにあなたは私がチェックアウトページのエラーに「配送方法を指定してください」解決するのに役立ちますmagento.stackexchange.com/q/225297/57334
ZUS

0

ただし、PayPal Expressでは、注文時に「支払人が特定されていません」というエラーが表示される場合があります。このエラーは、同じ「配送方法を指定してください」例外に起因しています。Magento 1.8.1.0では、注文時に「クォートマージ」または「カートマージ」を行うことにより、これを簡単に再現できます。見積もりまたはカートをマージすると、送料はクリアされますが、再計算されません。実際には、これを修正したくないのは、顧客が同意した金額以上を支払う可能性があるためです!代わりに、マージ機能を削除するか、Magentoをアップグレードします。

これは1.9で修正されています。顧客はPayPalにリダイレクトされる前にログインする必要があります。


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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.