Files
2025-03-12 17:06:23 +01:00

385 lines
13 KiB
PHP

<?php
/**
* SOTESHOP/stPayment
*
* Ten plik należy do aplikacji stPayment opartej na licencji (Professional License SOTE).
* Nie zmieniaj tego pliku, jeśli chcesz korzystać z automatycznych aktualizacji oprogramowania.
* Jeśli chcesz wprowadzać swoje modyfikacje do programu, zapoznaj się z dokumentacją, jak zmieniać
* oprogramowanie bez zmiany kodu bazowego http://www.sote.pl/modifications
*
* @package stPayment
* @subpackage actions
* @copyright SOTE (www.sote.pl)
* @license http://www.sote.pl/license/sote (Professional License SOTE)
* @version $Id: actions.class.php 10 2009-08-24 09:32:18Z michal $
* @author Michal Prochowski <michal.prochowski@sote.pl>,
*/
/**
* Klasa stPaymentActions
*
* @package stPayment
* @subpackage actions
*/
class stPaymentActions extends stActions
{
/**
* Undocumented variable
*
* @var Order
*/
protected $order;
/**
* Przekierowanie na strone główną sklepu jeżeli nie została wybrana żadna akcja
*/
public function executeIndex()
{
$this->redirect('@homepage');
}
/**
* Aktualizowanie dostawy za pomocą Ajax
*/
public function executeAjaxPaymentTypeUpdate()
{
$paymnetTypeId = $this->getRequestParameter('id');
stPayment::getInstance($this->getContext())->set($paymnetTypeId);
}
/**
* Akcja obsługująca żądanie ręcznego przekierowania do serwisu płatności
*
* @return mixed
* @throws PropelException
* @throws stNotificationException
* @throws sfStopException
*/
public function executePay()
{
$this->order = OrderPeer::retrieveByIdAndHashCode($this->getRequestParameter('id'), $this->getRequestParameter('hash_code'));
$currency = stCurrency::getInstance($this->getContext());
$currency->setByIso($this->order->getOrderCurrency()->getShortcut());
if ($this->order->getIsPayed())
{
return $this->redirect('@stOrderSummary?id=' . $this->order->getId() . '&hash_code=' . $this->order->getHashCode());
}
$paymentType = $this->order->getOrderPayment()->getPaymentType();
if ($paymentType && $paymentType->getApiInstance() instanceof stPaymentTypeInterface)
{
$url = $this->processPayment($paymentType->getApiInstance(), $this->order);
return $this->redirect($url);
}
$this->smarty = new stSmarty($this->getModuleName());
}
/**
* Akcja obsługująca żądanie z automatycznym przekierowaniem do serwisu płatności
*
* @return sfView::NONE
* @throws stPaymentTypeConfigurationException
* @throws PropelException
* @throws stNotificationException
*/
public function executeProcessPayment()
{
$type = $this->getRequestParameter('type');
$orderId = $this->getRequestParameter('order_id');
$orderHash = $this->getRequestParameter('order_hash');
$paymentType = stPaymentType::get($type);
$order = OrderPeer::retrieveByIdAndHashCode($orderId, $orderHash);
return $this->renderJSON([
'redirect' => $this->processPayment($paymentType, $order)
]);
}
/**
* Akcja obsługująca żądania błędów podczas przetwarzania płatności
*
* @return void
* @throws PropelException
* @throws sfViewException
* @throws stPaymentTypeConfigurationException
*/
public function executeFailure()
{
$type = $this->getRequestParameter('type');
$smarty = new stSmarty($this->getModuleName());
$webpage = WebpagePeer::retrieveByState('CONTACT');
if ($webpage)
{
sfLoader::loadHelpers(array('Helper', 'stUrl'));
$smarty->assign('contact_url', st_url_for('stWebpageFrontend/index?url=' . $webpage->getFriendlyUrl()));
}
$paymentType = stPaymentType::get($type);
$smarty->assign('title', $paymentType->getConfiguration()->getName());
$smarty->assign('logo', $paymentType->getLogoPath());
$smarty->assign('message', $this->getContext()->getI18N()->__('Wystąpił błąd podczas przetwarzania płatności.'));
$this->smarty = $smarty;
}
/**
* Akcja obsługująca żądania powrotu klienta do sklepu
*
* @return void
* @throws stPaymentTypeConfigurationException
* @throws PropelException
* @throws sfException
* @throws stNotificationException
*/
public function executeReturn()
{
$type = $this->getRequestParameter('type');
$orderId = $this->getRequestParameter('order_id');
$orderHash = $this->getRequestParameter('order_hash');
$paymentType = stPaymentType::get($type);
$logger = $paymentType->getLogger();
$order = OrderPeer::retrieveByIdAndHashCode($orderId, $orderHash);
if (null === $order)
{
$logger->fatal('Wystąpił nieoczekiwany wyjątek po powrocie klienta do sklepu: `Zamówienie o id **%%id%%** nie istnieje...`', [
'%%id%%' => $orderId,
]);
throw new sfException(sprintf('Zamówienie o id **%%id%% nie istnieje...', $orderId));
}
$ok = $paymentType->return($order, $this->getRequest());
if (false === $ok)
{
$payment = $order->getOrderPayment();
$payment->setCancel(true);
$payment->save();
$logger->info('Płatność dla zamówienia **[%%number%%](%%link%%)** została anulowana na życzenie klienta', [
'%%number%%' => $order->getNumber(),
'%%link%%' => $this->generateBackendUrl('@stOrder?action=edit&id='.$order->getId()),
]);
}
else
{
$logger->info('Klient zakończył opłacanie zamówienia **[%%number%%](%%link%%)** i powrócił do sklepu', [
'%%number%%' => $order->getNumber(),
'%%link%%' => $this->generateBackendUrl('@stOrder?action=edit&id='.$order->getId()),
]);
if (true === $ok)
{
$this->processPayment($paymentType, $order);
}
}
$smarty = new stSmarty($this->getModuleName());
$smarty->assign('title', $paymentType->getConfiguration()->getName());
$smarty->assign('logo', $paymentType->getLogoPath());
$smarty->assign('canceled', false === $ok);
$this->smarty = $smarty;
}
/**
* Akcja obsługująca żądania zmiany statusu płatności
*
* @return string
* @throws stPaymentTypeConfigurationException
* @throws PropelException
* @throws stNotificationException
*/
public function executeStatusNotification()
{
$type = $this->getRequestParameter('type');
$orderId = $this->getRequestParameter('order_id');
$orderHash = $this->getRequestParameter('order_hash');
$securityToken = $this->getRequestParameter('security_token');
$paymentType = stPaymentType::get($type);
$logger = $paymentType->getLogger();
$order = OrderPeer::retrieveByIdAndHashCode($orderId, $orderHash);
$logger->info('Przetwarzanie powiadomienia o statusie płatności');
if (null === $order)
{
$paymentType->getLogger()->fatal('Wystąpił nieoczekiwany wyjątek: `Zamówienie o id **%%id%%** nie istnieje...`', [
'%%id%%' => $orderId,
]);
return sfView::HEADER_ONLY;
}
try
{
if ($securityToken != stPaymentTypeAbstract::generateSecurityToken($order))
{
$paymentType->getLogger()->error('Nieprawidłowy token bezpieczeństwa');
}
else
{
$this->processStatusNotification($paymentType, $order);
}
}
catch (stPaymentTypeException $e)
{
}
return sfView::HEADER_ONLY;
}
public function executePaymentInformation()
{
$type = $this->getRequestParameter('type');
$amount = $this->getRequestParameter('amount');
$currencyAmount = $this->getRequestParameter('currency_amount');
$paymentType = stPaymentType::get($type);
$smarty = new stSmarty($paymentType->getConfiguration()->getFrontendModule());
$parameters = $paymentType->getPaymentInformation(stPrice::round($amount), stPrice::round($currencyAmount));
foreach ($parameters as $name => $value)
{
$smarty->assign($name, $value);
}
return $this->renderText($smarty->fetch('payment_information.html'));
}
/**
* Akcja obsługująca żądanie zwracające listę kanałów płatności
*
* @return void
* @throws PropelException
* @throws sfError404Exception
*/
public function executeSelectChannel()
{
$id = $this->getRequestParameter('id');
/**
* @var stBasket $basket
*/
$basket = $this->getUser()->getBasket();
$amount = $basket->getTotalAmount(true) + stDeliveryFrontend::getInstance($basket)->getTotalDeliveryCost(true);
$payment = PaymentTypePeer::retrieveByPK($id);
if (null === $payment)
{
return $this->forward404();
}
$api = $payment->getApiInstance();
if ($api instanceof stPaymentTypeInterface)
{
$smarty = new stSmarty($api->getConfiguration()->getFrontendModule());
if ($smarty->themeTemplateExists('payment_select_channel.html'))
{
$smarty->register_function('parent', [$this, 'getSelectChannelTemplate']);
}
}
else
{
$smarty = new stSmarty('stPayment');
}
$smarty->assign('amount', $amount);
$smarty->assign('payment', $payment);
$smarty->assign('payment_channels', $payment->getChannels($amount));
$this->smarty = $smarty;
}
public function getSelectChannelTemplate(?array $params, Smarty $currentSmarty)
{
$smarty = new stSmarty($this->getModuleName());
$smarty->_tpl_vars = !empty($params) ? array_merge($currentSmarty->get_template_vars(), $params) : $currentSmarty->get_template_vars();
return $smarty->fetch('payment_select_channel.html');
}
/**
* Metoda przetwarzania płatnośc przed przejściem do serwisu
*
* @param stPaymentTypeInterface $paymentType
* @param Order $order
* @return string
* @throws PropelException
* @throws stNotificationException
*/
protected function processPayment(stPaymentTypeInterface $paymentType, Order $order): string
{
try
{
$paymentType->getLogger()->info('Przetwarzanie płatności dla zamówienia **[%%number%%](%%link%%)**', [
'%%number%%' => $order->getNumber(),
'%%link%%' => $this->generateBackendUrl('@stOrder?action=edit&id='.$order->getId()),
]);
$url = $paymentType->process($order);
$payment = $order->getOrderPayment();
$payment->setInProgress(true);
$payment->save();
$paymentType->getLogger()->info('Przetwarzanie płatności dla zamówienia **[%%number%%](%%link%%)** zakończone pomyślnie, przekierowuję klienta do serwisu płatności <%%url%%>', [
'%%number%%' => $order->getNumber(),
'%%link%%' => $this->generateBackendUrl('@stOrder?action=edit&id='.$order->getId()),
'%%url%%' => $url,
]);
return $url;
}
catch (stPaymentTypeException $e)
{
$paymentType->getLogger()->exception($e);
}
return $paymentType->getFailureUrl($order);
}
protected function processStatusNotification(stPaymentTypeInterface $paymentType, Order $order): bool
{
if ($paymentType->statusNotification($order, $this->getRequest()))
{
$payment = $order->getOrderPayment();
$payment->setStatus(true);
$payment->save();
$paymentType->getLogger()->info('Zamówienie **[%%number%%](%%link%%)** zostało opłacone', [
'%%number%%' => $order->getNumber(),
'%%link%%' => $this->generateBackendUrl('@stOrder?action=edit&id='.$order->getId()),
]);
return true;
}
return false;
}
protected function generateBackendUrl($internalUrl)
{
$this->getRequest()->setScriptNameByApp('backend');
$result = $this->getController()->genUrl($internalUrl);
$this->getRequest()->setScriptNameByApp('frontend');
return $result;
}
}