Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.6.0
2.6.1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

namespace Tpay\Magento2\Api\Notification\Strategy;

use Tpay\OpenApi\Model\Objects\Objects;

interface NotificationProcessorFactoryInterface
{
public function create(array $data): NotificationProcessorInterface;
/** @param array|Objects $notification */
public function create($notification): NotificationProcessorInterface;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

interface NotificationProcessorInterface
{
public function process(?int $storeId);
public function process($notification);
}
6 changes: 6 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 2.6.1

### Changed

- New SDK notifications support

## 2.6.0

### Changed
Expand Down
68 changes: 42 additions & 26 deletions Notification/NotificationProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
namespace Tpay\Magento2\Notification;

use Magento\Framework\App\RequestInterface;
use Magento\Store\Model\StoreManagerInterface;
use Tpay\Magento2\Api\Notification\Strategy\NotificationProcessorFactoryInterface;
use Tpay\Magento2\Notification\Strategy\BlikAliasNotificationProcessor;
use Tpay\Magento2\Api\TpayConfigInterface;
use Tpay\Magento2\Service\TpayService;
use Tpay\OpenApi\Utilities\Cache;
use Tpay\OpenApi\Utilities\CacheCertificateProvider;
use Tpay\OpenApi\Webhook\JWSVerifiedPaymentNotification as OpenApiWebhook;
use Tpay\OriginApi\Webhook\JWSVerifiedPaymentNotification as OriginApiWebhook;

class NotificationProcessor
{
Expand All @@ -18,43 +23,54 @@ class NotificationProcessor
/** @var RequestInterface */
private $request;

public function __construct(NotificationProcessorFactoryInterface $factory, TpayService $tpayService, RequestInterface $request)
{
/** @var TpayConfigInterface */
private $config;

/** @var StoreManagerInterface */
private $storeManager;

public function __construct(
RequestInterface $request,
NotificationProcessorFactoryInterface $factory,
TpayService $tpayService,
TpayConfigInterface $config,
StoreManagerInterface $storeManager
) {
$this->request = $request;
$this->factory = $factory;
$this->tpayService = $tpayService;
$this->request = $request;
$this->config = $config;
$this->storeManager = $storeManager;
}

public function process()
{
$strategy = $this->factory->create($this->request->getPost()->toArray());
$storeId = null;

if (!$strategy instanceof BlikAliasNotificationProcessor) {
$orderId = $this->getOrderId();
if ($orderId) {
$storeId = $this->getOrderStore($orderId);
}
}
$storeId = $this->storeManager->getStore()->getId();
$webhook = $this->createWebhook($storeId);

$strategy->process($storeId);
}

private function getOrderId(): ?string
{
$value = $this->request->getPost('order_id') ?? $this->request->getPost('tr_crc');
$notification = $webhook->getNotification();

if (null === $value) {
return null;
}
$strategy = $this->factory->create($notification);

return base64_decode($value);
$strategy->process($notification);
}

private function getOrderStore(string $orderId): ?int
/** @return OpenApiWebhook|OriginApiWebhook */
private function createWebhook(?int $storeId)
{
$order = $this->tpayService->getOrderById($orderId);
if (null !== $this->request->getPost('card')) {
return new OriginApiWebhook(
$this->config->getApiPassword($storeId),
!$this->config->useSandboxMode($storeId)
);
}

$certificateProvider = new CacheCertificateProvider(new Cache());

return $order->getStoreId() ? (int) $order->getStoreId() : null;
return new OpenApiWebhook(
$certificateProvider,
$this->config->getSecurityCode($storeId),
!$this->config->useSandboxMode($storeId)
);
}
}
33 changes: 20 additions & 13 deletions Notification/Strategy/BlikAliasNotificationProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,42 @@

namespace Tpay\Magento2\Notification\Strategy;

use Magento\Framework\App\RequestInterface;
use RuntimeException;
use Tpay\Magento2\Api\Notification\Strategy\NotificationProcessorInterface;
use Tpay\Magento2\Service\TpayAliasServiceInterface;
use Tpay\OpenApi\Model\Objects\NotificationBody\BlikAliasRegister;
use Tpay\OpenApi\Model\Objects\NotificationBody\BlikAliasUnregister;

class BlikAliasNotificationProcessor implements NotificationProcessorInterface
{
/** @var TpayAliasServiceInterface */
protected $aliasService;

/** @var RequestInterface */
private $request;

public function __construct(TpayAliasServiceInterface $aliasService, RequestInterface $request)
public function __construct(TpayAliasServiceInterface $aliasService)
{
$this->aliasService = $aliasService;
$this->request = $request;
}

public function process(?int $storeId = null)
public function process($notification)
{
$response = $this->request->getPost()->toArray();
$userId = (int) explode('-', $response['msg_value']['value'])[1];
if ($notification instanceof BlikAliasRegister) {
$alias = (string) $notification->value->getValue();
$userId = (int) explode('-', $alias)[1];

$this->aliasService->saveCustomerAlias($userId, $alias);

if ('ALIAS_REGISTER' === $response['event']) {
$this->aliasService->saveCustomerAlias($userId, $response['msg_value']['value']);
return;
}

if ('ALIAS_UNREGISTER' === $response['event']) {
$this->aliasService->removeCustomerAlias($userId, $response['msg_value']['value']);
if ($notification instanceof BlikAliasUnregister) {
$alias = (string) $notification->value->getValue();
$userId = (int) explode('-', $alias)[1];

$this->aliasService->removeCustomerAlias($userId, $alias);

return;
}

throw new RuntimeException('Unsupported BLIK notification type');
}
}
12 changes: 3 additions & 9 deletions Notification/Strategy/CardNotificationProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Tpay\Magento2\Api\TpayInterface;
use Tpay\Magento2\Service\TpayService;
use Tpay\Magento2\Service\TpayTokensService;
use Tpay\OriginApi\Webhook\JWSVerifiedPaymentNotification;

class CardNotificationProcessor implements NotificationProcessorInterface
{
Expand All @@ -27,21 +26,16 @@ public function __construct(
TpayConfigInterface $tpayConfig,
TpayService $tpayService,
TpayTokensService $tokensService,
TpayInterface $tpayModel
TpayInterface $tpay
) {
$this->tpayConfig = $tpayConfig;
$this->tpayService = $tpayService;
$this->tokensService = $tokensService;
$this->tpay = $tpayModel;
$this->tpay = $tpay;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name have changed, but no other changes in this file - so this is unused dependency?

Copy link
Contributor Author

@aleksanderkakol aleksanderkakol Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its used in line 55, only name of parameter changed, property still has same name

}

public function process(?int $storeId)
public function process($notification)
{
$notification = (new JWSVerifiedPaymentNotification(
$this->tpayConfig->getSecurityCode($storeId),
!$this->tpayConfig->useSandboxMode($storeId)
))->getNotification();

$orderId = base64_decode($notification['order_id']);
$order = $this->tpayService->getOrderById($orderId);

Expand Down
76 changes: 42 additions & 34 deletions Notification/Strategy/DefaultNotificationProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@

namespace Tpay\Magento2\Notification\Strategy;

use RuntimeException;
use Tpay\Magento2\Api\Notification\Strategy\NotificationProcessorInterface;
use Tpay\Magento2\Api\TpayConfigInterface;
use Tpay\Magento2\Api\TpayInterface;
use Tpay\Magento2\Service\TpayService;
use Tpay\Magento2\Service\TpayTokensService;
use Tpay\OpenApi\Webhook\JWSVerifiedPaymentNotificationFactory;
use Tpay\OpenApi\Model\Objects\NotificationBody\BasicPayment;

class DefaultNotificationProcessor implements NotificationProcessorInterface
{
/** @var TpayConfigInterface */
protected $tpayConfig;

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

Expand All @@ -23,54 +20,65 @@ class DefaultNotificationProcessor implements NotificationProcessorInterface
/** @var TpayInterface */
protected $tpay;

/** @var JWSVerifiedPaymentNotificationFactory */
private $notificationFactory;

public function __construct(
TpayConfigInterface $tpayConfig,
TpayService $tpayService,
TpayTokensService $tokensService,
TpayInterface $tpayModel,
JWSVerifiedPaymentNotificationFactory $notificationFactory
TpayInterface $tpay
) {
$this->tpayConfig = $tpayConfig;
$this->tpayService = $tpayService;
$this->tokensService = $tokensService;
$this->tpay = $tpayModel;
$this->notificationFactory = $notificationFactory;
$this->tpay = $tpay;
}

public function process(?int $storeId)
public function process($notification)
{
$notification = $this->notificationFactory->create(['merchantSecret' => $this->tpayConfig->getSecurityCode($storeId), 'productionMode' => !$this->tpayConfig->useSandboxMode($storeId)])->getNotification();

$notification = $notification->getNotificationAssociative();
$orderId = base64_decode($notification['tr_crc']);
if (!$notification instanceof BasicPayment) {
throw new RuntimeException('Invalid payment notification type');
}

$orderId = base64_decode($notification->tr_crc->getValue());
$order = $this->tpayService->getOrderById($orderId);

if ('TRUE' === $notification['tr_status']) {
$this->tpayService->confirmPayment($order, $notification['tr_amount'], $notification['tr_id'], []);
$this->saveCard($notification, $orderId);
}
if ('CHARGEBACK' === $notification['tr_status']) {
$this->tpayService->addCommentToHistory($orderId, __('Transaction has been refunded via Tpay Transaction Panel'));
switch ($notification->tr_status->getValue()) {
case 'TRUE':
case 'PAID':
$this->tpayService->confirmPayment(
$order,
$notification->tr_amount->getValue(),
$notification->tr_id->getValue(),
[]
);
break;
case 'CHARGEBACK':
$this->tpayService->addCommentToHistory(
$orderId,
__('Transaction has been refunded via Tpay Transaction Panel')
);
break;
}

$this->saveCard($notification, $orderId);
}

private function saveCard(array $notification, string $orderId)
private function saveCard(BasicPayment $notification, string $orderId)
{
if (!$notification->card_token) {
return;
}

if ($this->tpay->isCustomerGuest($orderId)) {
return;
}

$order = $this->tpayService->getOrderById($orderId);

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

if (!empty($token)) {
$this->tokensService->updateTokenById((int) $token['tokenId'], $notification['card_token']);
}
if (!empty($token)) {
$this->tokensService->updateTokenById((int) $token['tokenId'], $notification->card_token->getValue());
}
}
}
19 changes: 8 additions & 11 deletions Notification/Strategy/Factory/NotificationProcessorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,29 @@

namespace Tpay\Magento2\Notification\Strategy\Factory;

use Magento\Framework\App\RequestInterface;
use Tpay\Magento2\Api\Notification\Strategy\NotificationProcessorFactoryInterface;
use Tpay\Magento2\Api\Notification\Strategy\NotificationProcessorInterface;
use Tpay\OpenApi\Model\Objects\NotificationBody\BlikAliasRegister;
use Tpay\OpenApi\Model\Objects\NotificationBody\BlikAliasUnregister;

class NotificationProcessorFactory implements NotificationProcessorFactoryInterface
{
/** @var list<NotificationProcessorInterface> */
protected $strategies;

/** @var RequestInterface */
private $request;

public function __construct(RequestInterface $request, array $strategies = [])
public function __construct(array $strategies = [])
{
$this->strategies = $strategies;
$this->request = $request;
}

public function create(array $data): NotificationProcessorInterface
public function create($notification): NotificationProcessorInterface
{
if (null !== $this->request->getPost('card')) {
return $this->strategies['card'];
if ($notification instanceof BlikAliasRegister || $notification instanceof BlikAliasUnregister) {
return $this->strategies['blikAlias'];
}

if (null !== $this->request->getPost('event')) {
return $this->strategies['blikAlias'];
if (is_array($notification) && isset($notification['card'])) {
return $this->strategies['card'];
}

return $this->strategies['default'];
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"php": ">=7.1",
"ext-json": "*",
"composer-runtime-api": "^2.0",
"tpay-com/tpay-openapi-php": "^2.2.3",
"tpay-com/tpay-openapi-php": "^2.4.0",
"tpay-com/tpay-php": "^2.4.7"
},
"suggest": {
Expand Down