He estado recibiendo registros de excepciones para este error en producción, pero no puedo reproducir el problema en mi entorno local o provisional, por lo que ha sido bastante difícil de solucionar.
El error se origina Mage_Sales_Model_Service_Quote::_validate()
porque el $rate
devuelto por $rate = $address->getShippingRateByCode($method)
está vacío.
He agregado algunos registros para intentar tener una mejor idea de lo que estaba sucediendo, y puedo ver que $method
contiene el método de envío correcto.
Mi mejor conjetura es que en algún momento del proceso, las tarifas de envío se eliminan antes de cuando deberían serlo.
Me di cuenta de que cada vez que se produce esta excepción, ocurre inmediatamente después de una excepción legítima, como una tarjeta de crédito no válida. Intenté reproducir el problema usando una tarjeta de crédito no válida, luego una válida, pero no se reproduce para mí, ya sea en escena, producción o local.
Mi presentimiento inicial fue que tal vez el método de envío se estaba perdiendo en algún lugar después de la primera excepción válida, pero ese no es el caso, porque veo que $method
tiene el valor correcto en el momento en que se lanza esta excepción.
El módulo de pago que estoy usando es AwesomeCheckout, que yo sepa no tiene ninguna lógica personalizada al crear pedidos que deberían causar problemas aquí, pero podrían estar relacionados.
ACTUALIZACIÓN: agregué un código para intentar recordar las tasas si faltan.
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.'));
}
}
Respuestas:
Debe comprender cómo funcionan las tarifas y cómo se solicitan. Básicamente, las tarifas se solicitan cuando
->setCollectShippingRates(true)
se establece en el objeto shippinAddress y resulta que las tarifas se recopilen y almacenen en la tabla de tarifas. Esta tabla se vacía después y se vuelve a llenar con una nueva solicitud de tarifa.Lo que sucede en su caso es que se arroja un error y la solicitud se repite y no se solicitan tarifas, pero se espera que estén allí. Así que intente forzar la recaudación de tasas
y luego trate de recolectar totales también si no funciona
tenga en cuenta que llamar a collectTotals varias veces puede arruinar sus totales si alguna extensión no implementa los objetos de totales correctamente (una falla común)
fuente
$this->getQuote()->getShippingAddress()->setCollectShippingRates(true)
línea, así que voy a intentarlo ahora.Podría haber resuelto esto. Tuve una excepción relacionada que se lanzó con aproximadamente la misma frecuencia que esta, que era "El método de pago solicitado no está disponible".
Resulta que la razón por la que estaba sucediendo era porque uno de mis observadores
sales_place_order_after
estaba creando un objeto de cotización (y guardándolo) para generar un precio de suscripción.Pude hacer que se reprodujera primero revisando con una tarjeta de crédito mala como un nuevo cliente (no conectado), luego volviendo y arreglando la tarjeta de crédito e intentando volver a pagar.
La excepción fue arrojada porque en el
loadCustomerQuote
observador decustomer_login
, fusionará sus cotizaciones juntas si tiene más de una cotización, y al hacerlo pierde parte de la información del método de pago en la cotización.La solución fue eliminar la nueva cita que estaba creando en mi observador de suscripción.
ACTUALIZACIÓN: No, la solución para "El método de pago solicitado no está disponible" no resolvió este problema, todavía se produce.
fuente
Solo teniendo en cuenta, a veces PayPal Express dará un error que dice "Pagador no identificado" al realizar el pedido. Este error proviene de la misma excepción "Especifique un método de envío". En Magento 1.8.1.0, esto es fácilmente reproducible al provocar una "fusión de cotización" o "fusión de carro" al realizar el pedido. La fusión de cotizaciones o carritos hará que las tarifas de envío se borren pero no se vuelvan a calcular. Y, de hecho, no quiere arreglar esto, ¡porque entonces el cliente podría estar pagando más de lo acordado! En su lugar, querrá eliminar la funcionalidad de fusión, o actualizar Magento.
Esto se arregla en 1.9; Los clientes primero deben iniciar sesión antes de ser redirigidos a PayPal.
fuente
En mi caso, este error se origina del
null
valor en$method
y$rate
así que establezco una tasa de esto. en método y tasa disponible en tu magento
fuente