diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..36ea091 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# Auto detect text files and perform LF normalization +* text=auto +* text eol=lf + +# Convert images to binary +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.tiff binary +*.ico binary \ No newline at end of file diff --git a/composer.json b/composer.json index 9e91e0b..fece440 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "paynl/php-sdk", "description": "Software Development Kit for implementing Pay.'s API version 3", - "version": "0.2.0", + "version": "0.2.1", "type": "library", "require": { "php": "^8.1", diff --git a/config/config.global.php b/config/config.global.php index cd9a18c..e6ff123 100644 --- a/config/config.global.php +++ b/config/config.global.php @@ -7,5 +7,6 @@ 'username' => '', # Use AT-Code or SL-Code. Use AT-code together with API-Token. 'password' => '', # Use API token or secret. Use Secret in combination with SL-Code. ], - 'debug' => false -]; \ No newline at end of file + 'debug' => false, + 'useFileCaching' => true +]; diff --git a/samples/OrderCreate.php b/samples/OrderCreate.php index d70ddf2..56cb440 100644 --- a/samples/OrderCreate.php +++ b/samples/OrderCreate.php @@ -106,7 +106,6 @@ try { $request->setReference('SDK0123456789'); $payOrder = $request->start(); - echo get_class($payOrder); } catch (PayException $e) { echo '
';
echo 'Technical message: ' . $e->getMessage() . PHP_EOL;
diff --git a/samples/ServiceGetConfig.php b/samples/ServiceGetConfig.php
index b24da48..cc17263 100644
--- a/samples/ServiceGetConfig.php
+++ b/samples/ServiceGetConfig.php
@@ -13,10 +13,9 @@
$config->setUsername($_REQUEST['username'] ?? '');
$config->setPassword($_REQUEST['password'] ?? '');
-
try {
$slCode = $_REQUEST['slcode'] ?? '';
- $config = (new ServiceGetConfigRequest($slCode))->setConfig($config)->start();
+ $serviceConfig = (new ServiceGetConfigRequest($slCode))->setConfig($config)->start();
} catch (PayException $e) {
echo '';
echo 'Technical message: ' . $e->getMessage() . PHP_EOL;
@@ -28,18 +27,18 @@
echo '';
-echo $config->getCode() . ' - ' . $config->getName() . PHP_EOL;
+echo $serviceConfig->getCode() . ' - ' . $serviceConfig->getName() . PHP_EOL;
-$banks = $config->getBanks();
+$banks = $serviceConfig->getBanks();
print_r($banks);
-$terminals = $config->getTerminals();
+$terminals = $serviceConfig->getTerminals();
print_r($terminals);
-$tguList = $config->getCores();
+$tguList = $serviceConfig->getCores();
print_r($tguList);
-$paymentMethods = $config->getPaymentMethods();
+$paymentMethods = $serviceConfig->getPaymentMethods();
foreach ($paymentMethods as $method) {
echo $method->getId() . ' - ';
echo $method->getName() . ' - ';
@@ -51,6 +50,6 @@
echo PHP_EOL;
}
-foreach ($config->getCheckoutOptions() as $checkoutOption) {
+foreach ($serviceConfig->getCheckoutOptions() as $checkoutOption) {
echo '=> TAG: ' . $checkoutOption->getTag() . PHP_EOL;
}
diff --git a/src/Config/Config.php b/src/Config/Config.php
index d9573e0..a987305 100644
--- a/src/Config/Config.php
+++ b/src/Config/Config.php
@@ -371,6 +371,14 @@ public function isEmpty()
return false;
}
+ /**
+ * @return boolean
+ */
+ public function isCacheEnabled()
+ {
+ return ($this->data['useFileCaching'] ?? 0) == 1;
+ }
+
/**
* @return string
*/
@@ -389,6 +397,16 @@ public function setPassword(string $password): self
return $this;
}
+ /**
+ * @param boolean $caching
+ * @return self
+ */
+ public function setCaching(bool $caching): self
+ {
+ $this->data['useFileCaching'] = $caching;
+ return $this;
+ }
+
/**
* @return string
*/
diff --git a/src/Helpers/StaticCacheTrait.php b/src/Helpers/StaticCacheTrait.php
new file mode 100644
index 0000000..19113f0
--- /dev/null
+++ b/src/Helpers/StaticCacheTrait.php
@@ -0,0 +1,63 @@
+ $this->orderId
+ 'transactionId' => $this->orderId
];
}
@@ -53,9 +57,25 @@ public function getBodyParameters(): array
*/
public function start(): PayOrder
{
- # Always use TGU-1 for orderStatus
- $this->config->setCore(Config::TGU1);
-
- return parent::start();
+ $cacheKey = 'order_status_' . md5(json_encode([$this->config->getUsername(), $this->orderId]));
+
+ if ($this->hasStaticCache($cacheKey)) {
+ return $this->getStaticCacheValue($cacheKey);
+ }
+
+ if ($this->config->isCacheEnabled()) {
+ $cache = new PayCache();
+ return $cache->get($cacheKey, function () use ($cacheKey) {
+ return $this->staticCache($cacheKey, function () {
+ $this->config->setCore(Config::TGU1);
+ return parent::start();
+ });
+ }, 3); # 3 seconds file caching
+ }
+
+ return $this->staticCache($cacheKey, function () {
+ $this->config->setCore(Config::TGU1);
+ return parent::start();
+ });
}
-}
\ No newline at end of file
+}
diff --git a/src/Model/Request/ServiceGetConfigRequest.php b/src/Model/Request/ServiceGetConfigRequest.php
index 767368e..cee0222 100644
--- a/src/Model/Request/ServiceGetConfigRequest.php
+++ b/src/Model/Request/ServiceGetConfigRequest.php
@@ -8,6 +8,8 @@
use PayNL\Sdk\Request\RequestData;
use PayNL\Sdk\Model\Response\ServiceGetConfigResponse;
use PayNL\Sdk\Request\RequestInterface;
+use PayNL\Sdk\Util\PayCache;
+use PayNL\Sdk\Helpers\StaticCacheTrait;
/**
* Class ServiceGetConfigRequest
@@ -18,12 +20,17 @@
*/
class ServiceGetConfigRequest extends RequestData
{
+ use StaticCacheTrait;
+
+ /**
+ * @var string|mixed
+ */
private string $serviceId;
/**
- * @param $serviceId
+ * @param string $serviceId
*/
- public function __construct($serviceId = '')
+ public function __construct(string $serviceId = '')
{
$this->serviceId = $serviceId;
parent::__construct('GetConfig', '/services/config', RequestInterface::METHOD_GET);
@@ -53,9 +60,35 @@ public function getBodyParameters(): array
* @throws PayException
*/
public function start(): ServiceGetConfigResponse
+ {
+ $cacheKey = 'service_getconfig_' . md5(json_encode([$this->config->getUsername(), $this->config->getPassword(), $this->serviceId]));
+
+ if ($this->hasStaticCache($cacheKey)) {
+ return $this->getStaticCacheValue($cacheKey);
+ }
+
+ if ($this->config->isCacheEnabled()) {
+ $cache = new PayCache();
+ return $cache->get($cacheKey, function () use ($cacheKey) {
+ return $this->staticCache($cacheKey, function () {
+ return $this->startAPI();
+ });
+ }, 5);
+ }
+
+ return $this->staticCache($cacheKey, function () {
+ return $this->startAPI();
+ });
+ }
+
+ /**
+ * @return ServiceGetConfigResponse
+ * @throws PayException
+ */
+ private function startAPI(): ServiceGetConfigResponse
{
$this->config->setCore('https://rest.pay.nl');
$this->config->setVersion(2);
return parent::start();
}
-}
\ No newline at end of file
+}
diff --git a/src/Model/Request/TransactionStatusRequest.php b/src/Model/Request/TransactionStatusRequest.php
index b328084..bf6629f 100644
--- a/src/Model/Request/TransactionStatusRequest.php
+++ b/src/Model/Request/TransactionStatusRequest.php
@@ -4,10 +4,13 @@
namespace PayNL\Sdk\Model\Request;
+use PayNL\Sdk\Config\Config;
use PayNL\Sdk\Exception\PayException;
use PayNL\Sdk\Request\RequestData;
use PayNL\Sdk\Model\Pay\PayOrder;
use PayNL\Sdk\Request\RequestInterface;
+use PayNL\Sdk\Helpers\StaticCacheTrait;
+use PayNL\Sdk\Util\PayCache;
/**
* Class TransactionStatusRequest
@@ -17,12 +20,14 @@
*/
class TransactionStatusRequest extends RequestData
{
+ use StaticCacheTrait;
+
private string $orderId;
/**
- * @param $orderid
+ * @param string $orderId
*/
- public function __construct($orderId)
+ public function __construct(string $orderId)
{
$this->orderId = $orderId;
parent::__construct('TransactionStatus', '/transactions/%transactionId%/status', RequestInterface::METHOD_GET);
@@ -48,12 +53,29 @@ public function getBodyParameters(): array
/**
* @return PayOrder
- * @throws PayException
+ * @throws \Exception
*/
public function start(): PayOrder
{
- # Always use rest.pay.nl for this status request
- $this->config->setCore('https://rest.pay.nl');
- return parent::start();
+ $cacheKey = 'transaction_status_' . md5(json_encode([$this->config->getUsername(), $this->orderId]));
+
+ if ($this->hasStaticCache($cacheKey)) {
+ return $this->getStaticCacheValue($cacheKey);
+ }
+
+ if ($this->config->isCacheEnabled()) {
+ $cache = new PayCache();
+ return $cache->get($cacheKey, function () use ($cacheKey) {
+ return $this->staticCache($cacheKey, function () {
+ $this->config->setCore('https://rest.pay.nl');
+ return parent::start();
+ });
+ }, 3); # 3 seconds file caching
+ }
+
+ return $this->staticCache($cacheKey, function () {
+ $this->config->setCore('https://rest.pay.nl');
+ return parent::start();
+ });
}
-}
\ No newline at end of file
+}
diff --git a/src/Model/Response/ServiceGetConfigResponse.php b/src/Model/Response/ServiceGetConfigResponse.php
index 4d8d2c4..be9712a 100644
--- a/src/Model/Response/ServiceGetConfigResponse.php
+++ b/src/Model/Response/ServiceGetConfigResponse.php
@@ -335,11 +335,30 @@ public function setTguList(array $tguList): void
}
/**
+ * Provides a core-list prepared with web protocol.
* @return array
*/
public function getCores(): array
{
- return $this->getTguList();
+ $cores = $this->getTguList();
+
+ $payDomain = false;
+ foreach ($cores as &$core) {
+ $domain = $core['domain'];
+
+ if (in_array($domain, ['pay.nl', 'connect.pay.nl'])) {
+ $payDomain = true;
+ }
+
+ $core['domain'] = 'https://' . $domain;
+ $core['label'] = $domain;
+ }
+
+ if ($payDomain !== true) {
+ array_unshift($cores, ['domain' => 'https://connect.pay.nl', 'label' => 'connect.pay.nl']);
+ }
+
+ return $cores;
}
/**
diff --git a/src/Request/RequestData.php b/src/Request/RequestData.php
index f357fad..fa702d1 100644
--- a/src/Request/RequestData.php
+++ b/src/Request/RequestData.php
@@ -43,7 +43,8 @@ public function __construct(string $mapperName, string $uri, string $requestMeth
*/
public function setConfig(Config $config): self
{
- $this->config = $config;
+ $this->config = (new Config(require __DIR__ . '/../../config/config.global.php'));
+ $this->config->merge($config);
return $this;
}
@@ -56,16 +57,17 @@ public function setApplication(Application $application): void
$this->application = $application;
}
+
/**
- * @return mixed
+ * @return Config|null
* @throws PayException
- * @throws Exception
*/
- public function start()
+ private function getConfig(): Config
{
- $config = (new Config(require __DIR__ . '/../../config/config.global.php'));
- if (!empty($this->config)) {
- $config->merge($this->config);
+ if (empty($this->config)) {
+ $config = (new Config(require __DIR__ . '/../../config/config.global.php'));
+ } else {
+ $config = $this->config;
}
if (!empty($config->getFailoverUrl())) {
@@ -76,6 +78,17 @@ public function start()
throw new PayException('Please check your config', 0, 0);
}
+ return $config;
+ }
+
+ /**
+ * @return mixed
+ * @throws PayException
+ */
+ public function start()
+ {
+ $config = $this->getConfig();
+
try {
if (empty($this->application)) {
$this->application = Application::init($config);
diff --git a/src/Util/Exchange.php b/src/Util/Exchange.php
index 06e54a1..7924edb 100644
--- a/src/Util/Exchange.php
+++ b/src/Util/Exchange.php
@@ -76,7 +76,7 @@ public function eventCapture()
*
* @param boolean $result
* @param string $message
- * @param boolean $returnOutput If true, then this method returs the output string
+ * @param boolean $returnOutput
* @return false|string|void
*/
public function setResponse(bool $result, string $message, bool $returnOutput = false)
diff --git a/src/Util/PayCache.php b/src/Util/PayCache.php
new file mode 100644
index 0000000..d557db8
--- /dev/null
+++ b/src/Util/PayCache.php
@@ -0,0 +1,137 @@
+cacheDir = $cacheDir ?? sys_get_temp_dir() . '/cache_pay_phpsdk';
+ $this->defaultTtl = $defaultTtl;
+
+ if (!is_dir($this->cacheDir)) {
+ if (!@mkdir($this->cacheDir, 0777, true) && !is_dir($this->cacheDir)) {
+ $this->enabled = false;
+ return;
+ }
+ }
+
+ if (!is_writable($this->cacheDir)) {
+ $this->enabled = false;
+ }
+ }
+
+ /**
+ * @param string $key
+ * @param callable|null $callback
+ * @param integer|null $ttl
+ * @return mixed|null
+ */
+ public function get(string $key, callable $callback = null, int $ttl = null): mixed
+ {
+ if (!$this->enabled) {
+ return $callback ? $callback() : null;
+ }
+
+ $file = $this->getCacheFile($key);
+
+ if (file_exists($file)) {
+ $data = @unserialize(file_get_contents($file));
+
+ if ($data !== false && isset($data['expires'], $data['value'])) {
+ if ($data['expires'] >= time()) {
+ return $data['value'];
+ }
+ }
+
+ # Cache expired or invalid
+ @unlink($file);
+ }
+
+ if ($callback !== null) {
+ $value = $callback();
+ $this->set($key, $value, $ttl);
+ return $value;
+ }
+
+ return null;
+ }
+
+ /**
+ * @param string $key
+ * @param mixed $value
+ * @param integer|null $ttl
+ * @return void
+ */
+ public function set(string $key, mixed $value, int $ttl = null): void
+ {
+ if (!$this->enabled) {
+ return;
+ }
+
+ $ttl = $ttl ?? $this->defaultTtl;
+ $file = $this->getCacheFile($key);
+
+ $data = [
+ 'expires' => time() + $ttl,
+ 'value' => $value
+ ];
+
+ @file_put_contents($file, serialize($data), LOCK_EX);
+ }
+
+ /**
+ * @param string $key
+ * @return void
+ */
+ public function delete(string $key): void
+ {
+ if (!$this->enabled) {
+ return;
+ }
+
+ $file = $this->getCacheFile($key);
+ if (file_exists($file)) {
+ @unlink($file);
+ }
+ }
+
+ /**
+ * @return void
+ */
+ public function clear(): void
+ {
+ if (!$this->enabled) {
+ return;
+ }
+
+ foreach (glob($this->cacheDir . '/*') ?: [] as $file) {
+ @unlink($file);
+ }
+ }
+
+ /**
+ * @param string $key
+ * @return string
+ */
+ private function getCacheFile(string $key): string
+ {
+ return $this->cacheDir . '/' . md5($key) . '.cache';
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isEnabled(): bool
+ {
+ return $this->enabled;
+ }
+}
diff --git a/src/Util/Text.php b/src/Util/Text.php
index acba9a6..ad15163 100644
--- a/src/Util/Text.php
+++ b/src/Util/Text.php
@@ -20,6 +20,7 @@ class Text
public static function getFriendlyMessage(string $errorMessage)
{
$friendlyMessages = [
+ 'requested payment method is not enabled' => 'This payment method is not available',
'INVALID_TRANSACTION_STAT' => 'Transaction not ready for refund.',
'username can not be empty' => 'Connection error. Please check your connection credentials.',
'bestelling kon niet worden gevonden' => 'Your order could not be found',