Finanzmanager/scripts/echtzeit-status.php
fds2610-bot 8b245ad769 Fix #113: Echtzeitüberweisung – offenen Status im Hintergrund bei der Bank nachfragen
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>
2026-10-06 15:48:38 +02:00

74 lines
2.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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
)
);