505 lines
16 KiB
PHP
505 lines
16 KiB
PHP
<?php
|
|
|
|
/**
|
|
* SOTESHOP/stPrzelewy24Plugin
|
|
*
|
|
* Ten plik należy do aplikacji stPrzelewy24Plugin 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 stPrzelewy24Plugin
|
|
* @subpackage libs
|
|
* @copyright SOTE (www.sote.pl)
|
|
* @license http://www.sote.pl/license/sote (Professional License SOTE)
|
|
* @version $Id$
|
|
* @author Marcin Butlak <marcin.butlak@sote.pl>
|
|
*/
|
|
|
|
/**
|
|
* Adres Przelewy24
|
|
*/
|
|
define('PRZELEWY24_URL', 'https://secure.przelewy24.pl/index.php');
|
|
|
|
define('PRZELEWY24_URL_TEST', 'https://sandbox.przelewy24.pl/index.php');
|
|
|
|
/**
|
|
* Klasa stPrzelewy24
|
|
*
|
|
* @package stPrzelewy24Plugin§
|
|
* @subpackage libs
|
|
*/
|
|
class stPrzelewy24 implements stPaymentInterface
|
|
{
|
|
const HIGHLIGHTED = [
|
|
'paypo' => ['name' => 'PayPo', 'id' => 227, 'description' => 'Kup teraz, zapłać za 30 dni.'],
|
|
'blik' => ['name' => 'Blik', 'id' => 154 , 'description' => 'Szybkie płatności Blik.'],
|
|
];
|
|
|
|
/**
|
|
* Konfiguracja
|
|
* @var stConfig
|
|
*/
|
|
private $config;
|
|
|
|
private $context = null;
|
|
|
|
private $currency = null;
|
|
|
|
private $id;
|
|
|
|
private $crc;
|
|
|
|
private $reportKey = null;
|
|
|
|
private $testMode = null;
|
|
|
|
/**
|
|
* Lista płatności wyróżnionych dla karty produktu
|
|
*
|
|
* @var mixed
|
|
*/
|
|
private $highlightedForProduct = null;
|
|
|
|
/**
|
|
* Lista płatności wyróżnionych dla koszyka
|
|
*
|
|
* @var mixed
|
|
*/
|
|
private $highlightedForBasket = null;
|
|
|
|
protected $paymentMethods = null;
|
|
|
|
protected $basketPaymentTypes = null;
|
|
|
|
/**
|
|
* Konstruktor - ładownianie konfiguracji
|
|
*/
|
|
public function __construct($id = null, $crc = null, $reportKey = null, $testMode = null)
|
|
{
|
|
$this->config = stConfig::getInstance('stPrzelewy24Backend');
|
|
|
|
if (null === $id)
|
|
{
|
|
$id = $this->config->get('przelewy24_id');
|
|
}
|
|
|
|
if (null === $crc)
|
|
{
|
|
$crc = $this->config->get('salt');
|
|
}
|
|
|
|
if (null === $reportKey)
|
|
{
|
|
$reportKey = $this->config->get('report_key');
|
|
}
|
|
|
|
if (null === $testMode)
|
|
{
|
|
$testMode = $this->config->get('test');
|
|
}
|
|
|
|
$this->id = trim($id);
|
|
$this->crc = trim($crc);
|
|
$this->reportKey = trim($reportKey);
|
|
$this->testMode = $testMode;
|
|
$this->context = sfContext::getInstance();
|
|
$this->currency = stCurrency::getInstance($this->context)->get();
|
|
}
|
|
|
|
/**
|
|
* Sprawdza czy serwis płatności ma dodatkowe kanały
|
|
* @return bool
|
|
*/
|
|
public function hasChannels(): bool
|
|
{
|
|
return $this->config->get('payment_channels_enabled');
|
|
}
|
|
|
|
/**
|
|
* Zwraca listę kanałów płatności
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getChannels(): array
|
|
{
|
|
if (false === $this->config->get('has_valid_configuration', null))
|
|
{
|
|
return [];
|
|
}
|
|
|
|
$channels = [];
|
|
$highlighted = [];
|
|
$selected = $this->config->get('channels', []);
|
|
|
|
try
|
|
{
|
|
$paymentMethods = $this->getPaymentMethods();
|
|
|
|
foreach ($this->getHighlightedPaymentsForBasket() as $current)
|
|
{
|
|
$highlighted[$current['id']] = $current;
|
|
}
|
|
|
|
foreach ($paymentMethods as $index => $method)
|
|
{
|
|
if (isset($highlighted[$method->id]))
|
|
{
|
|
$channels[] = [
|
|
'id' => $method->id,
|
|
'logo' => $method->imgUrl,
|
|
'name' => $method->name,
|
|
'description' => $highlighted[$method->id]['description'],
|
|
'highlighted' => true,
|
|
];
|
|
|
|
unset($paymentMethods[$index]);
|
|
}
|
|
}
|
|
|
|
foreach ($paymentMethods as $method)
|
|
{
|
|
if ((empty($selected) || in_array($method->id, $selected)) && $method->status)
|
|
{
|
|
$channels[] = [
|
|
'id' => $method->id,
|
|
'logo' => $method->imgUrl,
|
|
'name' => $method->name,
|
|
'description' => null,
|
|
'highlighted' => false,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
catch (stPrzelewyException $e)
|
|
{
|
|
if ($e->getCode() == 403 || $e->getCode() == 401)
|
|
{
|
|
$this->showNotification('payment.auth.problem', 'stPayment');
|
|
}
|
|
}
|
|
|
|
return $channels;
|
|
}
|
|
|
|
public function getLogoPath()
|
|
{
|
|
return '/plugins/stPrzelewy24Plugin/images/logo.svg';
|
|
}
|
|
|
|
public function isAutoRedirectEnabled()
|
|
{
|
|
return $this->config->get('autoredirect');
|
|
}
|
|
|
|
/**
|
|
* Zwraca listę dodatkowych typów płatności jakie mają pojawić się w koszyku
|
|
*
|
|
* @return PaymentType[]
|
|
*/
|
|
public function getBasketPaymentTypes($withDefault = false): array
|
|
{
|
|
if (null === $this->basketPaymentTypes)
|
|
{
|
|
$basketPaymentTypes = [];
|
|
|
|
foreach (PaymentTypePeer::doSelectByModuleName('stPrzelewy24') as $paymentType)
|
|
{
|
|
$type = $paymentType->getConfigurationParameter('type');
|
|
|
|
if ($type || $withDefault)
|
|
{
|
|
$basketPaymentTypes[$paymentType->getConfigurationParameter('type', 'default')] = $paymentType;
|
|
}
|
|
}
|
|
|
|
$this->basketPaymentTypes = $basketPaymentTypes;
|
|
}
|
|
|
|
return $this->basketPaymentTypes;
|
|
}
|
|
|
|
/**
|
|
* Zwraca listę płatności wyróżnionych dla karty produktu
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getHighlightedPaymentsForProduct(): array
|
|
{
|
|
if (null === $this->highlightedForProduct)
|
|
{
|
|
$highlighted = [];
|
|
|
|
if ($this->config->has('highlighted_for_product'))
|
|
{
|
|
$i18n = $this->context->getI18N();
|
|
$i18n->setCulture($this->config->getCulture());
|
|
|
|
foreach ($this->config->get('highlighted_for_product', []) as $namespace)
|
|
{
|
|
$highlighted[$namespace] = [
|
|
'name' => $i18n->__(self::HIGHLIGHTED[$namespace]['name']),
|
|
'id' => self::HIGHLIGHTED[$namespace]['id'],
|
|
'description' => $i18n->__(self::HIGHLIGHTED[$namespace]['description'], null, 'stPayment'),
|
|
];
|
|
}
|
|
|
|
$i18n->setCulture($this->context->getUser()->getCulture());
|
|
}
|
|
|
|
$this->highlightedForProduct = $highlighted;
|
|
}
|
|
|
|
return $this->highlightedForProduct;
|
|
}
|
|
|
|
|
|
/**
|
|
* Zwraca listę płatności wyróżnionych dla karty koszyka
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getHighlightedPaymentsForBasket(): array
|
|
{
|
|
if (null === $this->highlightedForBasket)
|
|
{
|
|
$highlighted = [];
|
|
|
|
if ($this->config->has('highlighted_for_basket'))
|
|
{
|
|
$i18n = $this->context->getI18N();
|
|
$i18n->setCulture($this->config->getCulture());
|
|
|
|
foreach ($this->config->get('highlighted_for_basket', []) as $namespace)
|
|
{
|
|
$highlighted[$namespace] = [
|
|
'name' => $i18n->__(self::HIGHLIGHTED[$namespace]['name']),
|
|
'id' => self::HIGHLIGHTED[$namespace]['id'],
|
|
'description' => $i18n->__(self::HIGHLIGHTED[$namespace]['description'], null, 'stPayment'),
|
|
];
|
|
}
|
|
|
|
$i18n->setCulture($this->context->getUser()->getCulture());
|
|
}
|
|
|
|
$this->highlightedForBasket = $highlighted;
|
|
}
|
|
|
|
return $this->highlightedForBasket;
|
|
}
|
|
|
|
/**
|
|
* Sprawdza poprawność konfiguracji danych dostępowych
|
|
*
|
|
* @return bool
|
|
* @throws stPrzelewyException
|
|
* @throws Exception
|
|
*/
|
|
public function testConnection()
|
|
{
|
|
$api = new Przelewy24($this->id, $this->id, $this->crc, $this->testMode);
|
|
|
|
$res = $api->testConnection();
|
|
|
|
if ($res['error'])
|
|
{
|
|
throw new stPrzelewyException($res['errorMessage']);
|
|
}
|
|
|
|
return !$this->config->get('payment_channels_enabled') || false !== $this->getPaymentMethods($this->context->getUser()->getCulture());
|
|
}
|
|
|
|
/**
|
|
* Pobranie metod płatności
|
|
*
|
|
* @param string|null $culture
|
|
* @return array|false
|
|
* @throws stPrzelewyException
|
|
*/
|
|
public function getPaymentMethods(?string $culture = null)
|
|
{
|
|
if (null === $this->paymentMethods)
|
|
{
|
|
if (!$this->checkPaymentConfiguration() || !$this->config->get('payment_channels_enabled'))
|
|
{
|
|
$this->paymentMethods = false;
|
|
}
|
|
else
|
|
{
|
|
$lang = $culture == 'pl_PL' ? 'pl' : 'en';
|
|
|
|
if ($this->testMode)
|
|
{
|
|
$url = "https://sandbox.przelewy24.pl/api/v1/payment/methods/{$lang}";
|
|
}
|
|
else
|
|
{
|
|
$url = "https://secure.przelewy24.pl/api/v1/payment/methods/{$lang}";
|
|
}
|
|
|
|
$ch = curl_init($url);
|
|
|
|
$authHeader = array(
|
|
"Content-Type: application/json",
|
|
"Authorization: Basic ".base64_encode($this->id.":".$this->reportKey)
|
|
);
|
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $authHeader);
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
|
|
$jsonResponse = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
if (401 == $httpCode)
|
|
{
|
|
stPayment::log('przelewy24', ['getPaymentMethods', $url, $authHeader, "Nieprawidłowa autoryzacja"], stPayment::LOG_ERROR);
|
|
throw new stPrzelewyException("Nieprawidłowa autoryzacja", $httpCode);
|
|
}
|
|
|
|
if (false === $jsonResponse)
|
|
{
|
|
$error = curl_error($ch);
|
|
stPayment::log('przelewy24', ['getPaymentMethods', $url, $authHeader, $error, $httpCode], stPayment::LOG_ERROR);
|
|
throw new stPrzelewyException($error, $httpCode);
|
|
}
|
|
|
|
$response = json_decode($jsonResponse);
|
|
|
|
if (!empty($response->error))
|
|
{
|
|
stPayment::log('przelewy24', ['getPaymentMethods', $url, $authHeader, $response->error], stPayment::LOG_ERROR);
|
|
throw new stPrzelewyException($response->error, $httpCode);
|
|
}
|
|
|
|
$paymentMethods = [];
|
|
|
|
foreach ($response->data as $method)
|
|
{
|
|
$paymentMethods[$method->id] = $method;
|
|
}
|
|
|
|
$this->paymentMethods = $paymentMethods;
|
|
}
|
|
}
|
|
|
|
return $this->paymentMethods;
|
|
}
|
|
|
|
public function getPaymentUrl(Order $order)
|
|
{
|
|
$api = new Przelewy24($this->id, $this->id, $this->crc, $this->testMode);
|
|
$i18n = $this->context->getI18N();
|
|
$controller = $this->context->getController();
|
|
$client = $order->getOrderUserDataBilling();
|
|
$country = $client->getCountry();
|
|
$currency = $order->getOrderCurrency();
|
|
$payment = $order->getOrderPayment();
|
|
$amount = $order->getUnpaidAmount() * 100;
|
|
$paymentChannel = $payment->getConfigurationParameter('payment_channel');
|
|
$p24_description = $i18n->__("Zamówienie nr", null, 'stOrder').' '.$order->getNumber();
|
|
$api->addValue("p24_amount", $amount);
|
|
$api->addValue("p24_currency", $currency->getShortcut());
|
|
$api->addValue("p24_description", $p24_description);
|
|
$api->addValue("p24_email", $order->getOptClientEmail());
|
|
$api->addValue("p24_session_id", $order->getId().':'.uniqid());
|
|
|
|
if ($paymentChannel)
|
|
{
|
|
$api->addValue('p24_method', is_array($paymentChannel) ? $paymentChannel['id'] : $paymentChannel);
|
|
}
|
|
|
|
$api->addValue("p24_client", $order->getOptClientName());
|
|
$api->addValue("p24_address", $client->getAddress());
|
|
$api->addValue("p24_zip", $client->getCode());
|
|
$api->addValue("p24_city", $client->getTown());
|
|
$api->addValue("p24_country", $country ? $country->getIsoA2() : null);
|
|
$api->addValue("p24_language", strtolower(stPaymentType::getLanguage()));
|
|
|
|
$api->addValue("p24_encoding", "UTF-8");
|
|
|
|
$api->addValue("p24_url_return", $controller->genUrl('@stPrzelewy24Plugin?action=returnSuccess', true));
|
|
$api->addValue("p24_url_status", $controller->genUrl('@stPrzelewy24Plugin?action=status&id='.$order->getId().'&hash='.$order->getHashCode(), true));
|
|
$api->addValue('p24_name_1', $p24_description);
|
|
$api->addValue('p24_quantity_1', 1);
|
|
$api->addValue('p24_price_1', $amount);
|
|
|
|
stPayment::log('przelewy24', ['trnRegister', $api->getValues()]);
|
|
|
|
$res = $api->trnRegister(false);
|
|
|
|
stPayment::log('przelewy24', ['trnRegister Response', $res]);
|
|
|
|
if (!empty($res['error']))
|
|
{
|
|
if (false !== strpos($res['errorMessage'], 'unfinished_registration'))
|
|
{
|
|
$this->showNotification('payment.unfinished.registration');
|
|
}
|
|
|
|
if (false !== strpos($res['errorMessage'], 'p24_posId:') || false !== strpos($res['errorMessage'], 'p24_sign:'))
|
|
{
|
|
$this->showNotification('payment.auth.problem', 'stPayment');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return $api->trnRequest($res['token'], false);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function verify(Order $order, sfRequest $request)
|
|
{
|
|
$api = new Przelewy24($this->id, $this->id, $this->crc, $this->testMode);
|
|
$api->addValue('p24_session_id', $request->getParameter('p24_session_id'));
|
|
$api->addValue('p24_order_id', $request->getParameter('p24_order_id'));
|
|
$api->addValue('p24_currency', $order->getOrderCurrency()->getShortcut());
|
|
$api->addValue('p24_amount', $order->getUnpaidAmount() * 100);
|
|
|
|
$res = $api->trnVerify();
|
|
|
|
if (isset($res['error']) && !$res['error'])
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
throw new Exception($res['error'] . ' - '. $res['errorMessage']);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Sprawdzenie czy płatność została skonfiguraowana
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function checkPaymentConfiguration()
|
|
{
|
|
// if (SF_APP != 'backend' && !$this->reportKey && $this->config->get('last_notification_update') <= time() - 300)
|
|
// {
|
|
// stNotification::getInstance()->addAlert('stPrzelewy24Plugin', 'payment.configuration.required', [
|
|
// 'singular' => true,
|
|
// 'action' => '@stPrzelewy24Plugin'
|
|
// ]);
|
|
|
|
// $this->config->set('last_notification_update', time());
|
|
// $this->config->save();
|
|
// }
|
|
|
|
return $this->config->get('enabled') && $this->id && $this->crc && (SF_APP != 'frontend' || false !== $this->config->get('has_valid_configuration', null) && in_array($this->currency->getShortcut(), array("PLN", "EUR", "GBP", "CZK")));
|
|
}
|
|
|
|
protected function showNotification(string $message, string $i18nCatalogue = 'stPrzelewy24Backend')
|
|
{
|
|
stNotification::getInstance()->addAlert('stPrzelewy24Plugin', $message, [
|
|
'singular' => true,
|
|
'action' => '@stPrzelewy24Plugin',
|
|
'i18n_catalogue' => $i18nCatalogue,
|
|
'call_count' => 0,
|
|
]);
|
|
}
|
|
} |