PaymentPresenter
extends BasePresenter
in package
Payment maintenance jobs: the activation audit and the retention of the gateway notification history.
Activation audit: probe for "paid but not activated": the payment is COMPLETED but the module items are not active
(a crash in the middle of the callback or a handler failure).
Recovery stays manual; the admin gets a bell notification (type PAYMENT_NOT_ACTIVATED, linking to the
payment detail), one per payment. How a missing activation is detected: PaymentActivationAuditManager.
URL: /cron/system/payment/activation-audit?token=xxx[&minutes=N][&days=N]
Parameters: minutes is the minimum payment age (default 15), days how far back to look (default 14).
Frequency: every 15 minutes. The endpoint guards itself to run at most once per GUARD_TTL seconds.
It sends only the internal bell notification, no e-mails or SMS (outbound: false).
Gateway notification retention, URL: /cron/system/payment/purge-notifications?token=xxx[&days=N]
Deletes rows of the gateway notification history (cms_system_payment_gateway_notifications, admin tab
"Communication with the gateway") older than ?days, else the setting payment.notificationLog.retentionDays
(group 1, Settings › Cron), else PaymentGatewayNotificationManager::DEFAULT_RETENTION_DAYS;
resolved by PaymentGatewayNotificationManager::purgeExpired().
A year keeps the evidence for complaints and chargebacks; payments and their transactions are not touched.
Frequency: daily, guarded to run at most once per PURGE_GUARD_TTL seconds.
Table of Contents
Constants
- GUARD_NAME : string = 'payment.activationAudit.lastRun'
- Lock row remembering the last run (`cms_cron_locks`) — deliberately never released on success.
- GUARD_TTL : int = 600
- 10 min, just under the 15 min period: a crontab fires a few seconds earlier than the previous run finished.
- PURGE_GUARD_NAME : string = 'payment.notificationLog.lastPurge'
- PURGE_GUARD_TTL : int = 72000
- 20 h, not 24 h: a daily crontab fires a few seconds earlier than the previous run finished.
Properties
- $cronLockManager : CronLockManager
- $operationRunner : OperationRunner
- Boundary of one cron action (see {@see self::tryCall()}).
- $settingContext : SettingContext
- $settingManager : SettingManager
- $debugMode : bool
- $productionMode : bool
- $activationAuditManager : PaymentActivationAuditManager
- $gatewayNotificationManager : PaymentGatewayNotificationManager
Methods
- __construct() : mixed
- actionActivationAudit() : void
- actionPurgeNotifications() : void
- releaseLock() : void
- Releases the lock at most once; called by both `shutdown()` and the PHP shutdown function.
- sendResponse() : void
- setConfigParameters() : void
- shutdown() : void
- startup() : void
- isSameSiteRequest() : bool
- Tells whether the request comes from the own site (Nette SameSite cookie); protects GET actions with a side effect.
- sendError() : never
- sendSkipped() : never
- Reports that the job did only part of the work and the next call finishes the rest (e.g. a reindex done in chunks).
- sendSuccess() : never
- tryCall() : bool
- Runs the `action<Action>()` method as one operation (transitional).
Constants
GUARD_NAME
Lock row remembering the last run (`cms_cron_locks`) — deliberately never released on success.
private
string
GUARD_NAME
= 'payment.activationAudit.lastRun'
GUARD_TTL
10 min, just under the 15 min period: a crontab fires a few seconds earlier than the previous run finished.
private
int
GUARD_TTL
= 600
PURGE_GUARD_NAME
private
string
PURGE_GUARD_NAME
= 'payment.notificationLog.lastPurge'
PURGE_GUARD_TTL
20 h, not 24 h: a daily crontab fires a few seconds earlier than the previous run finished.
private
int
PURGE_GUARD_TTL
= 72000
Properties
$cronLockManager
public
CronLockManager
$cronLockManager
Attributes
- #[Inject]
$operationRunner
Boundary of one cron action (see {@see self::tryCall()}).
public
OperationRunner
$operationRunner
Attributes
- #[Inject]
$settingContext
public
SettingContext
$settingContext
Attributes
- #[Inject]
$settingManager
public
SettingManager
$settingManager
Attributes
- #[Inject]
$debugMode
protected
bool
$debugMode
= false
$productionMode
protected
bool
$productionMode
= false
$activationAuditManager read-only
private
PaymentActivationAuditManager
$activationAuditManager
$gatewayNotificationManager read-only
private
PaymentGatewayNotificationManager
$gatewayNotificationManager
Methods
__construct()
public
__construct(PaymentActivationAuditManager $activationAuditManager, PaymentGatewayNotificationManager $gatewayNotificationManager) : mixed
Parameters
- $activationAuditManager : PaymentActivationAuditManager
- $gatewayNotificationManager : PaymentGatewayNotificationManager
actionActivationAudit()
public
actionActivationAudit([int|null $minutes = null ][, int|null $days = null ]) : void
Parameters
- $minutes : int|null = null
- $days : int|null = null
Attributes
- #[CronJob]
- $frequency: 'every:15'
- $outbound: false
actionPurgeNotifications()
public
actionPurgeNotifications([int|null $days = null ]) : void
Parameters
- $days : int|null = null
Attributes
- #[CronJob]
- $frequency: 'daily:04:18'
- $outbound: false
releaseLock()
Releases the lock at most once; called by both `shutdown()` and the PHP shutdown function.
public
releaseLock() : void
sendResponse()
public
sendResponse(Response $response) : void
Parameters
- $response : Response
setConfigParameters()
public
setConfigParameters([bool $debugMode = false ][, bool $productionMode = false ]) : void
Parameters
- $debugMode : bool = false
- $productionMode : bool = false
shutdown()
public
shutdown(Response $response) : void
Parameters
- $response : Response
startup()
public
startup() : void
isSameSiteRequest()
Tells whether the request comes from the own site (Nette SameSite cookie); protects GET actions with a side effect.
protected
isSameSiteRequest() : bool
getHttpRequest() returns the IRequest interface, while isSameSite() exists only on
Nette\Http\Request.
Return values
boolsendError()
protected
sendError(string $message[, int $code = 500 ]) : never
Parameters
- $message : string
- $code : int = 500
Return values
neversendSkipped()
Reports that the job did only part of the work and the next call finishes the rest (e.g. a reindex done in chunks).
protected
sendSkipped(string $reason[, array<string, mixed> $data = [] ]) : never
The scheduler does not record skipped as a run, so the job stays due and is called
again on the next tick.
Parameters
- $reason : string
- $data : array<string, mixed> = []
Return values
neversendSuccess()
protected
sendSuccess([array<string|int, mixed> $data = [] ]) : never
Parameters
- $data : array<string|int, mixed> = []
Return values
nevertryCall()
Runs the `action<Action>()` method as one operation (transitional).
protected
tryCall(string $method, array<string, mixed> $params) : bool
Cron has no internalAction*(): its actions call the Api managers directly, so without this in
scoped mode nothing would ever empty the unit of work of a cron run. The boundary is the action
only; startup() (settings, token, lock) stays outside like the startup of an Api request. A cron
action ends with AbortException from send*(), which is a regular end: the outcome comes from the
response (ok succeeded, skipped unknown — possibly a part of a batch was done, error failed).
Render and signal methods are not wrapped (cron presenters have none).
Parameters
- $method : string
- $params : array<string, mixed>