Magento Checkout – Throw Error on Custom Payment Checkout

checkoutonepage-checkout

I am writing a custom checkout module to work with the OnePage Checkout and I want a JavaScript alert to tell the user when their card has been declined or there has been an error with the API. Currently, the PHP processing throws an exception via Mage::throwException, but this does not cause a JavaScript error to pop up.

How can I do this? Is JavaScript code required, or do I need to return a specific data structure in the capture or process function?

Best Answer

Hi and welcome to Magento.SE! This is already a feature of the Magento Onepage Checkout.

In checkout any error raised (including those thrown from the gateway) are displayed as a Javascript alert. Take the current in-built Magento Authorize.net module (here shown in Sandbox mode) in the case of a decline:

enter image description here

It responds with a decline in a Javscript alert:

enter image description here

How does it do that?

If you look in the payment module for the error returned we can see that it's the description text on an Exception from Mage_Paygate_Model_Authorizenet::_place

File app/code/core/Mage/Paygate/Model/Authorizenet.php (line 519):

//line 519:
case self::REQUEST_TYPE_AUTH_CAPTURE:
    $newTransactionType = Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE;
    $defaultExceptionMessage = Mage::helper('paygate')->__('Payment capturing error.');
    break;

//...
//line 576:
Mage::throwException($defaultExceptionMessage);

So - we see that any exception raised during payment place bubbles back up as a JSON response. If you look at the network tab on a failed payment submit you'll see the JSON response from the route checkout/onepage/saveOrder:

{"success":false,"error":true,"error_messages":"Payment capturing error."}

Those three properties are the key to displaying the Javascript alert:

  • Success must be false
  • Error must be true
  • error_messages contains the text from the Mage::throwException message

To tap into this all that would be required is to throw a custom exception from your payment method