Skip to content

Commit 7e94c80

Browse files
committed
[PayumPayzen] Changed API configuration. Improved response checks. Added logs.
1 parent 855b0e7 commit 7e94c80

7 files changed

+161
-55
lines changed

Action/Api/AbstractApiAction.php

+54-1
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
use Payum\Core\Exception\UnsupportedApiException;
99
use Payum\Core\GatewayAwareInterface;
1010
use Payum\Core\GatewayAwareTrait;
11+
use Psr\Log\LoggerAwareInterface;
12+
use Psr\Log\LoggerInterface;
1113

1214
/**
1315
* Class AbstractApiAction
1416
* @package Ekyna\Component\Payum\Payzen\Action\Api
1517
* @author Etienne Dauvergne <contact@ekyna.com>
1618
*/
17-
abstract class AbstractApiAction implements ActionInterface, GatewayAwareInterface, ApiAwareInterface
19+
abstract class AbstractApiAction implements ActionInterface, GatewayAwareInterface, ApiAwareInterface, LoggerAwareInterface
1820
{
1921
use GatewayAwareTrait;
2022

@@ -23,6 +25,11 @@ abstract class AbstractApiAction implements ActionInterface, GatewayAwareInterfa
2325
*/
2426
protected $api;
2527

28+
/**
29+
* @var LoggerInterface
30+
*/
31+
private $logger;
32+
2633

2734
/**
2835
* @inheritDoc
@@ -35,4 +42,50 @@ public function setApi($api)
3542

3643
$this->api = $api;
3744
}
45+
46+
/**
47+
* {@inheritDoc}
48+
*/
49+
public function setLogger(LoggerInterface $logger)
50+
{
51+
$this->logger = $logger;
52+
}
53+
54+
/**
55+
* Logs the given message.
56+
*
57+
* @param string $message
58+
*/
59+
protected function log($message)
60+
{
61+
if (!$this->logger) {
62+
return;
63+
}
64+
65+
$this->logger->debug($message);
66+
}
67+
68+
/**
69+
* Logs the given message and data.
70+
*
71+
* @param string $message
72+
* @param array $data
73+
* @param array $filterKeys
74+
*/
75+
protected function logData($message, array $data, array $filterKeys = [])
76+
{
77+
if (!$this->logger) {
78+
return;
79+
}
80+
81+
if (!empty($filterKeys)) {
82+
$data = array_intersect_key($data, array_flip($filterKeys));
83+
}
84+
85+
$data = array_map(function($key, $value) {
86+
return "$key: $value";
87+
}, array_keys($data), $data);
88+
89+
$this->logger->debug($message . ': ' . implode(', ', $data));
90+
}
3891
}

Action/Api/ApiRequestAction.php

+25-1
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,35 @@ public function execute($request)
3333
$model['vads_trans_id'] = $this->api->getTransactionId();
3434
$model['vads_trans_date'] = date('YmdHis');
3535

36-
$url = $this->api->createRequestUrl($model->getArrayCopy());
36+
$data = $model->getArrayCopy();
37+
38+
$this->logRequestData($data);
39+
40+
$url = $this->api->createRequestUrl($data);
3741

3842
throw new HttpRedirect($url);
3943
}
4044

45+
/**
46+
* Logs the request data.
47+
*
48+
* @param array $data
49+
*/
50+
private function logRequestData(array $data)
51+
{
52+
$this->logData("[Payzen] Request", $data, [
53+
'vads_order_id',
54+
'vads_amount',
55+
'vads_ctx_mode',
56+
'vads_currency',
57+
'vads_payment_config',
58+
'vads_site_id',
59+
'vads_trans_date',
60+
'vads_trans_id',
61+
'vads_version',
62+
]);
63+
}
64+
4165
/**
4266
* @inheritdoc
4367
*/

Action/Api/ApiResponseAction.php

+24-1
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,42 @@ public function execute($request)
3333
return;
3434
}
3535

36+
$this->logResponseData($data);
37+
3638
// Check amount
3739
if ($model['vads_amount'] != $data['vads_amount']) {
3840
return;
3941
}
4042

4143
// Check the response signature
42-
if ($this->api->checkResponseSignature($data)) {
44+
if ($this->api->checkResponseIntegrity($data)) {
4345
// Update the payment details
4446
$model->replace($data);
4547
$request->setModel($model);
4648
}
4749
}
4850

51+
/**
52+
* Logs the response data.
53+
*
54+
* @param array $data
55+
*/
56+
private function logResponseData(array $data)
57+
{
58+
$this->logData("[Payzen] Response", $data, [
59+
'vads_order_id',
60+
'vads_trans_id',
61+
'vads_amount',
62+
'vads_auth_result',
63+
'vads_auth_mode',
64+
'vads_auth_number',
65+
'vads_validation_mode',
66+
'vads_result',
67+
'vads_extra_result',
68+
'vads_warranty_result',
69+
]);
70+
}
71+
4972
/**
5073
* @inheritdec
5174
*/

Action/ConvertPaymentAction.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ public function execute($request)
4242
}
4343
$divisor = pow(10, 2 - $currency->exp);
4444

45-
$model['vads_currency'] = $currency->numeric;
46-
$model['vads_amount'] = abs($payment->getTotalAmount() / $divisor);
45+
$model['vads_currency'] = (string)$currency->numeric;
46+
$model['vads_amount'] = (string)abs($payment->getTotalAmount() / $divisor);
4747
}
4848

4949
if (false == $model['vads_order_id']) {

Action/StatusAction.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function execute($request)
3131
return;
3232
}
3333

34-
if (false != $code = $model['vads_auth_result']) {
34+
if (false != $code = $model['vads_result']) {
3535
switch ($code) {
3636
case "00" : // transaction approuvée ou traitée avec succès
3737
$request->markCaptured();
@@ -88,7 +88,7 @@ public function execute($request)
8888
return;
8989
}
9090

91-
$request->markPending();
91+
$request->markNew();
9292
}
9393

9494
/**

Api/Api.php

+52-47
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
use Payum\Core\Exception\LogicException;
66
use Payum\Core\Exception\RuntimeException;
7-
use Psr\Log\LoggerInterface;
8-
use Psr\Log\NullLogger;
97
use Symfony\Component\OptionsResolver\Options;
108
use Symfony\Component\OptionsResolver\OptionsResolver;
119

@@ -31,21 +29,6 @@ class Api
3129
*/
3230
private $config;
3331

34-
/**
35-
* @var LoggerInterface
36-
*/
37-
private $logger;
38-
39-
40-
/**
41-
* Constructor
42-
*
43-
* @param LoggerInterface $logger
44-
*/
45-
public function __construct(LoggerInterface $logger = null)
46-
{
47-
$this->logger = $logger ?: new NullLogger();
48-
}
4932

5033
/**
5134
* Configures the api.
@@ -66,25 +49,19 @@ public function setConfig(array $config)
6649
*/
6750
public function getTransactionId()
6851
{
69-
$path = $this->config['trans_id_file_path'];
70-
71-
// Create directory if not exists
72-
if (!is_dir(dirname($path))) {
73-
mkdir(dirname($path), 0777, true);
74-
}
52+
$path = $this->getDirectoryPath() . 'transaction_id';
7553

7654
// Create file if not exists
7755
if (!file_exists($path)) {
7856
touch($path);
7957
}
8058

81-
$id = 1;
8259
$date = (new \DateTime())->format('Ymd');
8360
$fileDate = date('Ymd', filemtime($path));
8461
$isDailyFirstAccess = ($date != $fileDate);
8562

8663
// Open file
87-
$handle = fopen($this->config['trans_id_file_path'], 'r+');
64+
$handle = fopen($path, 'r+');
8865
if (false === $handle) {
8966
throw new RuntimeException('Failed to open the transaction ID file.');
9067
}
@@ -93,6 +70,7 @@ public function getTransactionId()
9370
throw new RuntimeException('Failed to lock the transaction ID file.');
9471
}
9572

73+
$id = 1;
9674
// If not daily first access, read and increment the id
9775
if (!$isDailyFirstAccess) {
9876
$id = (int)fread($handle, 6);
@@ -107,10 +85,13 @@ public function getTransactionId()
10785
flock($handle, LOCK_UN);
10886
fclose($handle);
10987

88+
if ($this->config['debug']) {
89+
$id += 89000;
90+
}
91+
11092
return str_pad($id, 6, '0', STR_PAD_LEFT);
11193
}
11294

113-
11495
/**
11596
* Creates the request url.
11697
*
@@ -144,13 +125,39 @@ public function parseResponseData(array $data)
144125
return $data;
145126
}
146127

147-
public function checkResponseSignature(array $data)
128+
/**
129+
* Checks the response signature.
130+
*
131+
* @param array $data
132+
*
133+
* @return bool
134+
*/
135+
public function checkResponseIntegrity(array $data)
148136
{
149137
if (!isset($data['signature'])) {
150138
return false;
151139
}
152140

153-
return $data['signature'] === $this->generateSignature($data);
141+
return $data['vads_site_id'] === (string)$this->config['site_id']
142+
&& $data['vads_ctx_mode'] === (string)$this->config['ctx_mode']
143+
&& $data['signature'] === $this->generateSignature($data);
144+
}
145+
146+
/**
147+
* Returns the directory path and creates it if not exists.
148+
*
149+
* @return string
150+
*/
151+
private function getDirectoryPath()
152+
{
153+
$path = $this->config['directory'];
154+
155+
// Create directory if not exists
156+
if (!is_dir(dirname($path))) {
157+
mkdir(dirname($path), 0700, true);
158+
}
159+
160+
return $path . DIRECTORY_SEPARATOR;
154161
}
155162

156163
/**
@@ -176,22 +183,18 @@ private function createRequestData(array $data)
176183
{
177184
$data = $this
178185
->getRequestOptionsResolver()
179-
->resolve(array_replace(
180-
[
181-
'vads_site_id' => $this->config['site_id'],
182-
'vads_ctx_mode' => $this->config['ctx_mode'],
183-
],
184-
$data,
185-
[
186-
'vads_page_action' => 'PAYMENT',
187-
'vads_version' => 'V2',
188-
]
189-
));
186+
->resolve(array_replace($data, [
187+
'vads_page_action' => 'PAYMENT',
188+
'vads_version' => 'V2',
189+
]));
190190

191191
$data = array_filter($data, function ($value) {
192192
return null !== $value;
193193
});
194194

195+
$data['vads_site_id'] = $this->config['site_id'];
196+
$data['vads_ctx_mode'] = $this->config['ctx_mode'];
197+
195198
$data['signature'] = $this->generateSignature($data);
196199

197200
return $data;
@@ -249,12 +252,17 @@ private function getConfigResolver()
249252
'site_id',
250253
'certificate',
251254
'ctx_mode',
252-
'trans_id_file_path',
255+
'directory',
256+
'debug',
253257
])
254-
->setAllowedTypes('site_id', ['string', 'int'])
255-
->setAllowedTypes('certificate', ['string', 'int'])
256-
->setAllowedTypes('trans_id_file_path', 'string')
257-
->setAllowedValues('ctx_mode', ['TEST', 'PRODUCTION']);
258+
->setAllowedTypes('site_id', 'string')
259+
->setAllowedTypes('certificate', 'string')
260+
->setAllowedValues('ctx_mode', ['TEST', 'PRODUCTION'])
261+
->setAllowedTypes('directory', 'string')
262+
->setAllowedTypes('debug', 'bool')
263+
->setNormalizer('directory', function (Options $options, $value) {
264+
return rtrim($value, DIRECTORY_SEPARATOR);
265+
});
258266

259267
return $this->configResolver = $resolver;
260268
}
@@ -362,16 +370,13 @@ private function getRequestOptionsResolver()
362370
])
363371
->setRequired([
364372
'vads_amount',
365-
'vads_ctx_mode',
366373
'vads_currency',
367374
'vads_payment_config',
368-
'vads_site_id',
369375
'vads_trans_date',
370376
'vads_trans_id',
371377
'vads_version',
372378
])
373379
->setAllowedValues('vads_action_mode', ['SILENT', 'INTERACTIVE'])
374-
->setAllowedValues('vads_ctx_mode', ['TEST', 'PRODUCTION'])
375380
->setAllowedValues('vads_currency', $this->getCurrencyCodes())
376381
->setAllowedValues('vads_language', $this->getLanguageCodes())
377382
->setAllowedValues('vads_page_action', 'PAYMENT')

0 commit comments

Comments
 (0)