CoolCMS API

PaymentPresenter extends BasePresenter
in package

FinalYes

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

$operationRunner

Boundary of one cron action (see {@see self::tryCall()}).

public OperationRunner $operationRunner
Attributes
#[Inject]

Methods

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

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
bool

sendError()

protected sendError(string $message[, int $code = 500 ]) : never
Parameters
$message : string
$code : int = 500
Return values
never

sendSkipped()

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
never

sendSuccess()

protected sendSuccess([array<string|int, mixed> $data = [] ]) : never
Parameters
$data : array<string|int, mixed> = []
Return values
never

tryCall()

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>
Return values
bool
On this page

Search results