Magento – Magento : Paypal Website Payments Standard, redirect issue

paypal

I recently encountered with a weird paypal redirect issue. this issue comes when i select Paypal Website Standard as payment method and place order. here after clicking on Place Order ideally it should have redirect me to paypal's website for payment processing but it gets stuck on domain.com/paypal/standard/redirect/ giving me a blank screen without any error.

If i hit the same URL on other magento site than it gives me these error Fatal error: Call to a member function validate() on a non-object in /public_html/app/code/core/Mage/Paypal/Model/Standard.php on line 137. but for these site case is completely different.

Below is the Action's code and in that these line $this->getResponse()->setBody($this->getLayout()->createBlock('paypal/standard_redirect')->toHtml()); is not getting executed.

   /**
     * When a customer chooses Paypal on Checkout/Payment page
     *
     */
    public function redirectAction()
    {
        $session = Mage::getSingleton('checkout/session');
        $session->setPaypalStandardQuoteId($session->getQuoteId());
        $this->getResponse()->setBody($this->getLayout()->createBlock('paypal/standard_redirect')->toHtml());
        $session->unsQuoteId();
        $session->unsRedirectUrl();
    }

Guys please help.

[EDIT]

if i do below changes than it will work

//Mage_Paypal_StandardController
$this->getResponse()->setBody($this->getLayout()->createBlock('paypal/standard_redirect')->toHtml());
to
$this->getResponse()->setBody($this->getLayout()->createBlock('paypal/standard_redirect')->_toHtml());

//Mage_Paypal_Block_Standard_Redirect
protected function _toHtml()
to
public function _toHtml()

but i dont think it is good to mess with the access modifier of the method.

Best Answer

The solution you've added isn't a solution. First of all, it's a core hack, which are not the way to go. Also, _toHtml() and toHtml() look the same, but do two completely different things. Looking at the method in the latest version of Magento, this is what both methods do:

toHtml()

final public function toHtml()
{
    Mage::dispatchEvent('core_block_abstract_to_html_before', array('block' => $this));
    if (Mage::getStoreConfig('advanced/modules_disable_output/' . $this->getModuleName())) {
        return '';
    }
    $html = $this->_loadCache();
    if ($html === false) {
        $translate = Mage::getSingleton('core/translate');
        /** @var $translate Mage_Core_Model_Translate */
        if ($this->hasData('translate_inline')) {
            $translate->setTranslateInline($this->getData('translate_inline'));
        }

        $this->_beforeToHtml();
        $html = $this->_toHtml();
        $this->_saveCache($html);

        if ($this->hasData('translate_inline')) {
            $translate->setTranslateInline(true);
        }
    }
    $html = $this->_afterToHtml($html);

    /**
     * Check framing options
     */
    if ($this->_frameOpenTag) {
        $html = '<' . $this->_frameOpenTag . '>' . $html . '<' . $this->_frameCloseTag . '>';
    }

    /**
     * Use single transport object instance for all blocks
     */
    if (self::$_transportObject === null) {
        self::$_transportObject = new Varien_Object;
    }
    self::$_transportObject->setHtml($html);
    Mage::dispatchEvent('core_block_abstract_to_html_after',
        array('block' => $this, 'transport' => self::$_transportObject));
    $html = self::$_transportObject->getHtml();

    return $html;
}

_toHtml()

protected function _toHtml()
{
    $standard = Mage::getModel('paypal/standard');

    $form = new Varien_Data_Form();
    $form->setAction($standard->getConfig()->getPaypalUrl())
        ->setId('paypal_standard_checkout')
        ->setName('paypal_standard_checkout')
        ->setMethod('POST')
        ->setUseContainer(true);
    foreach ($standard->getStandardCheckoutFormFields() as $field=>$value) {
        $form->addField($field, 'hidden', array('name'=>$field, 'value'=>$value));
    }
    $idSuffix = Mage::helper('core')->uniqHash();
    $submitButton = new Varien_Data_Form_Element_Submit(array(
        'value'    => $this->__('Click here if you are not redirected within 10 seconds...'),
    ));
    $id = "submit_to_paypal_button_{$idSuffix}";
    $submitButton->setId($id);
    $form->addElement($submitButton);
    $html = '<html><body>';
    $html.= $this->__('You will be redirected to the PayPal website in a few seconds.');
    $html.= $form->toHtml();
    $html.= '<script type="text/javascript">document.getElementById("paypal_standard_checkout").submit();</script>';
    $html.= '</body></html>';

    return $html;
}

As you can see, the toHtml() calls _toHtml(), but also does a lot more. Since you now know that the issue is not in the _toHtml() method, you should check the other functionality in the toHtml(). One of the things we can see here, is that it dispatches two events: one before and one after the code is executed. Also, there is a check if the extension is enabled or not and it does a check on the cache.

So, if you check if there is any extension using the events in the method, that would give you a little more information. Also, a really good way to debug this, is by using Xdebug.

I know this doesn't solve the problem, but this might explain the stuff that's done.

Related Topic