2012-02-07 2 views
2

Есть ли какая-либо функциональность в расширении платежных средств, чтобы остановить создание заказа до того, как возвращается статус успеха с платежного шлюза?Magento Payment Redirect Order

Расширение предназначено в качестве платежного редиректа (с getOrderPlaceRedirectUrl), но на самом деле в правильном действии контроллера, я размещаю от действия с Params, к шлюзу и вернуть успех, если все в порядке, и вернуть неудачу, если не ,

Но заказ уже создан, поэтому я должен отменить этот заказ, но он не должен создавать этот заказ в первую очередь.

Может быть, если я могу создать его как шлюз, я могу использовать какой-либо способ оплаты для этого?

Я думал о Validate или prepareSave методов, но оба они называются дважды - принять способ оплаты и на заказ места.

Также я думал о событиях - может быть, я могу использовать какое-то событие для выполнения этого действия post, а при отказе - просто исключение исключения?

Но я действительно думаю, что в способах оплаты должна быть какая-то стандартная функциональность, которую я могу использовать.

+1

как насчет расширения метода _validate() на Mage_Sales_Model_Service_Quote, и выдаст ошибку там, так что никогда не попадает в "$ transaction-> save();" немного. – ShaunOReilly

+0

Может быть, это хорошая идея. Попробуем это, если другие решения не будут представлены. – Kudja

+0

Я думаю, что я воспользуюсь этим решением, потому что: 1. Я могу проверить qote перед отправкой моего запроса, поэтому я буду знать, что если служба также даст заказ на успех, будет создано тоже. 2. Мне не нужно создавать какие-либо контроллеры и делать какие-либо переадресации. Thanx – Kudja

ответ

0

Как насчет расширения метода _validate() на Mage_Sales_Model_Service_Quote и выдайте там ошибку, чтобы он никогда не попадал в «$ 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; 
    } 

функция Validate выглядит следующим образом:

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();   

    } 
+0

Действительно, мне не нужно использовать submitOrder, и единственное, что мне нужно, это расширить функцию _validate, но я буду кулаком выполнять родительскую проверку, тогда я отправлю запрос, и если ошибка, я создам исключение, а затем просто верну его $ By как это хорошее решение, и я буду использовать его – Kudja

+0

Hm - прошлой ночью моя голова уже работает плохо - просто посмотри на заказСообщение – Kudja

+0

Я думаю, что я могу наблюдать событие sales_model_service_quote_submit_before - так что я попробую это и запишу свои результаты позже сегодня – Kudja

3

Это довольно распространенная проблема при разработке модуля оплаты.
Magento предлагает два крючка для классов методов оплаты, чтобы предоставить URL-адрес переадресации, один до создания заказа, один за ним.

Если модель способа оплаты реализует getOrderPlaceRedirectUrl(), клиент будет перенаправлен после этапа подтверждения проверки на одну страницу, будет создан объект заказа.

Если модель способ оплаты реализует метод getCheckoutRedirectUrl(), клиент будет перенаправлен после этапа оплаты на одной странице оформления заказа, а также нет порядка объект создается.

Это не идеально, но это то, что предлагает Magento из коробки.

+0

Thanx для ответа, но я думаю, что было бы более полезно работать без переадресаций вообще, как мы решили после [ShaunOReilly's] (http://stackoverflow.com/a/9187654/ 1043742) ответьте здесь. Я попытаюсь использовать событие sales_model_service_quote_submit_before и теперь начинаю реализовывать это. Чуть позже я получу свое окончательное решение здесь – Kudja

+0

Я согласен, что это лучше, без переадресаций. Только упоминал об этом, потому что именно так Magento построен, чтобы справиться с этим. Перенаправления очень распространены из-за соответствия PCI-DSS. Правильное место для реализации транзакции шлюза на стороне сервера будет выполняться в методах 'authorize()' и 'capture()' модели метода оплаты, а не в контроллере действий, злоупотребляющем методом getOrderPlaceRedirectUrl(). – Vinai

+0

Я знаю, но авторизация и методы захвата - это не то, что мне нужно. Как я знаю - эти методы называются при создании счета-фактуры, но не при создании заказа. Или я ошибаюсь? – Kudja

0

Как я уже сказал, дается образец, который я использовал для этого решения в финале.

Я предпочел наблюдать за событием, которое нужно отправить после запроса. Действительно, если вы будете использовать предложенный метод here , вы получите тот же эффект, но я предпочитаю использовать наблюдателя событий. Итак:

Сначала добавьте некоторые данные в конфигурацию .XML создать наблюдатель событий в интерфейсе разделе

<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:

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 - это то же самое, что и в нашей модели оплаты и с ней мы проверяем наблюдателя, если w е пойманное событие, когда клиент с помощью нашего метода оплаты

Все другой код прост, так что я думаю, что нет необходимости комментировать его