Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d8c8881
[ECP-9414] Generate event dispatcher/observer mechanism for reliabili…
khushboo-singhvi Oct 3, 2024
cab10f6
[ECP-9413] Create CheckoutAnalytics helper class
candemiralp Jul 10, 2025
7c952c3
[ECP-9750] Implement configuration field for metrics data collection …
candemiralp Jul 11, 2025
7cc4068
[ECP-9745] Update the DB schema and refactor related classes (#3024)
candemiralp Jul 11, 2025
ef583a9
[ECP-9746] Refactoring Checkout Analytics event requests (#3079)
khushboo-singhvi Sep 18, 2025
1577b5d
Remote tracking main into the feature branch
candemiralp Sep 18, 2025
c566cd6
Remote tracking main into feature branch
candemiralp Oct 3, 2025
bab5747
[ECP-9751] Implement a cronjob to submit pending events (#3087)
candemiralp Oct 6, 2025
8357536
[ECP-9417] Implement event dispatchers (#3113)
candemiralp Oct 20, 2025
581bc10
[ECP-9727] Implement an event dispatcher for plugin installation even…
candemiralp Oct 20, 2025
4cad31e
Remote track main into feature branch
candemiralp Nov 13, 2025
907ce99
[ECP-9835] Add the version field to the adyen_analytics_event entity …
candemiralp Nov 14, 2025
376a8ed
Merge branch 'main' into feature/reliability
candemiralp Jan 2, 2026
f3fb6bd
Add unit tests (#3207)
candemiralp Jan 5, 2026
8344942
Fix several issues
candemiralp Jan 5, 2026
c84361c
Remove unexpectedEnd event from the info event batch
candemiralp Jan 5, 2026
9aea1fd
Truncate the topic if necessary
candemiralp Jan 5, 2026
09ecab0
Implement data clean-up functionality (#3209)
candemiralp Jan 6, 2026
4df7fca
Merge branch 'main' into feature/reliability
candemiralp Jan 6, 2026
2c14aff
Update .github/workflows/e2e-test.yml
candemiralp Jan 6, 2026
6e242b0
Update .github/workflows/main.yml
candemiralp Jan 6, 2026
5a5f1d2
Update .github/workflows/main.yml
candemiralp Jan 6, 2026
b089b42
Merge branch 'main' into feature/reliability
candemiralp Jan 6, 2026
5f04efe
Reformat the message in case of errors
candemiralp Jan 6, 2026
969363d
Merge branch 'main' into feature/reliability
candemiralp Jan 6, 2026
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
15 changes: 15 additions & 0 deletions Api/AnalyticsEventRepositoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
namespace Adyen\Payment\Api;

use Adyen\Payment\Api\Data\AnalyticsEventInterface;

interface AnalyticsEventRepositoryInterface
{
public function save(AnalyticsEventInterface $analyticsEvent): AnalyticsEventInterface;

public function getById(int $id): AnalyticsEventInterface;

public function delete(AnalyticsEventInterface $analyticsEvent): void;

public function deleteById(int $id): void;
}
94 changes: 94 additions & 0 deletions Api/Data/AnalyticsEventInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
/**
*
* Adyen Payment Module
*
* Copyright (c) 2025 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Api\Data;

use DateTime;

interface AnalyticsEventInterface
{
const ADYEN_ANALYTICS_EVENT = 'adyen_analytics_event';
const TABLE_NAME_ALIAS = 'analytics_event';
const ENTITY_ID = 'entity_id';
const UUID = 'uuid';
const RELATION_ID = 'relation_id';
const TYPE = 'type';
const TOPIC = 'topic';
const MESSAGE = 'message';
const VERSION = 'version';
const ERROR_TYPE = 'error_type';
const ERROR_CODE = 'error_code';
const ERROR_COUNT = 'error_count';
const STATUS = 'status';
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
const SCHEDULED_PROCESSING_TIME = 'scheduled_processing_time';
const MAX_ERROR_COUNT = 5;

public function getEntityId();

public function setEntityId($entityId);

public function getRelationId(): string;

public function setRelationId(string $relationId): AnalyticsEventInterface;

public function getUuid(): string;

public function setUuid(string $uuid): AnalyticsEventInterface;

public function getType(): string;

public function setType(string $type): AnalyticsEventInterface;

public function getTopic(): string;

public function setTopic(string $topic): AnalyticsEventInterface;

public function getMessage(): ?string;

public function setMessage(?string $message = null): AnalyticsEventInterface;

public function getVersion(): string;

public function setVersion(string $version): AnalyticsEventInterface;

public function getErrorType(): ?string;

public function setErrorType(?string $errorType = null): AnalyticsEventInterface;

public function getErrorCode(): ?string;

public function setErrorCode(?string $errorCode = null): AnalyticsEventInterface;

public function getErrorCount(): int;

public function setErrorCount(int $errorCount): AnalyticsEventInterface;

public function getStatus(): string;

public function setStatus(string $status): AnalyticsEventInterface;

public function getCreatedAt(): string;

public function setCreatedAt(string $createdAt): AnalyticsEventInterface;

public function getCreatedAtTimestamp(): int;

public function getUpdatedAt(): ?string;

public function setUpdatedAt(?string $updatedAt = null): AnalyticsEventInterface;

public function getScheduledProcessingTime(): ?string;

public function setScheduledProcessingTime(?string $scheduledProcessingTime = null): AnalyticsEventInterface;
}
20 changes: 20 additions & 0 deletions Api/Data/AnalyticsEventStatusEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/**
*
* Adyen Payment Module
*
* Copyright (c) 2025 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Api\Data;

enum AnalyticsEventStatusEnum: int
{
case PENDING = 0;
case PROCESSING = 1;
case DONE = 2;
}
20 changes: 20 additions & 0 deletions Api/Data/AnalyticsEventTypeEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/**
*
* Adyen Payment Module
*
* Copyright (c) 2025 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Api\Data;

enum AnalyticsEventTypeEnum: string
{
case EXPECTED_START = 'expectedStart';
case EXPECTED_END = 'expectedEnd';
case UNEXPECTED_END = 'unexpectedEnd';
}
18 changes: 18 additions & 0 deletions Api/Data/ConfigurationEventType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
*
* Adyen Payment Module
*
* Copyright (c) 2025 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Api\Data;

enum ConfigurationEventType: string
{
case PLUGIN_INSTALLATION = 'plugin_installation';
}
54 changes: 54 additions & 0 deletions Cron/AnalyticsEventsCleanUp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/**
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2026 Adyen NV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Cron;

use Adyen\Payment\Api\Data\AnalyticsEventInterface;
use Adyen\Payment\Logger\AdyenLogger;
use Adyen\Payment\Model\ResourceModel\AnalyticsEvent;
use Adyen\Payment\Model\ResourceModel\AnalyticsEvent\CollectionFactory;
use Exception;

class AnalyticsEventsCleanUp
{
/**
* @param CollectionFactory $analyticsEventCollectionFactory
* @param AnalyticsEvent $analyticsEventResourceModel
* @param AdyenLogger $adyenLogger
*/
public function __construct(
private readonly CollectionFactory $analyticsEventCollectionFactory,
private readonly AnalyticsEvent $analyticsEventResourceModel,
private readonly AdyenLogger $adyenLogger
) {}

/**
* This method is executed by the cron job `adyen_payment_clean_up_analytics_events` and deletes
* the analytics events that are older than 45 days OR are in the done state.
*
* @return void
*/
public function execute(): void
{
try {
$collection = $this->analyticsEventCollectionFactory->create()->analyticsEventsToCleanUp();

$ids = $collection->getColumnValues(AnalyticsEventInterface::ENTITY_ID);
if (!empty($ids)) {
$this->analyticsEventResourceModel->deleteByIds($ids);
}
} catch (Exception $e) {
$this->adyenLogger->error(
sprintf("An error occurred while cleaning up the analytics events: %s", $e->getMessage())
);
}
}
}
35 changes: 35 additions & 0 deletions Cron/Providers/AnalyticsEventProviderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
/**
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2025 Adyen N.V. (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Cron\Providers;

use Adyen\Payment\Api\Data\AnalyticsEventInterface;

interface AnalyticsEventProviderInterface
{
const BATCH_SIZE = 1000;
const CLEAN_UP_BATCH_SIZE = 5000;

/**
* @return AnalyticsEventInterface[]
*/
public function provide(): array;

/**
* @return string
*/
public function getAnalyticsContext(): string;

/**
* @return string
*/
public function getProviderName(): string;
}
60 changes: 60 additions & 0 deletions Cron/Providers/PendingErrorsAnalyticsEventsProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2025 Adyen N.V. (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Cron\Providers;

use Adyen\AdyenException;
use Adyen\Payment\Api\Data\AnalyticsEventInterface;
use Adyen\Payment\Api\Data\AnalyticsEventTypeEnum;
use Adyen\Payment\Helper\CheckoutAnalytics;
use Adyen\Payment\Model\ResourceModel\AnalyticsEvent\Collection as AnalyticsEventCollection;
use Adyen\Payment\Model\ResourceModel\AnalyticsEvent\CollectionFactory as AnalyticsEventCollectionFactory;

class PendingErrorsAnalyticsEventsProvider implements AnalyticsEventProviderInterface
{
const PROVIDER_NAME = 'Pending analytics events for `errors` context';

public function __construct(
private readonly AnalyticsEventCollectionFactory $analyticsEventCollectionFactory
) {}

/**
* @return AnalyticsEventInterface[]
* @throws AdyenException
*/
public function provide(): array
{
$analyticsEventCollection = $this->analyticsEventCollectionFactory->create();

/** @var AnalyticsEventCollection $analyticsEventCollection */
$analyticsEventCollection = $analyticsEventCollection->pendingAnalyticsEvents([
AnalyticsEventTypeEnum::UNEXPECTED_END
]);

return $analyticsEventCollection->getItems();
}

/**
* @return string
*/
public function getProviderName(): string
{
return self::PROVIDER_NAME;
}

/**
* @return string
*/
public function getAnalyticsContext(): string
{
return CheckoutAnalytics::CONTEXT_TYPE_ERRORS;
}
}
61 changes: 61 additions & 0 deletions Cron/Providers/PendingInfoAnalyticsEventsProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
/**
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2025 Adyen N.V. (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Cron\Providers;

use Adyen\AdyenException;
use Adyen\Payment\Api\Data\AnalyticsEventInterface;
use Adyen\Payment\Api\Data\AnalyticsEventTypeEnum;
use Adyen\Payment\Helper\CheckoutAnalytics;
use Adyen\Payment\Model\ResourceModel\AnalyticsEvent\Collection as AnalyticsEventCollection;
use Adyen\Payment\Model\ResourceModel\AnalyticsEvent\CollectionFactory as AnalyticsEventCollectionFactory;

class PendingInfoAnalyticsEventsProvider implements AnalyticsEventProviderInterface
{
const PROVIDER_NAME = 'Pending analytics events for `info` context';

public function __construct(
private readonly AnalyticsEventCollectionFactory $analyticsEventCollectionFactory
) {}

/**
* @return AnalyticsEventInterface[]
* @throws AdyenException
*/
public function provide(): array
{
$analyticsEventCollection = $this->analyticsEventCollectionFactory->create();

/** @var AnalyticsEventCollection $analyticsEventCollection */
$analyticsEventCollection = $analyticsEventCollection->pendingAnalyticsEvents([
AnalyticsEventTypeEnum::EXPECTED_START,
AnalyticsEventTypeEnum::EXPECTED_END
]);

return $analyticsEventCollection->getItems();
}

/**
* @return string
*/
public function getProviderName(): string
{
return self::PROVIDER_NAME;
}

/**
* @return string
*/
public function getAnalyticsContext(): string
{
return CheckoutAnalytics::CONTEXT_TYPE_INFO;
}
}
Loading
Loading