Перенаправление пользовательского способа повторяющейся оплаты на платежный шлюз после размещения заказа в Magento 1
Я пытаюсь реализовать пользовательский модуль повторяющихся платежей для Magento 1.9.
Я следую учебнику из Блога Modulesgarden в сочетании с Paypal Express.
Мне удалось создать новый способ оплаты, который отображается при оформлении заказа только для повторяющихся продуктов. Если я создам только поддельный запрос на тестирование, как в учебнике, все работает хорошо, заказы созданы, профиль создан, я могу отменить или приостановить профиль из Моего аккаунта.
Проблема в том, что я не знаю, как перенаправить на страницу шлюза после размещения заказа. До сих пор я пытался добавить в свою платежную модель метод getOrderPlaceRedirectUrl()
, который вызывается в методе saveOrder()
, но это не работает, потому что метод выглядит так:
public function saveOrder()
{
$this->validate();
$isNewCustomer = false;
switch ($this->getCheckoutMethod()) {
case self::METHOD_GUEST:
$this->_prepareGuestQuote();
break;
case self::METHOD_REGISTER:
$this->_prepareNewCustomerQuote();
$isNewCustomer = true;
break;
default:
$this->_prepareCustomerQuote();
break;
}
$service = Mage::getModel('sales/service_quote', $this->getQuote());
$service->submitAll();
if ($isNewCustomer) {
try {
$this->_involveNewCustomer();
} catch (Exception $e) {
Mage::logException($e);
}
}
$this->_checkoutSession->setLastQuoteId($this->getQuote()->getId())
->setLastSuccessQuoteId($this->getQuote()->getId())
->clearHelperData();
$order = $service->getOrder();
if ($order) {
Mage::dispatchEvent('checkout_type_onepage_save_order_after',
array('order'=>$order, 'quote'=>$this->getQuote()));
/**
* a flag to set that there will be redirect to third party after confirmation
* eg: paypal standard ipn
*/
$redirectUrl = $this->getQuote()->getPayment()->getOrderPlaceRedirectUrl();
/**
* we only want to send to customer about new order when there is no redirect to third party
*/
if (!$redirectUrl && $order->getCanSendNewEmailFlag()) {
try {
$order->queueNewOrderEmail();
} catch (Exception $e) {
Mage::logException($e);
}
}
// add order information to the session
$this->_checkoutSession->setLastOrderId($order->getId())
->setRedirectUrl($redirectUrl)
->setLastRealOrderId($order->getIncrementId());
// as well a billing agreement can be created
$agreement = $order->getPayment()->getBillingAgreement();
if ($agreement) {
$this->_checkoutSession->setLastBillingAgreementId($agreement->getId());
}
}
// add recurring profiles information to the session
$profiles = $service->getRecurringPaymentProfiles();
if ($profiles) {
$ids = array();
foreach ($profiles as $profile) {
$ids[] = $profile->getId();
}
$this->_checkoutSession->setLastRecurringProfileIds($ids);
// TODO: send recurring profile emails
}
Mage::dispatchEvent(
'checkout_submit_all_after',
array('order' => $order, 'quote' => $this->getQuote(), 'recurring_profiles' => $profiles)
);
return $this;
}
Метод вызывается только в том случае, если есть порядок, но его нет, потому что при использовании повторяющихся профилей порядок создается позже, поэтому выполняется только код внутри if ($profiles) {}
, и нет redirectUrl
.
Затем я попытался использовать метод getCheckoutRedirectUrl()
, как он используется в PayPal Express. Теперь я перенаправлен на платежный шлюз, но проблема в том, что этот метод вызывается в savePaymentAction()
, и это означает, что я перенаправлен перед этапом проверки заказа.
Можно ли перенаправить на платежный шлюз только после размещения заказа, где-нибудь в методе submitRecurringProfile()
? Я не хочу удалять этап проверки заказа, потому что клиенты должны принять условия и положения.
Спасибо вам!
2 answers
Итак, после нескольких дней исследований и отладки я только что нашел простое решение.
Во-первых, поскольку мы не можем изменять файлы ядра, я просто копирую Onepage.php
из ядра:
App/code/core/Mage/Checkout/Model/Type/Onepage.php
Кому:
App/code/local/Mage/Checkout/Model/Type/Onepage.php
И я внес некоторые изменения в метод saveOrder()
. Теперь этот метод выглядит так:
public function saveOrder()
{
$this->validate();
$isNewCustomer = false;
switch ($this->getCheckoutMethod()) {
case self::METHOD_GUEST:
$this->_prepareGuestQuote();
break;
case self::METHOD_REGISTER:
$this->_prepareNewCustomerQuote();
$isNewCustomer = true;
break;
default:
$this->_prepareCustomerQuote();
break;
}
$service = Mage::getModel('sales/service_quote', $this->getQuote());
$service->submitAll();
if ($isNewCustomer) {
try {
$this->_involveNewCustomer();
} catch (Exception $e) {
Mage::logException($e);
}
}
$this->_checkoutSession->setLastQuoteId($this->getQuote()->getId())
->setLastSuccessQuoteId($this->getQuote()->getId())
->clearHelperData();
$order = $service->getOrder();
/**
* a flag to set that there will be redirect to third party after confirmation
* eg: paypal standard ipn
*/
$redirectUrl = $this->getQuote()->getPayment()->getOrderPlaceRedirectUrl();
if ($order) {
Mage::dispatchEvent('checkout_type_onepage_save_order_after',
array('order'=>$order, 'quote'=>$this->getQuote()));
/**
* we only want to send to customer about new order when there is no redirect to third party
*/
if (!$redirectUrl && $order->getCanSendNewEmailFlag()) {
try {
$order->queueNewOrderEmail();
} catch (Exception $e) {
Mage::logException($e);
}
}
// add order information to the session
$this->_checkoutSession->setLastOrderId($order->getId())
->setRedirectUrl($redirectUrl)
->setLastRealOrderId($order->getIncrementId());
// as well a billing agreement can be created
$agreement = $order->getPayment()->getBillingAgreement();
if ($agreement) {
$this->_checkoutSession->setLastBillingAgreementId($agreement->getId());
}
}
// add recurring profiles information to the session
$profiles = $service->getRecurringPaymentProfiles();
if ($profiles) {
$this->_checkoutSession->setRedirectUrl($redirectUrl);
$ids = array();
foreach ($profiles as $profile) {
$ids[] = $profile->getId();
}
$this->_checkoutSession->setLastRecurringProfileIds($ids);
// TODO: send recurring profile emails
}
Mage::dispatchEvent(
'checkout_submit_all_after',
array('order' => $order, 'quote' => $this->getQuote(), 'recurring_profiles' => $profiles)
);
return $this;
}
Различия заключаются в том, что я определил $redirectUrl
даже если заказа нет, и я устанавливаю его в $checkoutSession
в обоих случаях, если существует заказ или повторяющийся профиль. Вы можете сравнить методы saveOrder()
из моего вопроса и моего ответа, чтобы увидеть различия.
После этого вы должны создать метод getOrderPlaceRedirectUrl()
в своей платежной модели, и все должно работать идеально.
Надеюсь, это поможет другим разработчикам!
Я столкнулся с точно такой же проблемой и подошел к ней по-другому.
Я создал наблюдателя для события checkout_submit_all_after и внутри наблюдателя я проверяю, были ли добавлены какие-либо повторяющиеся профили в данные события. Если это так, то я принудительно перенаправляю свое действие.
Вот код метода наблюдателя
public function checkoutSubmitAllFunction(Varien_Event_Observer $observer){
Mage::log(__FUNCTION__, Zend_Log::DEBUG, $this->logFileName);
if(0 < sizeof($observer->getEvent()->getData()['recurring_profiles'])){
$recurringProfileId = $observer->getEvent()->getData()['recurring_profiles'][0]['profile_id'];
if($recurringProfileId){
/* Construct the redirect URL. */
$redirectUrl = Mage::getUrl('module/controller/action', ['_query' => ['profileId' => $recurringProfileId]]);
/* Set the redirect URL. */
Mage::getSingleton('checkout/session')->setRedirectUrl($redirectUrl);
}
}
return $this;
}
Надеюсь, это поможет. :)