magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.55k stars 9.32k forks source link

Improve error reporting for failed order placement (checkout) #4682

Closed leoquijano closed 8 years ago

leoquijano commented 8 years ago

Hi,

I've been debugging some checkout issues. I noticed that several of them were fixed in Magento 2.0.7, so I went in to test our payment process using that version.

As I tested my integration with Autorize.NET DPM gateway, my checkout page froze in the "loading" stage. The order was successfully received and Authorize.NET debug log showed the information. However, something was happening after the response came back.

Sometimes I would get a window saying "Cannot place order". Sometimes it would just get stuck. However, at no point I would get more detailed information, as a developer, to what's going on.

I traced down the issue to the vendor/magento/module-authorizenet/Controller/Directpost/Payment/Place.php file (I'm using a Composer based install). The following method would be executed:

protected function placeCheckoutOrder()
{
    $result = new DataObject();
    $response = $this->getResponse();
    try {
        $this->cartManagement->placeOrder($this->_getCheckout()->getQuote()->getId());
        $result->setData('success', true);
        $this->eventManager->dispatch(
            'checkout_directpost_placeOrder',
            [
                'result' => $result,
                'action' => $this
            ]
        );
    } catch (\Exception $exception) {
        $result->setData('error', true);
        $result->setData('error_messages', __('Cannot place order.'));
    }
    if ($response instanceof Http) {
        $response->representJson($this->jsonHelper->jsonEncode($result));
    }
}

Since I got the error message 'Cannot place order' a couple of times, I entered some logging statements, and got this in my log:

2016-05-24T23:08:42+00:00 INFO (6): Error placing order: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '000000010-1' for key 'SALES_ORDER_INCREMENT_ID_STORE_ID', query was: INSERT INTO `sales_order` (`state`, `status`, `protect_code`, `shipping_description`, `is_virtual`, `store_id`, `customer_id`, `base_discount_amount`, `base_grand_total`, `base_shipping_amount`, `base_shipping_tax_amount`, `base_subtotal`, `base_tax_amount`, `base_to_global_rate`, `base_to_order_rate`, `discount_amount`, `grand_total`, `shipping_amount`, `shipping_tax_amount`, `store_to_base_rate`, `store_to_order_rate`, `subtotal`, `tax_amount`, `total_qty_ordered`, `customer_is_guest`, `customer_note_notify`, `customer_group_id`, `quote_id`, `base_shipping_discount_amount`, `base_total_due`, `shipping_discount_amount`, `subtotal_incl_tax`, `total_due`, `weight`, `increment_id`, `base_currency_code`, `customer_email`, `customer_firstname`, `customer_lastname`, `customer_middlename`, `global_currency_code`, `order_currency_code`, `remote_ip`, `shipping_method`, `store_currency_code`, `store_name`, `total_item_count`, `discount_tax_compensation_amount`, `base_discount_tax_compensation_amount`, `shipping_discount_tax_compensation_amount`, `base_shipping_discount_tax_compensation_amnt`, `discount_tax_compensation_invoiced`, `base_discount_tax_compensation_invoiced`, `discount_tax_compensation_refunded`, `base_discount_tax_compensation_refunded`, `shipping_incl_tax`, `base_shipping_incl_tax`, `gift_message_id`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

So it is clearly an inconsistent database state. I deleted the contents from the sales_order table and the checkout now works fine.

However, it would be a good idea to provide feedback for developers when an order placement fails. Something like this:

protected function placeCheckoutOrder()
{
    $result = new DataObject();
    $response = $this->getResponse();
    try {
        $this->cartManagement->placeOrder($this->_getCheckout()->getQuote()->getId());
        $result->setData('success', true);
        $this->eventManager->dispatch(
            'checkout_directpost_placeOrder',
            [
                'result' => $result,
                'action' => $this
            ]
        );
    } catch (\Exception $exception) {
        $this->_logger->info("Error placing order: ".$exception->getMessage());
        $result->setData('error', true);
        $result->setData('error_messages', __('Cannot place order.'));
    }

    if ($response instanceof Http) {
        $response->representJson($this->jsonHelper->jsonEncode($result));
    }
}

... where $this->_logger is an appropriately configured logger (via DI). This would provide something to the developer to work with, and prevent exception swallowing.

leoquijano commented 8 years ago

Here's an additional suggestion. It turns out I hadn't configured the default relay URL for Authorize.NET, so this code was failing silently (/vendor/magento/module-payment/view/frontend/web/transparent.js):

_postPaymentToGateway: function(data) {
    var tmpl;
    var iframeSelector = '[data-container="' + this.options.gateway + '-transparent-iframe"]';

    tmpl = this.hiddenFormTmpl({
        data: {
            target: $(iframeSelector).attr('name'),
            action: this.options.cgiUrl,
            inputs: data
        }
    });
    $(tmpl).appendTo($(iframeSelector)).submit();
},

Is there any way to catch error messages when doing that submit() call? In my case it was "The Referrer or Relay Response URL is invalid." (error reference can be seen here). To reproduce, just use a Authorize.NET with no default relay response URL set, and try to have Magento submit a transaction with the x_relay_url parameter set.

This is a harder error to catch, I reckon. The first ones I mentioned are easier to improve.

asemenenko commented 8 years ago

Added to MAGETWO-53457

hudson1985 commented 8 years ago

I am getting the message "Cannot Place Order" only when logged in as a registered user. I deleted the contents from the sales_order table and reindexed the database and cleared the cache. I am still getting the same error. Weird enough it goes through as a non registered user. Anyone have any suggestions?

leoquijano commented 8 years ago

Hi @hudson1985 . Check my original post. You can add manually this statement:

        $this->_logger->info("Error placing order: ".$exception->getMessage());

To the appropriate spot (described there). And test again.

My issue report is for an improvement. Your "Cannot Place Order" error may be related to something else entirely.

hudson1985 commented 8 years ago

Thank you so much for replying so quickly. Is it possible to send me a link to the specific original post you are referring to in order to ensure I get it right. Also please let me know if you have a fee structure that we could pay to cure this in the event we can't cure it.

Hudson Copeland 256-483-2671

Hudson Copeland

Director, Software Solutions, e-Commerce Management

Distinctive Designs International Inc.

hcopeland@distdesigns.com dhoffmann@distdesigns.com

800-243-4787 x 127

Office: 256-332-7390 x 127

Mobile: 256-483-2671

Fax: 256-332-7890

On Sat, Jun 18, 2016 at 11:12 PM, Leonardo Quijano <notifications@github.com

wrote:

Hi @hudson1985 https://github.com/hudson1985 . Check my original post. You can add manually this statement:

    $this->_logger->info("Error placing order: ".$exception->getMessage());

To the appropriate spot (described there). My issue report is for an improvement. Your "Cannot Place Order" may be related to something else entirely.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/magento/magento2/issues/4682#issuecomment-226978403, or mute the thread https://github.com/notifications/unsubscribe/ARJ1k-BeOpxQathpJbhes05niVd_lVxJks5qNMGVgaJpZM4ImBo6 .

leoquijano commented 8 years ago

The original post is right here in this issue #4682. This is the direct link:

https://github.com/magento/magento2/issues/4682#issue-156631769

I emailed you privately about your issue.

piotrekkaminski commented 8 years ago

Thank you for your submission.

We recently made some changes to the way we process GitHub submissions to more quickly identify and respond to core code issues.

Feature Requests and Improvements should now be submitted to the new Magento 2 Feature Requests and Improvements forum (see details here).

We are closing this GitHub ticket and have moved your request to the new forum.