Skip to content

Commit 8b4b7cb

Browse files
authored
Merge pull request #60 from SzymonKostrubiec/op-283
OP-283 Add PayU error handling, updatede and run ECS
2 parents 7e55eea + b0947a1 commit 8b4b7cb

20 files changed

+345
-60
lines changed

composer.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"friends-of-behat/variadic-extension": "^1.3",
3636
"phpspec/phpspec": "^7.0",
3737
"phpunit/phpunit": "^9.5",
38-
"sylius-labs/coding-standard": "~4.1.0",
38+
"sylius-labs/coding-standard": "^4.1",
3939
"symfony/browser-kit": "^6.0 || ^5.4",
4040
"symfony/debug-bundle": "^6.0 || ^5.4",
4141
"symfony/dotenv": "^6.0 || ^5.4",
@@ -44,7 +44,7 @@
4444
"vimeo/psalm": "4.16.1",
4545
"symfony/dependency-injection": "<4.4.19 || ^5.2",
4646
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
47-
"bitbag/coding-standard": "^2.0"
47+
"bitbag/coding-standard": "^3.0"
4848
},
4949
"conflict": {
5050
"symfony/symfony": "4.1.8",

ecs.php

+12-8
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@
88

99
declare(strict_types=1);
1010

11-
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
12-
use Symplify\EasyCodingStandard\ValueObject\Option;
11+
use PhpCsFixer\Fixer\ClassNotation\VisibilityRequiredFixer;
12+
use Symplify\EasyCodingStandard\Config\ECSConfig;
1313

14-
return static function (ContainerConfigurator $containerConfigurator): void {
15-
$containerConfigurator->import('vendor/bitbag/coding-standard/ecs.php');
16-
17-
$parameters = $containerConfigurator->parameters();
18-
$parameters->set(Option::PATHS, [
14+
return static function (ECSConfig $ecsConfig): void {
15+
$ecsConfig->paths([
1916
__DIR__ . '/src',
20-
__DIR__ . '/tests',
17+
__DIR__ . '/tests/Behat',
18+
__DIR__ . '/ecs.php',
19+
]);
20+
21+
$ecsConfig->import('vendor/sylius-labs/coding-standard/ecs.php');
22+
23+
$ecsConfig->skip([
24+
VisibilityRequiredFixer::class => ['*Spec.php'],
2125
]);
2226
};

src/Action/CaptureAction.php

+13-9
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ final class CaptureAction implements ActionInterface, ApiAwareInterface, Generic
4747

4848
public function __construct(
4949
OpenPayUBridgeInterface $openPayUBridge,
50-
PaymentDescriptionProviderInterface $paymentDescriptionProvider
50+
PaymentDescriptionProviderInterface $paymentDescriptionProvider,
5151
) {
5252
$this->openPayUBridge = $openPayUBridge;
5353
$this->paymentDescriptionProvider = $paymentDescriptionProvider;
@@ -67,7 +67,7 @@ public function setApi($api): void
6767
$api['signature_key'],
6868
$api['pos_id'],
6969
$api['oauth_client_id'],
70-
$api['oauth_client_secret']
70+
$api['oauth_client_secret'],
7171
);
7272
}
7373

@@ -77,7 +77,7 @@ public function execute($request): void
7777
$model = $request->getModel();
7878
/** @var PaymentInterface $payment */
7979
$payment = $request->getFirstModel();
80-
/** @var OrderInterface $orderData */
80+
/** @var OrderInterface $order */
8181
$order = $payment->getOrder();
8282

8383
/** @var TokenInterface $token */
@@ -122,12 +122,15 @@ public function setGenericTokenFactory(GenericTokenFactoryInterface $genericToke
122122
public function supports($request): bool
123123
{
124124
return
125-
$request instanceof Capture
126-
&& $request->getModel() instanceof ArrayObject;
125+
$request instanceof Capture &&
126+
$request->getModel() instanceof ArrayObject;
127127
}
128128

129-
private function prepareOrder(TokenInterface $token, OrderInterface $order, PaymentInterface $payment): array
130-
{
129+
private function prepareOrder(
130+
TokenInterface $token,
131+
OrderInterface $order,
132+
PaymentInterface $payment,
133+
): array {
131134
$notifyToken = $this->tokenFactory->createNotifyToken($token->getGatewayName(), $token->getDetails());
132135
$payUdata = [];
133136

@@ -138,6 +141,7 @@ private function prepareOrder(TokenInterface $token, OrderInterface $order, Paym
138141
$payUdata['description'] = $this->paymentDescriptionProvider->getPaymentDescription($payment);
139142
$payUdata['currencyCode'] = $order->getCurrencyCode();
140143
$payUdata['totalAmount'] = $order->getTotal();
144+
$payUdata['tokenValue'] = $order->getTokenValue();
141145
/** @var CustomerInterface $customer */
142146
$customer = $order->getCustomer();
143147

@@ -146,8 +150,8 @@ private function prepareOrder(TokenInterface $token, OrderInterface $order, Paym
146150
CustomerInterface::class,
147151
sprintf(
148152
'Make sure the first model is the %s instance.',
149-
CustomerInterface::class
150-
)
153+
CustomerInterface::class,
154+
),
151155
);
152156

153157
$buyer = [

src/Action/ConvertPaymentAction.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ final class ConvertPaymentAction implements ActionInterface, GatewayAwareInterfa
2424
use GatewayAwareTrait;
2525

2626
/**
27-
* {@inheritdoc}
27+
* @inheritdoc
2828
*
2929
* @param Convert $request
3030
*/
@@ -49,13 +49,13 @@ public function execute($request): void
4949
}
5050

5151
/**
52-
* {@inheritdoc}
52+
* @inheritdoc
5353
*/
5454
public function supports($request): bool
5555
{
56-
return $request instanceof Convert
57-
&& $request->getSource() instanceof PaymentInterface
58-
&& 'array' === $request->getTo();
56+
return $request instanceof Convert &&
57+
$request->getSource() instanceof PaymentInterface &&
58+
'array' === $request->getTo();
5959
}
6060

6161
private function getClientIp(): ?string

src/Action/NotifyAction.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ final class NotifyAction implements ActionInterface, ApiAwareInterface
3131
/** @var OpenPayUBridgeInterface */
3232
private $openPayUBridge;
3333

34-
/** @param OpenPayUBridgeInterface $openPayUBridge */
3534
public function __construct(OpenPayUBridgeInterface $openPayUBridge)
3635
{
3736
$this->openPayUBridge = $openPayUBridge;
@@ -51,16 +50,15 @@ public function setApi($api): void
5150
$api['signature_key'],
5251
$api['pos_id'],
5352
$api['oauth_client_id'],
54-
$api['oauth_client_secret']
53+
$api['oauth_client_secret'],
5554
);
5655
}
5756

5857
/**
59-
* {@inheritdoc}
58+
* @inheritdoc
6059
*/
6160
public function execute($request): void
6261
{
63-
/** @var $request Notify */
6462
RequestNotSupportedException::assertSupports($this, $request);
6563
/** @var PaymentInterface $payment */
6664
$payment = $request->getFirstModel();
@@ -99,7 +97,7 @@ public function execute($request): void
9997
}
10098

10199
/**
102-
* {@inheritdoc}
100+
* @inheritdoc
103101
*/
104102
public function supports($request): bool
105103
{

src/Action/StatusAction.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ final class StatusAction implements ActionInterface
2323
/** @var OpenPayUBridgeInterface */
2424
private $openPayUBridge;
2525

26-
/** @param OpenPayUBridgeInterface $openPayUBridge */
2726
public function __construct(OpenPayUBridgeInterface $openPayUBridge)
2827
{
2928
$this->openPayUBridge = $openPayUBridge;
@@ -43,16 +42,15 @@ public function setApi($api): void
4342
$api['signature_key'],
4443
$api['pos_id'],
4544
$api['oauth_client_id'],
46-
$api['oauth_client_secret']
45+
$api['oauth_client_secret'],
4746
);
4847
}
4948

5049
/**
51-
* {@inheritdoc}
50+
* @inheritdoc
5251
*/
5352
public function execute($request): void
5453
{
55-
/** @var $request GetStatusInterface */
5654
RequestNotSupportedException::assertSupports($this, $request);
5755

5856
$model = ArrayObject::ensureArrayObject($request->getModel());

src/Bridge/OpenPayUBridge.php

+9-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace BitBag\SyliusPayUPlugin\Bridge;
1212

13+
use BitBag\SyliusPayUPlugin\Exception\PayUResponseException;
1314
use OauthCacheFile;
1415
use OpenPayU_Configuration;
1516
use OpenPayU_Order;
@@ -30,7 +31,7 @@ public function setAuthorizationData(
3031
string $signatureKey,
3132
string $posId,
3233
string $clientId,
33-
string $clientSecret
34+
string $clientSecret,
3435
): void {
3536
OpenPayU_Configuration::setEnvironment($environment);
3637

@@ -47,10 +48,14 @@ public function setAuthorizationData(
4748

4849
public function create(array $order): ?OpenPayU_Result
4950
{
50-
/** @var OpenPayU_Result|null $result */
51-
$result = OpenPayU_Order::create($order);
51+
try {
52+
/** @var OpenPayU_Result|null $result */
53+
$result = OpenPayU_Order::create($order);
5254

53-
return $result;
55+
return $result;
56+
} catch (\OpenPayU_Exception $exception) {
57+
throw new PayUResponseException($exception->getOriginalResponse()->getStatus(), $exception->getCode(), $order);
58+
}
5459
}
5560

5661
public function retrieve(string $orderId): OpenPayU_Result

src/Bridge/OpenPayUBridgeInterface.php

+11-1
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,35 @@
1515
interface OpenPayUBridgeInterface
1616
{
1717
public const SANDBOX_ENVIRONMENT = 'sandbox';
18+
1819
public const SECURE_ENVIRONMENT = 'secure';
1920

2021
public const NEW_API_STATUS = 'NEW';
22+
2123
public const PENDING_API_STATUS = 'PENDING';
24+
2225
public const COMPLETED_API_STATUS = 'COMPLETED';
26+
2327
public const SUCCESS_API_STATUS = 'SUCCESS';
28+
2429
public const CANCELED_API_STATUS = 'CANCELED';
30+
2531
public const COMPLETED_PAYMENT_STATUS = 'COMPLETED';
32+
2633
public const PENDING_PAYMENT_STATUS = 'PENDING';
34+
2735
public const CANCELED_PAYMENT_STATUS = 'CANCELED';
36+
2837
public const WAITING_FOR_CONFIRMATION_PAYMENT_STATUS = 'WAITING_FOR_CONFIRMATION';
38+
2939
public const REJECTED_STATUS = 'REJECTED';
3040

3141
public function setAuthorizationData(
3242
string $environment,
3343
string $signatureKey,
3444
string $posId,
3545
string $clientId,
36-
string $clientSecret
46+
string $clientSecret,
3747
): void;
3848

3949
public function create(array $order): ?OpenPayU_Result;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/*
4+
* This file was created by developers working at BitBag
5+
* Do you need more information about us and what we do? Visit our https://bitbag.io website!
6+
* We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace BitBag\SyliusPayUPlugin\EventListener;
12+
13+
use BitBag\SyliusPayUPlugin\Exception\PayUResponseException;
14+
use Psr\Log\LoggerInterface;
15+
use Symfony\Component\HttpFoundation\RedirectResponse;
16+
use Symfony\Component\HttpFoundation\RequestStack;
17+
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
18+
use Symfony\Component\Routing\RouterInterface;
19+
20+
final class PayUResponseExceptionEventListener
21+
{
22+
private RouterInterface $router;
23+
24+
private RequestStack $requestStack;
25+
26+
private LoggerInterface $logger;
27+
28+
public function __construct(
29+
RouterInterface $router,
30+
RequestStack $requestStack,
31+
LoggerInterface $logger,
32+
) {
33+
$this->router = $router;
34+
$this->requestStack = $requestStack;
35+
$this->logger = $logger;
36+
}
37+
38+
public function onPayuOpenException(ExceptionEvent $event)
39+
{
40+
$exception = $event->getThrowable();
41+
42+
if ($exception instanceof PayUResponseException) {
43+
$message = PayUResponseException::getTranslationByMessage($exception->getMessage());
44+
$order = $exception->getOrder();
45+
46+
$this->logError($exception);
47+
$this->requestStack->getSession()->getBag('flashes')->add('error', $message);
48+
49+
$route = empty($order['tokenValue'])
50+
? $this->router->generate('sylius_shop_cart_summary')
51+
: $this->router->generate('sylius_shop_order_show', ['tokenValue' => $order['tokenValue']]);
52+
53+
$response = new RedirectResponse($route);
54+
$event->setResponse($response);
55+
}
56+
}
57+
58+
public function logError(\Exception $exception): void
59+
{
60+
$message = sprintf(
61+
'%s %s',
62+
'[PayU] Error while placing order',
63+
$exception->getMessage(),
64+
);
65+
66+
$this->logger->error($message);
67+
}
68+
}
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
* This file was created by developers working at BitBag
5+
* Do you need more information about us and what we do? Visit our https://bitbag.io website!
6+
* We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace BitBag\SyliusPayUPlugin\Exception;
12+
13+
use Exception;
14+
use Payum\Core\Exception\Http\HttpException;
15+
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
16+
17+
final class PayUResponseException extends Exception
18+
{
19+
private array $order;
20+
21+
public function __construct(
22+
string $message,
23+
int $code,
24+
?array $order = [],
25+
?Exception $previous = null,
26+
) {
27+
$this->order = $order;
28+
parent::__construct($message, $code, $previous);
29+
}
30+
31+
public function getOrder(): array
32+
{
33+
return $this->order;
34+
}
35+
36+
public static function getTranslationByMessage(?string $message): string
37+
{
38+
switch ($message) {
39+
case 'ERROR_INCONSISTENT_CURRENCIES':
40+
return 'bitbag.payu_plugin.payu_exception.currencies';
41+
default:
42+
return 'bitbag.payu_plugin.payu_exception.default';
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)