Skip to content

Commit

Permalink
Add Blik one click payment variant
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Wysocki committed Nov 14, 2024
1 parent 3bb10ba commit b62021f
Show file tree
Hide file tree
Showing 27 changed files with 526 additions and 209 deletions.
1 change: 1 addition & 0 deletions Api/TpayInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface TpayInterface
public const GROUP = 'group';
public const CHANNEL = 'channel';
public const BLIK_CODE = 'blik_code';
public const BLIK_ALIAS = 'blik_alias';
public const TERMS_ACCEPT = 'accept_tos';
public const CARDDATA = 'card_data';
public const CARD_SAVE = 'card_save';
Expand Down
29 changes: 21 additions & 8 deletions Controller/Tpay/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public function execute(): ResultInterface
return $this->redirectFactory->redirectSuccess();
}

$result = $this->blikPay($transaction['title'], $additionalPaymentInformation['blik_code']);
$result = $this->blikPay($transaction['title'], $additionalPaymentInformation['blik_code'] ?? '', $additionalPaymentInformation['blik_alias'] ?? '');
$this->checkoutSession->unsQuoteId();

if (!$result) {
Expand All @@ -125,9 +125,13 @@ public function execute(): ResultInterface
* @param string $blikTransactionId
* @param string $blikCode
*/
protected function blikPay($blikTransactionId, $blikCode): bool
protected function blikPay($blikTransactionId, $blikCode, $blikAlias): bool
{
$apiResult = $this->transaction->blik($blikTransactionId, $blikCode);
if ($blikAlias) {
$apiResult = $this->transaction->blikAlias($blikTransactionId, $blikAlias);
} else {
$apiResult = $this->transaction->blik($blikTransactionId, $blikCode);
}

return isset($apiResult['result']) && 1 === $apiResult['result'];
}
Expand All @@ -139,7 +143,7 @@ private function prepareTransaction($orderId, array $additionalPaymentInformatio
if ($this->additionalPaymentInfoValidator->validateBlikIfPresent($additionalPaymentInformation)) {
$data['group'] = TransactionOriginApi::BLIK_CHANNEL;
$data['channel'] = null;
$this->handleBlikData($data, $additionalPaymentInformation['blik_code']);
$this->handleBlikData($data, $additionalPaymentInformation['blik_code'] ?? '', $additionalPaymentInformation['blik_alias'] ?? '');
} else {
$data['group'] = (int) ($additionalPaymentInformation['group'] ?? null);
$data['channel'] = (int) ($additionalPaymentInformation['channel'] ?? null);
Expand All @@ -159,12 +163,21 @@ private function prepareTransaction($orderId, array $additionalPaymentInformatio
return $this->transaction->create($data);
}

private function handleBlikData(array &$data, string $blikCode)
private function handleBlikData(array &$data, string $blikCode, string $blikAlias)
{
if ($this->transaction->isOpenApiUse() && $this->tpay->checkBlikLevel0Settings()) {
$data['blikPaymentData'] = [
'blikToken' => $blikCode,
];
if ($blikCode) {
$data['blikPaymentData'] = [
'blikToken' => $blikCode,
];
}

if ($blikAlias) {
$data['blikPaymentData']['aliases'] = [
'type' => 'UID',
'value' => $blikAlias,
];
}
}
if (!$this->transaction->isOpenApiUse()) {
unset($data['channel']);
Expand Down
182 changes: 9 additions & 173 deletions Controller/Tpay/Notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,78 +4,37 @@

namespace Tpay\Magento2\Controller\Tpay;

use Exception;
use Laminas\Http\Response;
use Magento\Framework\App\CsrfAwareActionInterface;
use Magento\Framework\App\Request\InvalidRequestException;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Sales\Model\Order;
use Tpay\Magento2\Api\TpayConfigInterface;
use Tpay\Magento2\Api\TpayInterface;
use Tpay\Magento2\Notification\Strategy\Factory\NotificationProcessorFactoryInterface;
use Tpay\Magento2\Service\TpayService;
use Tpay\Magento2\Service\TpayTokensService;
use Tpay\OpenApi\Webhook\JWSVerifiedPaymentNotification;
use Tpay\OriginApi\Utilities\Util;
use Tpay\OriginApi\Webhook\JWSVerifiedPaymentNotification as OriginJWSVerifiedPaymentNotification;
use Throwable;
use Tpay\Magento2\Notification\NotificationProcessor;

class Notification implements CsrfAwareActionInterface
{
/** @var TpayInterface */
protected $tpay;

/** @var TpayConfigInterface */
protected $tpayConfig;

/** @var TpayService */
protected $tpayService;

/** @var NotificationProcessorFactoryInterface */
protected $notificationProcessorFactory;

/** @var TpayTokensService */
private $tokensService;
/** @var NotificationProcessor */
protected $notificationProcessor;

/** @var ResponseInterface */
private $response;

public function __construct(
TpayInterface $tpayModel,
TpayConfigInterface $tpayConfig,
TpayService $tpayService,
TpayTokensService $tokensService,
ResponseInterface $response,
NotificationProcessorFactoryInterface $notificationProcessorFactory
NotificationProcessor $notificationProcessor
) {
$this->tpay = $tpayModel;
$this->tpayConfig = $tpayConfig;
$this->tpayService = $tpayService;
$this->tokensService = $tokensService;
$this->response = $response;
$this->notificationProcessorFactory = $notificationProcessorFactory;
Util::$loggingEnabled = false;
$this->notificationProcessor = $notificationProcessor;
}

public function execute(): ?Response
{
try {
if (isset($_POST['card'])) {
$orderId = base64_decode($_POST['order_id']);

return $this->extractCardNotification($this->getOrderStore($orderId));
}

if (isset($_POST['event'])) {
return $this->response->setStatusCode(Response::STATUS_CODE_400)->setContent('kurwa mac');
}

$orderId = base64_decode($_POST['tr_crc']);
$orderId = isset($_POST['order_id']) ? base64_decode($_POST['order_id']) : base64_decode($_POST['tr_crc']);

$strategy = $this->notificationProcessorFactory->create($_POST);

$strategy->process($this->getOrderStore($orderId));
} catch (\Throwable $e) {
$this->notificationProcessor->process($orderId);
} catch (Throwable $e) {
return $this->response->setStatusCode(Response::STATUS_CODE_400)->setContent($e->getMessage());
}

Expand All @@ -91,127 +50,4 @@ public function validateForCsrf(RequestInterface $request): ?bool
{
return true;
}

/**
* Check if the order has been canceled and get response to Tpay server.
*
* @throws Exception
*/
protected function getPaidTransactionResponse(string $orderId): string
{
$order = $this->tpayService->getOrderById($orderId);

if (!$order->getId()) {
throw new Exception(sprintf('Unable to get order by orderId %s', $orderId));
}

if (Order::STATE_CANCELED === $order->getState()) {
return 'FALSE';
}

return 'TRUE';
}

private function saveCard(array $notification, string $orderId)
{
$order = $this->tpayService->getOrderById($orderId);

if (isset($notification['card_token']) && !$this->tpay->isCustomerGuest($orderId)) {
$token = $this->tokensService->getWithoutAuthCustomerTokens(
(string) $order->getCustomerId(),
$notification['tr_crc']
);

if (!empty($token)) {
$this->tokensService->updateTokenById((int) $token['tokenId'], $notification['card_token']);
}
}
}

private function saveOriginCard(array $notification, string $orderId)
{
$order = $this->tpayService->getOrderById($orderId);

$payment = $this->tpayService->getPayment($orderId);
$additionalPaymentInformation = $payment->getData()['additional_information'];

if (isset($notification['cli_auth']) && $this->tpayConfig->getCardSaveEnabled() && !$this->tpay->isCustomerGuest($orderId)) {
$this->tokensService->setCustomerToken(
(string) $order->getCustomerId(),
$notification['cli_auth'],
$notification['card'],
$additionalPaymentInformation['card_vendor']
);
}
}

private function extractNotification(?int $storeId = null): Response
{
try {
$notification = (new JWSVerifiedPaymentNotification(
$this->tpayConfig->getSecurityCode($storeId),
!$this->tpayConfig->useSandboxMode($storeId)
))->getNotification();

$notification = $notification->getNotificationAssociative();
$orderId = base64_decode($notification['tr_crc']);

if ('PAID' === $notification['tr_status']) {
$response = $this->getPaidTransactionResponse($orderId);

return $this->response->setStatusCode(Response::STATUS_CODE_200)->setContent($response);
}

$this->saveCard($notification, $orderId);
$this->tpayService->setOrderStatus($orderId, $notification, $this->tpayConfig);

return $this->response->setStatusCode(Response::STATUS_CODE_200)->setContent('TRUE');
} catch (Exception $e) {
$this->handleException($e);

return $this->response->setStatusCode(Response::STATUS_CODE_400)->setContent('FALSE');
}
}

private function extractCardNotification(?int $storeId = null): ?Response
{
try {
$notification = (new OriginJWSVerifiedPaymentNotification(
$this->tpayConfig->getSecurityCode($storeId),
!$this->tpayConfig->useSandboxMode($storeId)
))->getNotification();

$orderId = base64_decode($notification['order_id']);

$this->tpayService->setCardOrderStatus($orderId, $notification, $this->tpayConfig);
$this->saveOriginCard($notification, $orderId);

return $this->response->setStatusCode(Response::STATUS_CODE_200)->setContent('TRUE');
} catch (Exception $e) {
$this->handleException($e);

return $this->response->setStatusCode(Response::STATUS_CODE_400)->setContent('FALSE');
}
}

private function handleException(Exception $e)
{
Util::log(
'Notification exception',
sprintf(
'%s in file %s line: %d \n\n %s',
$e->getMessage(),
$e->getFile(),
$e->getLine(),
$e->getTraceAsString()
)
);
}

private function getOrderStore(string $orderId): ?int
{
$order = $this->tpayService->getOrderById($orderId);

return $order->getStoreId() ? (int) $order->getStoreId() : null;
}
}
38 changes: 35 additions & 3 deletions Model/Alias.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,44 @@

namespace Tpay\Magento2\Model;

use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Model\Context;
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Framework\Registry;
use Tpay\Magento2\Model\Api\Data\AliasInterface;

class Alias extends AbstractModel
class Alias extends AbstractModel implements AliasInterface
{
public function __construct()
{
public function __construct(
Context $context,
Registry $registry,
AbstractResource $resource = null,
AbstractDb $resourceCollection = null,
array $data = []
) {
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
$this->_init(ResourceModel\Alias::class);
}

public function setCustomerId(int $id): AliasInterface
{
$this->setData('cli_id', $id);

return $this;
}

public function setAlias(string $alias): AliasInterface
{
$this->setData('alias', $alias);

return $this;
}

public function created(): AliasInterface
{
$this->setData('created_at', date('Y-m-d H:i:s'));

return $this;
}
}
48 changes: 48 additions & 0 deletions Model/AliasRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace Tpay\Magento2\Model;

use Tpay\Magento2\Model\Api\AliasRepositoryInterface;
use Tpay\Magento2\Model\Api\Data\AliasInterface;
use Tpay\Magento2\Model\ResourceModel\Alias as AliasResourceModel;

class AliasRepository implements AliasRepositoryInterface
{
/** @var AliasFactory */
protected $aliasFactory;

/** @var AliasResourceModel */
protected $aliasResourceModel;

public function __construct(AliasFactory $aliasFactory, AliasResourceModel $aliasResourceModel)
{
$this->aliasFactory = $aliasFactory;
$this->aliasResourceModel = $aliasResourceModel;
}

public function findByCustomerId(int $customerId): ?AliasInterface
{
$alias = $this->aliasFactory->create();
$this->aliasResourceModel->load($alias, $customerId, 'cli_id');

return $alias;
}

/**
* @inheritDoc
*/
public function save(AliasInterface $alias): void
{
$this->aliasResourceModel->save($alias);
}

/**
* @inheritDoc
*/
public function remove(AliasInterface $alias): void
{
$this->aliasResourceModel->delete($alias);
}
}
Loading

0 comments on commit b62021f

Please sign in to comment.