Skip to content

Commit

Permalink
Merge pull request #60 from SzymonKostrubiec/op-283
Browse files Browse the repository at this point in the history
OP-283 Add PayU error handling, updatede and run ECS
  • Loading branch information
senghe authored Jun 10, 2024
2 parents 7e55eea + b0947a1 commit 8b4b7cb
Show file tree
Hide file tree
Showing 20 changed files with 345 additions and 60 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"friends-of-behat/variadic-extension": "^1.3",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^9.5",
"sylius-labs/coding-standard": "~4.1.0",
"sylius-labs/coding-standard": "^4.1",
"symfony/browser-kit": "^6.0 || ^5.4",
"symfony/debug-bundle": "^6.0 || ^5.4",
"symfony/dotenv": "^6.0 || ^5.4",
Expand All @@ -44,7 +44,7 @@
"vimeo/psalm": "4.16.1",
"symfony/dependency-injection": "<4.4.19 || ^5.2",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"bitbag/coding-standard": "^2.0"
"bitbag/coding-standard": "^3.0"
},
"conflict": {
"symfony/symfony": "4.1.8",
Expand Down
20 changes: 12 additions & 8 deletions ecs.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@

declare(strict_types=1);

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\EasyCodingStandard\ValueObject\Option;
use PhpCsFixer\Fixer\ClassNotation\VisibilityRequiredFixer;
use Symplify\EasyCodingStandard\Config\ECSConfig;

return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->import('vendor/bitbag/coding-standard/ecs.php');

$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [
return static function (ECSConfig $ecsConfig): void {
$ecsConfig->paths([
__DIR__ . '/src',
__DIR__ . '/tests',
__DIR__ . '/tests/Behat',
__DIR__ . '/ecs.php',
]);

$ecsConfig->import('vendor/sylius-labs/coding-standard/ecs.php');

$ecsConfig->skip([
VisibilityRequiredFixer::class => ['*Spec.php'],
]);
};
22 changes: 13 additions & 9 deletions src/Action/CaptureAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ final class CaptureAction implements ActionInterface, ApiAwareInterface, Generic

public function __construct(
OpenPayUBridgeInterface $openPayUBridge,
PaymentDescriptionProviderInterface $paymentDescriptionProvider
PaymentDescriptionProviderInterface $paymentDescriptionProvider,
) {
$this->openPayUBridge = $openPayUBridge;
$this->paymentDescriptionProvider = $paymentDescriptionProvider;
Expand All @@ -67,7 +67,7 @@ public function setApi($api): void
$api['signature_key'],
$api['pos_id'],
$api['oauth_client_id'],
$api['oauth_client_secret']
$api['oauth_client_secret'],
);
}

Expand All @@ -77,7 +77,7 @@ public function execute($request): void
$model = $request->getModel();
/** @var PaymentInterface $payment */
$payment = $request->getFirstModel();
/** @var OrderInterface $orderData */
/** @var OrderInterface $order */
$order = $payment->getOrder();

/** @var TokenInterface $token */
Expand Down Expand Up @@ -122,12 +122,15 @@ public function setGenericTokenFactory(GenericTokenFactoryInterface $genericToke
public function supports($request): bool
{
return
$request instanceof Capture
&& $request->getModel() instanceof ArrayObject;
$request instanceof Capture &&
$request->getModel() instanceof ArrayObject;
}

private function prepareOrder(TokenInterface $token, OrderInterface $order, PaymentInterface $payment): array
{
private function prepareOrder(
TokenInterface $token,
OrderInterface $order,
PaymentInterface $payment,
): array {
$notifyToken = $this->tokenFactory->createNotifyToken($token->getGatewayName(), $token->getDetails());
$payUdata = [];

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

Expand All @@ -146,8 +150,8 @@ private function prepareOrder(TokenInterface $token, OrderInterface $order, Paym
CustomerInterface::class,
sprintf(
'Make sure the first model is the %s instance.',
CustomerInterface::class
)
CustomerInterface::class,
),
);

$buyer = [
Expand Down
10 changes: 5 additions & 5 deletions src/Action/ConvertPaymentAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class ConvertPaymentAction implements ActionInterface, GatewayAwareInterfa
use GatewayAwareTrait;

/**
* {@inheritdoc}
* @inheritdoc
*
* @param Convert $request
*/
Expand All @@ -49,13 +49,13 @@ public function execute($request): void
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function supports($request): bool
{
return $request instanceof Convert
&& $request->getSource() instanceof PaymentInterface
&& 'array' === $request->getTo();
return $request instanceof Convert &&
$request->getSource() instanceof PaymentInterface &&
'array' === $request->getTo();
}

private function getClientIp(): ?string
Expand Down
8 changes: 3 additions & 5 deletions src/Action/NotifyAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ final class NotifyAction implements ActionInterface, ApiAwareInterface
/** @var OpenPayUBridgeInterface */
private $openPayUBridge;

/** @param OpenPayUBridgeInterface $openPayUBridge */
public function __construct(OpenPayUBridgeInterface $openPayUBridge)
{
$this->openPayUBridge = $openPayUBridge;
Expand All @@ -51,16 +50,15 @@ public function setApi($api): void
$api['signature_key'],
$api['pos_id'],
$api['oauth_client_id'],
$api['oauth_client_secret']
$api['oauth_client_secret'],
);
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function execute($request): void
{
/** @var $request Notify */
RequestNotSupportedException::assertSupports($this, $request);
/** @var PaymentInterface $payment */
$payment = $request->getFirstModel();
Expand Down Expand Up @@ -99,7 +97,7 @@ public function execute($request): void
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function supports($request): bool
{
Expand Down
6 changes: 2 additions & 4 deletions src/Action/StatusAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ final class StatusAction implements ActionInterface
/** @var OpenPayUBridgeInterface */
private $openPayUBridge;

/** @param OpenPayUBridgeInterface $openPayUBridge */
public function __construct(OpenPayUBridgeInterface $openPayUBridge)
{
$this->openPayUBridge = $openPayUBridge;
Expand All @@ -43,16 +42,15 @@ public function setApi($api): void
$api['signature_key'],
$api['pos_id'],
$api['oauth_client_id'],
$api['oauth_client_secret']
$api['oauth_client_secret'],
);
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function execute($request): void
{
/** @var $request GetStatusInterface */
RequestNotSupportedException::assertSupports($this, $request);

$model = ArrayObject::ensureArrayObject($request->getModel());
Expand Down
13 changes: 9 additions & 4 deletions src/Bridge/OpenPayUBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace BitBag\SyliusPayUPlugin\Bridge;

use BitBag\SyliusPayUPlugin\Exception\PayUResponseException;
use OauthCacheFile;
use OpenPayU_Configuration;
use OpenPayU_Order;
Expand All @@ -30,7 +31,7 @@ public function setAuthorizationData(
string $signatureKey,
string $posId,
string $clientId,
string $clientSecret
string $clientSecret,
): void {
OpenPayU_Configuration::setEnvironment($environment);

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

public function create(array $order): ?OpenPayU_Result
{
/** @var OpenPayU_Result|null $result */
$result = OpenPayU_Order::create($order);
try {
/** @var OpenPayU_Result|null $result */
$result = OpenPayU_Order::create($order);

return $result;
return $result;
} catch (\OpenPayU_Exception $exception) {
throw new PayUResponseException($exception->getOriginalResponse()->getStatus(), $exception->getCode(), $order);
}
}

public function retrieve(string $orderId): OpenPayU_Result
Expand Down
12 changes: 11 additions & 1 deletion src/Bridge/OpenPayUBridgeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,35 @@
interface OpenPayUBridgeInterface
{
public const SANDBOX_ENVIRONMENT = 'sandbox';

public const SECURE_ENVIRONMENT = 'secure';

public const NEW_API_STATUS = 'NEW';

public const PENDING_API_STATUS = 'PENDING';

public const COMPLETED_API_STATUS = 'COMPLETED';

public const SUCCESS_API_STATUS = 'SUCCESS';

public const CANCELED_API_STATUS = 'CANCELED';

public const COMPLETED_PAYMENT_STATUS = 'COMPLETED';

public const PENDING_PAYMENT_STATUS = 'PENDING';

public const CANCELED_PAYMENT_STATUS = 'CANCELED';

public const WAITING_FOR_CONFIRMATION_PAYMENT_STATUS = 'WAITING_FOR_CONFIRMATION';

public const REJECTED_STATUS = 'REJECTED';

public function setAuthorizationData(
string $environment,
string $signatureKey,
string $posId,
string $clientId,
string $clientSecret
string $clientSecret,
): void;

public function create(array $order): ?OpenPayU_Result;
Expand Down
68 changes: 68 additions & 0 deletions src/EventListener/PayUResponseExceptionEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

/*
* This file was created by developers working at BitBag
* Do you need more information about us and what we do? Visit our https://bitbag.io website!
* 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
*/

declare(strict_types=1);

namespace BitBag\SyliusPayUPlugin\EventListener;

use BitBag\SyliusPayUPlugin\Exception\PayUResponseException;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\Routing\RouterInterface;

final class PayUResponseExceptionEventListener
{
private RouterInterface $router;

private RequestStack $requestStack;

private LoggerInterface $logger;

public function __construct(
RouterInterface $router,
RequestStack $requestStack,
LoggerInterface $logger,
) {
$this->router = $router;
$this->requestStack = $requestStack;
$this->logger = $logger;
}

public function onPayuOpenException(ExceptionEvent $event)
{
$exception = $event->getThrowable();

if ($exception instanceof PayUResponseException) {
$message = PayUResponseException::getTranslationByMessage($exception->getMessage());
$order = $exception->getOrder();

$this->logError($exception);
$this->requestStack->getSession()->getBag('flashes')->add('error', $message);

$route = empty($order['tokenValue'])
? $this->router->generate('sylius_shop_cart_summary')
: $this->router->generate('sylius_shop_order_show', ['tokenValue' => $order['tokenValue']]);

$response = new RedirectResponse($route);
$event->setResponse($response);
}
}

public function logError(\Exception $exception): void
{
$message = sprintf(
'%s %s',
'[PayU] Error while placing order',
$exception->getMessage(),
);

$this->logger->error($message);
}
}
45 changes: 45 additions & 0 deletions src/Exception/PayUResponseException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/*
* This file was created by developers working at BitBag
* Do you need more information about us and what we do? Visit our https://bitbag.io website!
* 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
*/

declare(strict_types=1);

namespace BitBag\SyliusPayUPlugin\Exception;

use Exception;
use Payum\Core\Exception\Http\HttpException;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;

final class PayUResponseException extends Exception
{
private array $order;

public function __construct(
string $message,
int $code,
?array $order = [],
?Exception $previous = null,
) {
$this->order = $order;
parent::__construct($message, $code, $previous);
}

public function getOrder(): array
{
return $this->order;
}

public static function getTranslationByMessage(?string $message): string
{
switch ($message) {
case 'ERROR_INCONSISTENT_CURRENCIES':
return 'bitbag.payu_plugin.payu_exception.currencies';
default:
return 'bitbag.payu_plugin.payu_exception.default';
}
}
}
Loading

0 comments on commit 8b4b7cb

Please sign in to comment.