Obtener una excepción de "Especifique un método de envío" durante el pago

18

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 $ratedevuelto 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 $methodcontiene 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 $methodtiene 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.'));
        }
    }
kalenjordan
fuente
¿Está utilizando una extensión de envío de terceros? Las pruebas con un método nativo de Magento como flatrate tal vez darían una idea de si se trata de la extensión de pago o la extensión de envío
Sander Mangel
1
También he visto una tienda con esto sucediendo en producción, a menudo varias veces seguidas. Nunca hemos podido reproducirnos en ningún entorno.
Peter O'Callaghan
@Sander, sí, estamos usando una extensión de terceros. Sin embargo, estoy bastante seguro de que no es la causa raíz porque devuelve las tasas sobre el método collectRates () muy bien e incluso en los casos en que esto falla, puedo ver que las tasas se devolvieron a través de la API muy bien.
kalenjordan
@Cags, ¿de verdad? Es bueno saber, tal vez tendremos que etiquetar al equipo de esto. Es una de esas cosas que es importante, pero debido a que se reproduce con poca frecuencia, no es una prioridad importante.
kalenjordan
@SanderMangel, desafortunadamente probar esto con flatrate no es una opción, porque no podemos dejar de ofrecer las tarifas de envío correctas a cientos de clientes en producción para intentar reproducir el problema. Si pudiera reproducir esto en mi entorno local, seguro que probarlo con un método de envío estándar sería una de las primeras cosas que probaría.
kalenjordan

Respuestas:

8

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

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

y luego trate de recolectar totales también si no funciona

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

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)

Anton S
fuente
Gracias, tiene sentido. ¿Alguna idea de por qué esto ocurriría tan raramente? Si el error de pago restablecía las tarifas, esperaría que ocurriera cada vez que haya un error de pago.
kalenjordan 01 de
esto depende de los indicadores y si se llama o no si puede replicar esto en caso de error, entonces es fácil de rastrear con el depurador. Sin embargo, si el error de método de pago no hace un ida y vuelta completa al servidor y me rompe la solicitud con salida sólo se puede romper todo observador dependiente etc ejecución
Anton S
Se agregó algún código y aún falló. Sin embargo, olvidé la $this->getQuote()->getShippingAddress()->setCollectShippingRates(true)línea, así que voy a intentarlo ahora.
kalenjordan
El problema volvió a ocurrir, y el código que tengo instalado evitó que ocurriera la excepción. Pero la transacción aún falló porque SIMULTÁNEAMENTE Braintree estuvo inactivo por unos minutos. Increíble.
kalenjordan
1
De acuerdo, tacha eso. La razón por la que ocurrió esta vez fue por razones completamente diferentes. Se estaba intentando generar un pedido de suscripción para una dirección donde en realidad no había tarifas de envío disponibles, por lo que el mensaje de error era válido. @ProxiBlue
kalenjordan
3

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_afterestaba 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 loadCustomerQuoteobservador de customer_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.

kalenjordan
fuente
Muy tarde, pero es por eso que ya no uso ese evento (lugar de pedido de venta después). Si necesito que suceda algo después de un pedido, me pongo en una cola.
philwinkle
Igual me ayudarán a resolver "Especifique un método de envío" en el error de la página de pago: magento.stackexchange.com/q/225297/57334
zus
0

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.

Erfan
fuente
0

En mi caso, este error se origina del nullvalor en $methody$rate

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

así que establezco una tasa de esto. en método y tasa disponible en tu magento

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