*/ /** * 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, ]); } }