Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento "Quote Totals must be collected" Exception due to failed prototype Form.serizalize in checkout

An intermittent and seemingly random bug is affecting Magento checkout on at least three different sites. There are a number of threads on this topic on the Magento forums with some bad advice (swallow the exception). The issue is causing lost sales and resulting in a lot of frustration for site owners. This issue has been logged with Magento since March 2011 (http://www.magentocommerce.com/bug-tracking/issue/?issue=11081).

There is no pattern in payment method, browser, Magento version or other factors that we have attempted to correlate. The primary symptom is an Exception recorded in var/log/exception.log which states "Quote Totals must be collected" which gets thrown in Mage_Sales_Model_Quote::prepareRecurringPaymentProfiles().

We have logged the Request params when the Exception occurs and identified that the payment param is empty. We believe that Magento re-sends the form elements from the Payment step at the time of the customer clicking Place Order (so that credit card details are not persisted on the site between AJAX requests), and the form serialization is failing and returning a null/empty which the opcheckout.js code then passes onto PHP triggering the Exception.

Can you suggest what conditions or data would cause prototype's Form.serialize method to fail in this manner and/or how to further attack the issue?

like image 906
Jonathan Day Avatar asked Dec 08 '12 12:12

Jonathan Day


1 Answers

Actually there are few possible reasons for that.

Prototype's Form.serialize() method is using another method from the same class, called Form.getElements(). You can try the following code too see what elements are passed from payment.form object. Just override review.save() method during runtime for debug purpose.

You can paste the following code into console of your favorite browser (Chrome, Firefox or Safari):

review.save = review.save.wrap(function (originalMethod) {
    console.log(payment.form); // Check what is in the form object
    console.log(Form.getElements(payment.form)); // Check what items are returned for serializing
    originalMethod(); // Calling original place order functionality to see if the issue occurs, so you can compare above debug info
});

I think it will help you in finding out the problem with serialization process. It might be possible that payment form somehow got empty, or all items in the form got disabled and so on...

Sincerely, Ivan

like image 110
Ivan Chepurnyi Avatar answered Jan 05 '23 04:01

Ivan Chepurnyi