Magento 付款重定向订单

Posted

技术标签:

【中文标题】Magento 付款重定向订单【英文标题】:Magento Payment Redirect Order 【发布时间】:2012-02-29 09:42:46 【问题描述】:

magento 支付扩展中是否有任何功能可以在返回支付网关的成功状态之前停止创建订单?

扩展程序被设计为支付重定向(使用 getOrderPlaceRedirectUrl),但实际上在正确的控制器操作中,我确实从带有参数的操作发布到网关,如果一切正常,则返回成功,并且如果没有返回失败。

但是订单已经创建,所以我必须取消这个订单,但它不应该首先创建这个订单。

如果我可以把它设计成一个网关,我可以使用一些支付方式来做到这一点?

我考虑了 validateprepareSave 方法,但它们都被调用了两次 - 接受付款方式和下订单。

我还考虑了事件 - 也许我可以使用一些事件来执行此发布操作,并且在失败时抛出异常?

但我真的认为,在支付方式中,必须有一些我可以使用的标准功能。

【问题讨论】:

如何在 Mage_Sales_Model_Service_Quote 上扩展 _validate() 方法,并在那里抛出错误,使其永远不会到达“$transaction->save();”位。 也许这是个好主意。如果没有其他解决方案会尝试这个。 我想我会使用这个解决方案,因为: 1. 我可以在发送请求之前验证 qote,所以我会知道如果服务成功,也会创建订单。 2. 我不需要创建任何控制器并进行任何重定向。谢谢 没问题,我们使用了相同的解决方案。我试图格式化一个合适的例子。 【参考方案1】:

这是支付模块开发过程中很常见的问题。 Magento 为支付方法类提供了两个钩子以提供重定向 URL,一个在订单创建之前,一个在创建之后。

如果支付方式模型实现getOrderPlaceRedirectUrl(),客户将在单页结账确认步骤后被重定向,订单实体将被创建。

如果支付方式模型实现了getCheckoutRedirectUrl()方法,客户将在单页结账的支付步骤后被重定向,并且不创建订单实体

这并不理想,但这就是 Magento 开箱即用的功能。

【讨论】:

感谢回复,但我认为完全没有重定向的工作会更有用,因为我们在ShaunOReilly's 回答here之后决定。我将尝试使用事件 sales_model_service_quote_submit_before,现在开始实施。稍后我会在这里得到我的最终解决方案 我同意没有重定向会更好。只提到这一点,因为这就是 Magento 的构建方式。由于 PCI-DSS 合规性,重定向非常常见。实现服务器端支付网关事务的正确位置是在支付方法模型的authorize()capture() 方法中,而不是在滥用getOrderPlaceRedirectUrl() 方法的操作控制器中。 我知道,但是授权和捕获方法不是我需要的。据我所知 - 创建发票时调用此方法,但在创建订单时调用。还是我错了? 您所做的请求只是某种形式的地址和客户验证,还是支付流程的一部分?也许我误解了你的问题。我相信您只想在付款成功的情况下创建订单。对吗? 这样的。在这里,我使用客户端数据向某个 url 发布请求并获得响应(我们可以说这就像客户验证一样,因为如果散列很好并且所有参数设置 + url 都是可访问的,我们将获得成功结果)。然后如果我们失败了,我们就会抛出异常。【参考方案2】:

如何在 Mage_Sales_Model_Service_Quote 上扩展 _validate() 方法,并在那里抛出错误,使其永远不会到达“$transaction->save();”位。

public function submitOrder()
    
        $this->_deleteNominalItems();
        // do some check here
        $this->_validate();
        // End checks
        $quote = $this->_quote;
        $isVirtual = $quote->isVirtual();

        ........

        try 
            $transaction->save();
            $this->_inactivateQuote();
            Mage::dispatchEvent('sales_model_service_quote_submit_success', array('order'=>$order, 'quote'=>$quote));
         catch (Exception $e) 
            ...........
        
        ...........
        return $order;
    

验证函数如下所示:

protected function _validate()

    $helper = Mage::helper('sales');
    if (!$this->getQuote()->isVirtual()) 
        $address = $this->getQuote()->getShippingAddress();
        $addressValidation = $address->validate();
        if ($addressValidation !== true) 
            Mage::throwException(
                $helper->__('Please check shipping address information. %s', implode(' ', $addressValidation))
            );
        
        $method= $address->getShippingMethod();
        $rate  = $address->getShippingRateByCode($method);
        if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) 
            Mage::throwException($helper->__('Please specify a shipping method.'));
        
    

    $addressValidation = $this->getQuote()->getBillingAddress()->validate();
    if ($addressValidation !== true) 
        Mage::throwException(
            $helper->__('Please check billing address information. %s', implode(' ', $addressValidation))
        );
    

    if (!($this->getQuote()->getPayment()->getMethod())) 
        Mage::throwException($helper->__('Please select a valid payment method.'));
    

    return $this;

扩展函数可以是这样的:

    public function __construct(Mage_Sales_Model_Quote $quote)
    
        $this->_quote = $quote;
        parent::__construct($quote);
    

protected function _validate()
    
        // Code to test comes here
        Mage::throwException(Mage::helper('payment')->__('unsuccessfull.....'));
        // Code ends, now call parent

        return parent::_validate();        

    

【讨论】:

真的我不需要使用 submitOrder,我唯一需要的是扩展函数 _validate 但我会先做父验证,然后我会发送请求,如果错误我会创建异常和然后直接返回 $this 顺便说一句,这是一个很好的解决方案,我会使用它 嗯 - 昨晚我的头已经坏了 - 看看订单提交 我想我可以观察到事件 sales_model_service_quote_submit_before - 所以我会尝试这个并在今天晚些时候写回我的结果 提交订单仅显示调用验证函数的位置。让我知道什么对你有用。 在我测试时同时使用这两种变体,但使用观察事件是更好的做法,所以我使用了它。我将为观察事件添加新答案和示例【参考方案3】:

正如我所说 - 最后给出我用于此解决方案的示例。

我更喜欢观察事件来做发布请求。真的,如果你会使用here提出的方法 你会得到同样的效果,但我更喜欢使用事件观察者。所以:

首先在 config.xml 中添加一些数据以在 frontend 部分中创建事件观察者

<events>
    <sales_model_service_quote_submit_before>
        <observers>
            <lacpaycs>
                <type>singleton</type>
                <class>OS_LacPayCS_Model_Observer</class>
                <method>lacpaycs_payment_send</method>
            </lacpaycs>
        </observers>
    </sales_model_service_quote_submit_before>
</events>

那么我们必须在OS/LacPayCS/Mode/Observer.php中创建Observer类

     class OS_LacPayCS_Model_Observer 

        protected $_code = 'lacpaycs';

        // Here some our additional functions

        /**
         * @param Varien_Object $observer
         */
        public function lacpaycs_payment_send(Varien_Object $observer)
        
            /**
             * @var Mage_Sales_Model_Order $order
             * @var Mage_Sales_Model_Quote $quote
             */
            $order = $observer->getOrder();
            $quote = $observer->getQuote();
            $payment = $order->getPayment();
            if ($payment->getMethodInstance()->getCode() != $this->_code) 
                return;
            

            $helper = Mage::helper('lacpaycs');
            try 

                // Here we prepare data and sending request to gateway, and getting response

                if (!$this->_validateResponse($response)) 
                    Mage::throwException('Error '.$this->errorMsg);
                
             catch (Exception $e) 
                Mage::throwException($e->getMessage());
            
        

    

因此,简而言之,我们在这里所做的 $_code 与我们的支付模式中的操作相同,并且当客户使用我们的支付方式时,如果我们捕捉到事件,我们会通过它检查观察者

其他的代码都很简单,我觉得没必要评论了

【讨论】:

以上是关于Magento 付款重定向订单的主要内容,如果未能解决你的问题,请参考以下文章

magento 将结帐付款重定向到第三方网关

Magento Paypal 下订单但重定向不正确

Magento 在贝宝付款前下订单

用于多运输的 magento 自定义支付模块

Magento 1.8.0.0:添加自定义付款方式重定向到新页面

Magento:支付完成后,paypal 标准支付未重定向到 Magento 成功页面