first commit

This commit is contained in:
2025-03-12 17:06:23 +01:00
commit 2241f7131f
13185 changed files with 1692479 additions and 0 deletions

View File

@@ -0,0 +1,270 @@
<?php
/**
* Przelewy24 comunication class
*
* @author DialCom24 Sp. z o.o.
* @copyright DialCom24 Sp. z o.o.
* @version 1.1
* @since 2014-04-29
*/
/**
*
* Communication protol version
* @var double
*/
define("P24_VERSION", "3.2");
class Przelewy24
{
/**
* Live system URL address
* @var string
*/
private $hostLive = "https://secure.przelewy24.pl/";
/**
* Sandbox system URL address
* @var string
*/
private $hostSandbox = "https://sandbox.przelewy24.pl/";
/**
* Use Live (false) or Sandbox (true) enviroment
* @var bool
*/
private $testMode = false;
/**
* Merchant posId
* @var int
*/
private $posId = 0;
/**
* Salt to create a control sum (from P24 panel)
* @var string
*/
private $salt = "";
/**
* Array of POST data
* @var array
*/
private $postData = array();
/**
*
* Obcject constructor. Set initial parameters
* @param int $merchantId
* @param int $posId
* @param string $salt
* @param bool $testMode
*/
public function __construct($merchantId, $posId, $salt, $testMode = false)
{
$this->posId = (int) $posId;
$this->salt = $salt;
if ($testMode)
{
$this->hostLive = $this->hostSandbox;
}
$this->addValue("p24_merchant_id", $merchantId);
$this->addValue("p24_pos_id", $this->posId);
$this->addValue("p24_api_version", P24_VERSION);
return true;
}
/**
*
* Returns host URL
*/
public function getHost()
{
return $this->hostLive;
}
/**
*
* Add value do post request
* @param string $name Argument name
* @param mixed $value Argument value
* @todo Add postData validation
*/
public function addValue($name, $value)
{
$this->postData[$name] = $value;
}
/**
* Returns post request values
*
* @return array
*/
public function getValues()
{
return $this->postData;
}
/**
*
* Function is testing a connection with P24 server
* @return array Array(INT Error, Array Data), where data
*/
public function testConnection()
{
$crc = md5($this->posId . "|" . $this->salt);
$ARG["p24_pos_id"] = $this->posId;
$ARG["p24_sign"] = $crc;
$RES = $this->callUrl("testConnection", $ARG);
return $RES;
}
/**
*
* Prepare a transaction request
* @param bool $redirect Set true to redirect to Przelewy24 after transaction registration
* @return array array(INT Error code, STRING Token)
*/
public function trnRegister($redirect = false)
{
$crc = md5($this->postData["p24_session_id"] . "|" . $this->posId . "|" . $this->postData["p24_amount"] . "|" . $this->postData["p24_currency"] . "|" . $this->salt);
$this->addValue("p24_sign", $crc);
$RES = $this->callUrl("trnRegister", $this->postData);
if ($RES["error"] == "0")
{
$token = $RES["token"];
}
else
{
return $RES;
}
if ($redirect)
{
$this->trnRequest($token);
}
return array("error" => 0, "token" => $token);
}
/**
* Redirects or returns URL to a P24 payment screen
* @param string $token Token
* @param bool $redirect If set to true redirects to P24 payment screen. If set to false function returns URL to redirect to P24 payment screen
* @return string URL to P24 payment screen
*/
public function trnRequest($token, $redirect = true)
{
if ($redirect)
{
header("Location:" . $this->hostLive . "trnRequest/" . $token);
return "";
}
else
{
return $this->hostLive . "trnRequest/" . $token;
}
}
/**
*
* Function verify received from P24 system transaction's result.
* @return array
*/
public function trnVerify()
{
$crc = md5($this->postData["p24_session_id"] . "|" . $this->postData["p24_order_id"] . "|" . $this->postData["p24_amount"] . "|" . $this->postData["p24_currency"] . "|" . $this->salt);
$this->addValue("p24_sign", $crc);
$RES = $this->callUrl("trnVerify", $this->postData);
return $RES;
}
/**
*
* Function contect to P24 system
* @param string $function Method name
* @param array $ARG POST parameters
* @return array array(INT Error code, ARRAY Result)
*/
private function callUrl($function, $ARG)
{
if (!in_array($function, array("trnRegister", "trnRequest", "trnVerify", "testConnection")))
{
return array("error" => 201, "errorMessage" => "class:Method not exists");
}
$REQ = array();
foreach ($ARG as $k => $v) $REQ[] = $k . "=" . urlencode($v);
$url = $this->hostLive . $function;
$user_agent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
if ($ch = curl_init())
{
if (count($REQ))
{
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, join("&", $REQ));
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
if ($result = curl_exec($ch))
{
$INFO = curl_getinfo($ch);
$error = curl_error($ch);
curl_close($ch);
if ($INFO["http_code"] != 200)
{
return array("error" => $INFO["http_code"], "errorMessage" => "HTTP connection error (" . $INFO["http_code"] . ")");
}
else
{
$RES = array();
$X = explode("&", $result);
foreach ($X as $val)
{
$Y = explode("=", $val);
$RES[trim($Y[0])] = urldecode(trim($Y[1]));
}
return $RES;
}
}
else
{
$error = curl_error($ch);
curl_close($ch);
return array("error" => 203, "errorMessage" => $error);
}
}
else
{
return array("error" => 202, "errorMessage" => "call:Curl init error");
}
}
}

View File

@@ -0,0 +1,77 @@
<?php
function st_przelewy24_payment_methods_select_tag($name, $value, array $options = [])
{
$selectOptions = [];
$api = new stPrzelewy24();
$culture = sfContext::getInstance()->getUser()->getCulture();
try
{
$response = $api->getPaymentMethods($culture);
if (false !== $response)
{
foreach ($response as $paymentMethod)
{
if ($paymentMethod->status)
{
$selectOptions[$paymentMethod->id] = $paymentMethod->name;
}
}
}
asort($selectOptions, SORT_NATURAL);
}
catch (stPrzelewyException $e)
{
}
$options['multiple'] = true;
$options['selected'] = $value;
return select_tag($name, $selectOptions, $options);
}
function st_przelewy24_highlighted_payments_select_tag($name, $value, array $options = [])
{
$selectOptions = [];
$culture = sfContext::getInstance()->getUser()->getCulture();
$options['selected'] = $value;
$options['multiple'] = true;
try
{
$api = new stPrzelewy24();
$paymentMethods = $api->getPaymentMethods($culture);
if (!empty($paymentMethods))
{
foreach (stPrzelewy24::HIGHLIGHTED as $type => $fieldParams)
{
$id = $fieldParams['id'];
if (isset($paymentMethods[$id]) && $paymentMethods[$id]->status)
{
$selectOptions[$type] = $fieldParams['name'];
}
}
}
}
catch (stPrzelewyException $e)
{
}
return select_tag($name, $selectOptions, $options);
}
function object_st_przelewy24_highlighted_payments_select_tag($object, $method, $options = array(), $default_value = null)
{
$options = _parse_attributes($options);
$value = _get_object_value($object, $method, $default_value);
$name = _convert_method_to_name($method, $options);
return st_przelewy24_highlighted_payments_select_tag($name, $value, $options);
}

View File

@@ -0,0 +1,505 @@
<?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,
]);
}
}

View File

@@ -0,0 +1,6 @@
<?php
class stPrzelewyException extends Exception
{
}