Meldet die Bank nach der TAN 3045 (noch keine Rückmeldung zum Status), fragt ein Hintergrundprozess nach der Mindestwartezeit aus HIIPSS per HKIPS nach (höchstens fünfmal). Ausgeführt wird vermerkt, abgelehnt entfernt die Buchung; ein verbundener Kontoumsatz klärt den Status ebenfalls. php-fints-Fork v4.1.7 bringt HKIPS/HIIPS/HIIPSS mit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
74 lines
2.5 KiB
PHP
74 lines
2.5 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
/**
|
||
* Fragt den Status einer Echtzeitüberweisung im Hintergrund nach (#113).
|
||
*
|
||
* Meldet die Bank nach dem Senden 3045 („noch keine Rückmeldung zum Status“),
|
||
* startet `FinTsUeberweisung::hintergrundStarten()` dieses Skript losgelöst vom
|
||
* Browser:
|
||
*
|
||
* php scripts/echtzeit-status.php <benutzer_id> <auftrag_id>
|
||
*
|
||
* Es wartet jeweils die Mindestwartezeit der Bank ab und fragt nach – höchstens
|
||
* VERSUCHE Mal. Bleibt der Ausgang offen, stellt es die automatische Abfrage
|
||
* ein; dann klärt ihn der nächste Umsatzabruf. Eine Sperrdatei je Auftrag
|
||
* verhindert, dass zwei Prozesse gleichzeitig dieselbe Überweisung abfragen.
|
||
*/
|
||
|
||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||
|
||
use Finanzmanager\Config;
|
||
use Finanzmanager\Mandant;
|
||
use Finanzmanager\Models\Einstellung;
|
||
use Finanzmanager\Models\Zahlungsauftrag;
|
||
use Finanzmanager\Services\DebugLog;
|
||
use Finanzmanager\Services\FinTsUeberweisung;
|
||
|
||
const VERSUCHE = 5;
|
||
|
||
Config::load();
|
||
|
||
$benutzerId = (int)($argv[1] ?? 0);
|
||
$auftragId = (int)($argv[2] ?? 0);
|
||
if ($benutzerId === 0 || $auftragId === 0) {
|
||
fwrite(STDERR, "Aufruf: php scripts/echtzeit-status.php <benutzer_id> <auftrag_id>\n");
|
||
exit(1);
|
||
}
|
||
|
||
$sperre = fopen(sys_get_temp_dir() . '/finanzmanager-echtzeit-' . $auftragId . '.lock', 'c');
|
||
if ($sperre === false || !flock($sperre, LOCK_EX | LOCK_NB)) {
|
||
exit(0); // Ein anderer Prozess fragt diesen Auftrag schon ab.
|
||
}
|
||
|
||
Mandant::setze($benutzerId);
|
||
DebugLog::setAktiv(Einstellung::getBool('debug_log_aktiv', (bool)Config::get('debug_log', false)));
|
||
|
||
for ($versuch = 1; $versuch <= VERSUCHE; $versuch++) {
|
||
$auftrag = Zahlungsauftrag::find($auftragId);
|
||
$sekunden = $auftrag === null ? null : Zahlungsauftrag::sekundenBisStatusabfrage($auftrag);
|
||
if ($sekunden === null) {
|
||
exit(0); // Geklärt, eingestellt oder nicht (mehr) abfragbar.
|
||
}
|
||
|
||
if ($sekunden > 0) {
|
||
sleep($sekunden);
|
||
}
|
||
|
||
try {
|
||
$ergebnis = FinTsUeberweisung::statusImHintergrund($auftragId);
|
||
DebugLog::schreibe('fints', sprintf('Statusabfrage %d/%d für Auftrag %d: %s', $versuch, VERSUCHE, $auftragId, $ergebnis['meldung']));
|
||
} catch (\Throwable $e) {
|
||
DebugLog::fehler($e);
|
||
}
|
||
}
|
||
|
||
Zahlungsauftrag::echtzeitAbfrageEinstellen(
|
||
$auftragId,
|
||
sprintf(
|
||
'Die Bank hat den Ausgang der Echtzeitüberweisung auch nach %d Statusabfragen nicht bestätigt. '
|
||
. 'Er klärt sich beim nächsten Umsatzabruf. Nicht erneut senden – das wäre eine Doppelzahlung.',
|
||
VERSUCHE
|
||
)
|
||
);
|