[ECP-9944] Add cron to clean up stale adyen_payment_response rows#3297
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a PaymentResponseCleanUp cron job to manage the growth of the adyen_payment_response table by deleting records associated with finalized orders or orphaned entries older than a grace period. Key additions include a created_at timestamp in the database schema, configuration toggles, and corresponding unit tests. Feedback suggests improving the architecture by moving database constants to the Resource Model, enhancing the cron job to process multiple batches in a single run for better scalability, and ensuring timezone consistency by using UTC DateTime for date calculations.
| const TABLE_NAME = 'adyen_payment_response'; | ||
| const TABLE_NAME_ALIAS = 'payment_response'; |
There was a problem hiding this comment.
Database-specific constants such as TABLE_NAME and TABLE_NAME_ALIAS should ideally reside in the Resource Model rather than the Data Interface. The Interface should focus on the data contract, while the Resource Model handles storage details. Moving these to Adyen\Payment\Model\ResourceModel\PaymentResponse would better adhere to the separation of concerns.
| $finalizedRemoved = $this->deleteBatch( | ||
| 'finalized', | ||
| fn (): array => $this->paymentResponseCollectionFactory->create() | ||
| ->getFinalizedPaymentResponseIds(self::BATCH_SIZE) | ||
| ); | ||
|
|
||
| $orphanRemoved = $this->deleteBatch( | ||
| 'orphan', | ||
| fn (): array => $this->paymentResponseCollectionFactory->create() | ||
| ->getOrphanPaymentResponseIds(self::ORPHAN_GRACE_DAYS, self::BATCH_SIZE) | ||
| ); |
There was a problem hiding this comment.
The current implementation only processes a single batch of 1000 rows per cron run. For high-volume stores or when clearing a large backlog, this might be insufficient. Consider wrapping the deletion logic in a loop that continues until fewer than BATCH_SIZE rows are returned, or until a maximum number of iterations is reached to prevent timeouts. This would ensure the table is cleaned more effectively without relying solely on the cron scheduler to trigger multiple runs.
| */ | ||
| public function getOrphanPaymentResponseIds(int $graceDays, int $batchSize): array | ||
| { | ||
| $dateFrom = date('Y-m-d H:i:s', time() - $graceDays * 24 * 60 * 60); |
There was a problem hiding this comment.
Using date() and time() relies on the PHP server's configured timezone, which may differ from the UTC timezone typically used by the Magento database for timestamp columns. This can result in an incorrect grace period calculation if the server timezone is not UTC. It is recommended to use an explicit UTC DateTime object to ensure the date string matches the database storage.
$dateFrom = (new \DateTime('now', new \DateTimeZone('UTC')))->sub(new \DateInterval("P{$graceDays}D"))->format('Y-m-d H:i:s');
|



Description
This PR introduces an opt-in nightly cron job that removes stale rows from adyen_payment_response. Once the order is finalized or orphaned, it is safe to drop these records.
Fixes #2578