Magento Authorize.net Direct Post не очищает корзину (не устанавливает цитату как неактивную)
На создаваемом мной сайте, который использует Authorize.net Direct Post в качестве способа оплаты, я столкнулся с проблемой, из-за которой корзина не будет инактивирована после успешного завершения заказа. В Mage_Authorizenet_Model_Directpost я смог подтвердить, что предложение инактивируется в строке 574 в рамках этапа авторизации заказа.
Mage::getModel('sales/quote')
->load($order->getQuoteId())
->setIsActive(false)
->save();
Однако в directpost.js, когда Authorize.net загружает IFrame и вызывается функция returnQuote, он перенаправляет в returnQuoteAction Mage_Authorizenet_Directpost_PaymentController, который вызывает функцию _returnCustomerQuote.
if ($order->getId()) {
$quote = Mage::getModel('sales/quote')
->load($order->getQuoteId());
if ($quote->getId()) {
$quote->setIsActive(1)
->setReservedOrderId(NULL)
->save();
$this->_getCheckout()->replaceQuote($quote);
}
$this->_getDirectPostSession()->removeCheckoutOrderIncrementId($incrementId);
$this->_getDirectPostSession()->unsetData('quote_id');
if ($cancelOrder) {
$order->registerCancellation($errorMsg)->save();
}
}
Обратите внимание, что цитата снова становится активной. Я не знаю, почему они это делают, если заказ не отменен. Я думаю, что, может быть, я что-то упускаю из логики здесь Мы выполнили некоторые настройки оформления одностраничного оформления и некоторые настройки при фактической подаче заказа, но я не вижу ничего, что могло бы повлиять на это. Ожидает ли Magento, что цитата будет отключена позже по цепочке вызовов? Мне трудно это отладить, так как я не могу пошагово пройти по коду, учитывая, что Authorize.net Direct Post не будет передавать ответ обратно на мой локальный адрес.
Спасибо за любую помощь, которая может быть предложена.
1 ответ
Из того, что я могу сказать, похоже, что _returnCustomerQuote может быть вызван, если параметры запроса от Authorize.net содержат сообщение об ошибке, даже если оно прошло успешно. Это из действия перенаправления Mage_Authorizenet_Directpost_PaymentController
if (!empty($redirectParams['success'])
&& isset($redirectParams['x_invoice_num'])
&& isset($redirectParams['controller_action_name'])
) {
$this->_getDirectPostSession()->unsetData('quote_id');
$params['redirect_parent'] = Mage::helper('authorizenet')->getSuccessOrderUrl($redirectParams);
}
if (!empty($redirectParams['error_msg'])) {
$cancelOrder = empty($redirectParams['x_invoice_num']);
$this->_returnCustomerQuote($cancelOrder, $redirectParams['error_msg']);
}
Тем не менее, я мог сказать в моей ситуации, посмотрев на access.log [комбинированный], что была запись от /checkout/onepage
собирается /authorizenet/directpost_payment/returnQuote
,
После того, как я немного потрепался, покопался в коде и провел некоторые исследования, я чувствую, что это может быть только ошибкой в функции loadIframe, которая связана с onLoadIframe в directpost.js.
loadIframe : function() {
if (this.paymentRequestSent) {
switch (this.controller) {
case 'onepage':
this.paymentRequestSent = false;
if (!this.hasError) {
this.returnQuote();
}
break;
case 'sales_order_edit':
case 'sales_order_create':
if (!this.orderRequestSent) {
this.paymentRequestSent = false;
if (!this.hasError) {
this.returnQuote();
} else {
this.changeInputOptions('disabled', false);
toggleSelectsUnderBlock($('loading-mask'), true);
$('loading-mask').hide();
enableElements('save');
}
}
break;
}
if (this.tmpForm) {
document.body.removeChild(this.tmpForm);
}
}
},
Мне кажется, что он проверяет, был ли отправлен запрос на оплату, когда действие перенаправления заполняет iframe. Если запрос на оплату был отправлен, если он использовал одностраничный контроллер, и если в ответе НЕТ ошибки, верните предложение и, таким образом, оставьте его активным, и товары останутся в корзине...
Это не имеет смысла для меня, поэтому я удалил взрыв из этого. Теперь корзина очищается после заказа, и у меня, похоже, нет других проблем
Похоже, что сейчас, я хотел бы, чтобы кто-то сказал мне, что я не прав (серьезно).
loadIframe : function() {
if (this.paymentRequestSent) {
switch (this.controller) {
case 'onepage':
this.paymentRequestSent = false;
if (this.hasError) {
this.returnQuote();
}
break;
case 'sales_order_edit':
case 'sales_order_create':
if (!this.orderRequestSent) {
this.paymentRequestSent = false;
if (!this.hasError) {
this.returnQuote();
} else {
this.changeInputOptions('disabled', false);
toggleSelectsUnderBlock($('loading-mask'), true);
$('loading-mask').hide();
enableElements('save');
}
}
break;
}
if (this.tmpForm) {
document.body.removeChild(this.tmpForm);
}
}
},
Кажется, что это будет в случае контроллера 'sales_order_create', но я пока оставляю Magento в покое.