Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions lib/Fhp/Action/SendSEPATransferVoP.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Fhp\Action;

use Fhp\Protocol\BPD;
use Fhp\Protocol\Message;
use Fhp\Protocol\UPD;
use Fhp\Segment\HIRMS\Rueckmeldungscode;
use Fhp\Segment\VPP\HIVPPSv1;
use Fhp\Segment\VPP\HIVPPv1;
use Fhp\Segment\VPP\HKVPPv1;
use Fhp\UnsupportedException;

/**
* Initiates an outgoing wire transfer in SEPA format (PAIN XML) with VoP.
* @see FinTS_3.0_Messages_Geschaeftsvorfaelle_VOP_1.01_2025_06_27_FV.pdf
*/
class SendSEPATransferVoP extends SendSEPATransfer
{
protected $vopRequired = false;
protected $vopIsPending = false;
protected $vopNeedsConfirmation = false;

protected function createRequest(BPD $bpd, ?UPD $upd)
{
$requestSegment = parent::createRequest($bpd, $upd);
$requestSegments = [$requestSegment];

// Check if VoP is supported by the bank

/** @var HIVPPSv1 $hivpps */
if ($hivpps = $bpd->getLatestSupportedParameters('HIVPPS')) {
// Check if the request segment is in the list of VoP-supported segments
if (in_array($requestSegment->getName(), $hivpps->parameter->vopPflichtigerZahlungsverkehrsauftrag)) {

$this->vopRequired = true;

$hkvpp = HKVPPv1::createEmpty();

// For now just pretend we support all formats
$supportedFormats = explode(';', $hivpps->parameter->unterstuetztePaymentStatusReportDatenformate);
$hkvpp->unterstuetztePaymentStatusReports->paymentStatusReportDescriptor = $supportedFormats;

// VoP before the transfer request
$requestSegments = [$hkvpp, $requestSegment];
}
}

return $requestSegments;
}

public function processResponse(Message $response)
{
// The bank accepted the request as is.
if ($response->findRueckmeldung(Rueckmeldungscode::ENTGEGENGENOMMEN) !== null || $response->findRueckmeldung(Rueckmeldungscode::AUSGEFUEHRT) !== null) {
parent::processResponse($response);
return;
}

// The Bank does not want a separate HKVPA ("VoP Ausführungsauftrag").
if ($response->findRueckmeldung(Rueckmeldungscode::VOP_AUSFUEHRUNGSAUFTRAG_NICHT_BENOETIGT) !== null) {
parent::processResponse($response);
return;
}

if ($response->findRueckmeldung(Rueckmeldungscode::VOP_NAMENSABGLEICH_IST_NOCH_IN_BEARBEITUNG) !== null) {
$this->vopIsPending = true;
return;
}

// The user needs to check the result of the name check.
if ($response->findRueckmeldung(Rueckmeldungscode::VOP_ERGEBNIS_NAMENSABGLEICH_PRUEFEN) !== null) {

$this->vopNeedsConfirmation = true;
/** @var HIVPPv1 $hivpp */
$hivpp = $response->findSegment(HIVPPv1::class);

throw new UnsupportedException('The user needs to check the result of the name check. This is not implemented yet.');
}
}

public function needsTime()
{
return $this->vopIsPending;
}

public function needsConfirmation()
{
return $this->vopNeedsConfirmation;
}

}
10 changes: 10 additions & 0 deletions lib/Fhp/BaseAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ public function getTanRequest(): ?TanRequest
return $this->tanRequest;
}

public function needsConfirmation()
{
return false;
}

public function needsTime()
{
return false;
}

/**
* Throws an exception unless this action has been successfully executed, i.e. in the following cases:
* - the action has not been {@link FinTs::execute()}-d at all or the {@link FinTs::execute()} call for it threw an
Expand Down
10 changes: 10 additions & 0 deletions lib/Fhp/Segment/HIRMS/Rueckmeldungscode.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ public static function isError(int $code): bool
*/
public const PAGINATION = 3040;

public const VOP_KEINE_NAMENSABWEICHUNG = 0025;

public const VOP_ERGEBNIS_NAMENSABGLEICH_PRUEFEN = 3090;

public const VOP_AUSFUEHRUNGSAUFTRAG_NICHT_BENOETIGT = 3091;

public const VOP_NAMENSABGLEICH_IST_NOCH_IN_BEARBEITUNG = 3093;

public const VOP_NAMENSABGLEICH_IST_KOMPLETT = 3094;

/**
* Zugelassene Ein- und Zwei-Schritt-Verfahren für den Benutzer (+ Rückmeldungsparameter).
* The parameters reference the VerfahrensparameterZweiSchrittVerfahren.sicherheitsfunktion values (900..997) from
Expand Down
19 changes: 19 additions & 0 deletions lib/Fhp/Segment/VPP/ErgebnisVopPruefungEinzeltransaktion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Fhp\Segment\VPP;

class ErgebnisVopPruefungEinzeltransaktion
{
public string $ibanEmpfaenger;

public ?string $ibanZusatzinformationen = null;

public ?string $abweichenderEmpfängername = null;

public ?string $anderesIdentifikationmerkmal = null;

/** Allowed values: RVMC, RCVC, RVNM, RVNA, PDNG */
public string $vopPruefergebnis;

public ?string $grundRVNA = null;
}
16 changes: 16 additions & 0 deletions lib/Fhp/Segment/VPP/HIVPPSv1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Fhp\Segment\VPP;

use Fhp\Segment\BaseGeschaeftsvorfallparameter;

/**
* Segment: Namensabgleich Prüfauftrag Parameter
*
* @see FinTS_3.0_Messages_Geschaeftsvorfaelle_VOP_1.01_2025_06_27_FV.pdf
* Section: C.10.7.1 c)
*/
class HIVPPSv1 extends BaseGeschaeftsvorfallparameter
{
public ParameterNamensabgleichPruefauftrag $parameter;
}
33 changes: 33 additions & 0 deletions lib/Fhp/Segment/VPP/HIVPPv1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Fhp\Segment\VPP;

use Fhp\Segment\BaseSegment;
use Fhp\Segment\Common\Tsp;
use Fhp\Syntax\Bin;

/**
* Segment: Namensabgleich Prüfergebnis
*
* @see FinTS_3.0_Messages_Geschaeftsvorfaelle_VOP_1.01_2025_06_27_FV.pdf
* Section: C.10.7.1 b)
*/
class HIVPPv1 extends BaseSegment
{
public ?Bin $vopId = null;

public ?Tsp $vopIdGueltigBis = null;

public ?Bin $pollingId = null;

public ?string $paymentStatusReportDescriptor = null;

public ?Bin $paymentStatusReport = null;

public ?ErgebnisVopPruefungEinzeltransaktion $ergebnisVopPruefungEinzeltransaktion = null;

public ?string $aufklaerungstextAutorisierungTrotzAbweichung = null;

// This value is in seconds
public ?int $wartezeitVorNaechsterAbfrage = null;
}
25 changes: 25 additions & 0 deletions lib/Fhp/Segment/VPP/HKVPPv1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Fhp\Segment\VPP;

use Fhp\Segment\BaseSegment;
use Fhp\Syntax\Bin;

/**
* Segment: Namensabgleich Prüfauftrag
*
* @see FinTS_3.0_Messages_Geschaeftsvorfaelle_VOP_1.01_2025_06_27_FV.pdf
* Section: C.10.7.1 a)
*/
class HKVPPv1 extends BaseSegment
{
public UnterstuetztePaymentStatusReports $unterstuetztePaymentStatusReports;

public ?Bin $pollingId = null;

/** Only allowed if {@link ParameterNamensabgleichPruefauftrag::$eingabeAnzahlEintraegeErlaubt} says so. */
public ?int $maximaleAnzahlEintraege = null;

/** For pagination. Max length: 35 */
public ?string $aufsetzpunkt = null;
}
22 changes: 22 additions & 0 deletions lib/Fhp/Segment/VPP/ParameterNamensabgleichPruefauftrag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Fhp\Segment\VPP;

class ParameterNamensabgleichPruefauftrag
{
public int $maximaleAnzahlCreditTransferTransactionInformationOptIn;

public bool $aufklaerungstextStrukturiert;

/** Allowed values: V, S */
public string $artDerLieferungPaymentStatusReport;

public bool $sammelzahlungenMitEinemAuftragErlaubt;

public bool $eingabeAnzahlEintraegeErlaubt;

public string $unterstuetztePaymentStatusReportDatenformate;

/** @var string[] @Max(N) Max length each: 6 */
public array $vopPflichtigerZahlungsverkehrsauftrag;
}
11 changes: 11 additions & 0 deletions lib/Fhp/Segment/VPP/UnterstuetztePaymentStatusReports.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Fhp\Segment\VPP;

use Fhp\Segment\BaseDeg;

class UnterstuetztePaymentStatusReports extends BaseDeg
{
/** @var string[] @Max(99) Max length each: 256 */
public array $paymentStatusReportDescriptor;
}