Skip to content

Commit 9b93d6e

Browse files
authored
Merge pull request #291 from Cugar15/sepa-b2b
Added B2B support for SEPADirectDebit
2 parents 13c5ee8 + 5c91d2d commit 9b93d6e

28 files changed

+395
-73
lines changed

lib/Fhp/Action/GetSEPADirectDebitParameters.php

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,67 +5,74 @@
55
use Fhp\BaseAction;
66
use Fhp\Protocol\BPD;
77
use Fhp\Protocol\UPD;
8-
use Fhp\Segment\DME\HIDXES;
9-
use Fhp\Segment\DME\MinimaleVorlaufzeitSEPALastschrift;
8+
use Fhp\Segment\DSE\HIDXES;
9+
use Fhp\Segment\DSE\MinimaleVorlaufzeitSEPALastschrift;
1010

1111
/**
1212
* Retrieves information about SEPA Direct Debit Requests
1313
*/
1414
class GetSEPADirectDebitParameters extends BaseAction
1515
{
1616
const SEQUENCE_TYPES = ['FRST', 'OOFF', 'FNAL', 'RCUR'];
17-
const CORE_TYPES = ['CORE', 'COR1'];
17+
const DIRECT_DEBIT_TYPES = ['CORE', 'COR1', 'B2B'];
1818

1919
/** @var string */
20-
private $coreType;
20+
private $directDebitType;
2121

2222
/** @var string */
2323
private $seqType;
2424

2525
/** @var bool */
2626
private $singleDirectDebit;
2727

28-
/** @var MinimaleVorlaufzeitSEPALastschrift|null */
29-
private $minimalLeadTime;
28+
/** @var HIDXES */
29+
private $hidxes;
3030

31-
public static function create(string $seqType, bool $singleDirectDebit, string $coreType = 'CORE')
31+
public static function create(string $seqType, bool $singleDirectDebit, string $directDebitType = 'CORE')
3232
{
33-
if (!in_array($coreType, self::CORE_TYPES)) {
34-
throw new \InvalidArgumentException('Unknown CORE type, possible values are ' . implode(', ', self::CORE_TYPES));
33+
if (!in_array($directDebitType, self::DIRECT_DEBIT_TYPES)) {
34+
throw new \InvalidArgumentException('Unknown CORE type, possible values are ' . implode(', ', self::DIRECT_DEBIT_TYPES));
3535
}
3636
if (!in_array($seqType, self::SEQUENCE_TYPES)) {
3737
throw new \InvalidArgumentException('Unknown SEPA sequence type, possible values are ' . implode(', ', self::SEQUENCE_TYPES));
3838
}
3939
$result = new GetSEPADirectDebitParameters();
40-
$result->coreType = $coreType;
40+
$result->directDebitType = $directDebitType;
4141
$result->seqType = $seqType;
4242
$result->singleDirectDebit = $singleDirectDebit;
43-
4443
return $result;
4544
}
4645

46+
public static function getHixxesSegmentName(string $directDebitType, bool $singleDirectDebit): string
47+
{
48+
switch ($directDebitType) {
49+
case 'CORE':
50+
case 'COR1':
51+
return $singleDirectDebit ? 'HIDSES' : 'HIDMES';
52+
case 'B2B':
53+
return $singleDirectDebit ? 'HIBSES' : 'HIBMES';
54+
default:
55+
throw new \InvalidArgumentException('Unknown DirectDebitTypes type, possible values are ' . implode(', ', self::DIRECT_DEBIT_TYPES));
56+
}
57+
}
58+
4759
/** {@inheritdoc} */
4860
protected function createRequest(BPD $bpd, ?UPD $upd)
4961
{
50-
$type = $this->singleDirectDebit ? 'HIDSES' : 'HIDMES';
51-
52-
/** @var HIDXES $hidxes */
53-
$hidxes = $bpd->requireLatestSupportedParameters($type);
54-
55-
$this->minimalLeadTime = $hidxes->getParameter()->getMinimalLeadTime($this->seqType, $this->coreType);
56-
62+
$this->hidxes = $bpd->requireLatestSupportedParameters(static::getHixxesSegmentName($this->directDebitType, $this->singleDirectDebit));
5763
$this->isDone = true;
58-
59-
// No request to the bank required
60-
return [];
64+
return []; // No request to the bank required
6165
}
6266

6367
/**
64-
* @return MinimaleVorlaufzeitSEPALastschrift|null The information about the lead time for the given Sequence Type and Core Type
68+
* @return MinimaleVorlaufzeitSEPALastschrift|null The information about the lead time for the given Sequence Type and Direct Debit Type
6569
*/
6670
public function getMinimalLeadTime(): ?MinimaleVorlaufzeitSEPALastschrift
6771
{
68-
//$this->ensureDone();
69-
return $this->minimalLeadTime;
72+
$parsed = $this->hidxes->getParameter()->getMinimalLeadTime($this->seqType);
73+
if ($parsed instanceof MinimaleVorlaufzeitSEPALastschrift) {
74+
return $parsed;
75+
}
76+
return $parsed[$this->directDebitType] ?? null;
7077
}
7178
}

lib/Fhp/Action/SendSEPADirectDebit.php

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,8 @@
1111
use Fhp\Segment\Common\Kti;
1212
use Fhp\Segment\DME\HIDMESv1;
1313
use Fhp\Segment\DME\HIDMESv2;
14-
use Fhp\Segment\DME\HIDXES;
15-
use Fhp\Segment\DME\HKDMEv1;
16-
use Fhp\Segment\DME\HKDMEv2;
1714
use Fhp\Segment\DSE\HIDSESv2;
18-
use Fhp\Segment\DSE\HKDSEv1;
19-
use Fhp\Segment\DSE\HKDSEv2;
15+
use Fhp\Segment\DSE\HIDXES;
2016
use Fhp\Segment\SPA\HISPAS;
2117
use Fhp\Syntax\Bin;
2218
use Fhp\UnsupportedException;
@@ -44,6 +40,9 @@ class SendSEPADirectDebit extends BaseAction
4440
/** @var bool */
4541
protected $tryToUseControlSumForSingleTransactions = false;
4642

43+
/** @var string */
44+
private $coreType;
45+
4746
public static function create(SEPAAccount $account, string $painMessage, bool $tryToUseControlSumForSingleTransactions = false): SendSEPADirectDebit
4847
{
4948
if (preg_match('/xmlns="(?<namespace>[^"]+)"/s', $painMessage, $matches) === 1) {
@@ -56,10 +55,16 @@ public static function create(SEPAAccount $account, string $painMessage, bool $t
5655
$nbOfTxs = substr_count($painMessage, '<DrctDbtTxInf>');
5756
$ctrlSum = null;
5857

59-
if (preg_match('/<GrpHdr>.*<CtrlSum>(?<ctrlsum>[.0-9]+)<\/CtrlSum>.*<\/GrpHdr>/s', $painMessage, $matches) === 1) {
58+
if (preg_match('@<GrpHdr>.*<CtrlSum>(?<ctrlsum>[.0-9]+)</CtrlSum>.*</GrpHdr>@s', $painMessage, $matches) === 1) {
6059
$ctrlSum = $matches['ctrlsum'];
6160
}
6261

62+
if (preg_match('@<PmtTpInf>.*<LclInstrm>.*<Cd>(?<coretype>CORE|COR1|B2B)</Cd>.*</LclInstrm>.*</PmtTpInf>@s', $painMessage, $matches) === 1) {
63+
$coreType = $matches['coretype'];
64+
} else {
65+
throw new \InvalidArgumentException('The type CORE/COR1/B2B is missing in PAIN message');
66+
}
67+
6368
if ($nbOfTxs > 1 && is_null($ctrlSum)) {
6469
throw new \InvalidArgumentException('The control sum aka "<GrpHdr><CtrlSum>xx</CtrlSum></GrpHdr>" is missing in PAIN message');
6570
}
@@ -69,6 +74,7 @@ public static function create(SEPAAccount $account, string $painMessage, bool $t
6974
$result->painMessage = $painMessage;
7075
$result->painNamespace = $painNamespace;
7176
$result->ctrlSum = $ctrlSum;
77+
$result->coreType = $coreType;
7278

7379
$result->singleDirectDebit = $nbOfTxs === 1;
7480

@@ -86,8 +92,8 @@ protected function createRequest(BPD $bpd, ?UPD $upd)
8692
$useSingleDirectDebit = false;
8793
}
8894

89-
/** @var HIDXES|BaseSegment $hidxes */
90-
$hidxes = $bpd->requireLatestSupportedParameters($useSingleDirectDebit ? 'HIDSES' : 'HIDMES');
95+
/* @var HIDXES|BaseSegment $hidxes */
96+
$hidxes = $bpd->requireLatestSupportedParameters(GetSEPADirectDebitParameters::getHixxesSegmentName($this->coreType, $useSingleDirectDebit));
9197

9298
$supportedPainNamespaces = null;
9399

@@ -108,19 +114,8 @@ protected function createRequest(BPD $bpd, ?UPD $upd)
108114
. implode(', ', $supportedPainNamespaces));
109115
}
110116

111-
/** @var HKDMEv1|HKDSEv1 $hkdxe */
112-
$hkdxe = null;
113-
switch ($hidxes->getVersion()) {
114-
case 1:
115-
$hkdxe = $useSingleDirectDebit ? HKDSEv1::createEmpty() : HKDMEv1::createEmpty();
116-
break;
117-
case 2:
118-
$hkdxe = $useSingleDirectDebit ? HKDSEv2::createEmpty() : HKDMEv2::createEmpty();
119-
break;
120-
default:
121-
throw new UnsupportedException('Unsupported HKDME or HKDSE version: ' . $hidxes->getVersion());
122-
}
123-
117+
/** @var mixed $hkdxe */ // TODO Put a new interface type here.
118+
$hkdxe = $hidxes->createRequestSegment();
124119
$hkdxe->kontoverbindungInternational = Kti::fromAccount($this->account);
125120
$hkdxe->sepaDescriptor = $this->painNamespace;
126121
$hkdxe->sepaPainMessage = new Bin($this->painMessage);

lib/Fhp/Model/StatementOfAccount/Transaction.php

100755100644
File mode changed.

lib/Fhp/Segment/BME/HIBMESv1.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Fhp\Segment\BME;
4+
5+
use Fhp\Segment\BaseGeschaeftsvorfallparameter;
6+
use Fhp\Segment\BaseSegment;
7+
use Fhp\Segment\DSE\HIDXES;
8+
use Fhp\Segment\DSE\SEPADirectDebitMinimalLeadTimeProvider;
9+
10+
/**
11+
* Segment: Terminierte SEPA-Sammellastschrift einreichen Parameter
12+
*
13+
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
14+
* Section: C.10.3.3.2.1 c)
15+
*/
16+
class HIBMESv1 extends BaseGeschaeftsvorfallparameter implements HIDXES
17+
{
18+
/** @var ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV1 */
19+
public $parameter;
20+
21+
public function getParameter(): SEPADirectDebitMinimalLeadTimeProvider
22+
{
23+
return $this->parameter;
24+
}
25+
26+
public function createRequestSegment(): BaseSegment
27+
{
28+
return HKBMEv1::createEmpty();
29+
}
30+
}

lib/Fhp/Segment/BME/HIBMESv2.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Fhp\Segment\BME;
4+
5+
use Fhp\Segment\BaseGeschaeftsvorfallparameter;
6+
use Fhp\Segment\BaseSegment;
7+
use Fhp\Segment\DSE\HIDXES;
8+
use Fhp\Segment\DSE\SEPADirectDebitMinimalLeadTimeProvider;
9+
10+
/**
11+
* Segment: Terminierte SEPA-Sammellastschrift einreichen Parameter
12+
*
13+
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
14+
* Section: C.10.3.3.2.1 c)
15+
*/
16+
class HIBMESv2 extends BaseGeschaeftsvorfallparameter implements HIDXES
17+
{
18+
/** @var ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV2 */
19+
public $parameter;
20+
21+
public function getParameter(): SEPADirectDebitMinimalLeadTimeProvider
22+
{
23+
return $this->parameter;
24+
}
25+
26+
public function createRequestSegment(): BaseSegment
27+
{
28+
return HKBMEv2::createEmpty();
29+
}
30+
}

lib/Fhp/Segment/BME/HKBMEv1.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Fhp\Segment\BME;
4+
5+
use Fhp\Segment\DME\HKDMEv1;
6+
7+
/**
8+
* Einreichung terminierter SEPA-Sammellastschrift (Segmentversion 1)
9+
*
10+
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
11+
* Section: C.10.3.3.2.1
12+
*/
13+
class HKBMEv1 extends HKDMEv1
14+
{
15+
}

lib/Fhp/Segment/BME/HKBMEv2.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Fhp\Segment\BME;
4+
5+
/**
6+
* Einreichung terminierter SEPA-Sammellastschrift (Segmentversion 2)
7+
*
8+
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
9+
* Section: C.10.3.3.2.2
10+
*/
11+
class HKBMEv2 extends HKBMEv1
12+
{
13+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Fhp\Segment\BME;
4+
5+
use Fhp\Segment\BSE\ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV1;
6+
7+
class ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV1 extends ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV1
8+
{
9+
/** @var int */
10+
public $maximaleAnzahlDirectDebitTransferTransactionInformation;
11+
12+
/** @var bool */
13+
public $summenfeldBenoetigt;
14+
15+
/** @var bool */
16+
public $einzelbuchungErlaubt;
17+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Fhp\Segment\BME;
4+
5+
use Fhp\Segment\BSE\ParameterTerminierteSEPAFirmenLastschriftEinreichenV2;
6+
7+
class ParameterTerminierteSEPAFirmenSammellastschriftEinreichenV2 extends ParameterTerminierteSEPAFirmenLastschriftEinreichenV2
8+
{
9+
/** @var int */
10+
public $maximaleAnzahlDirectDebitTransferTransactionInformation;
11+
12+
/** @var bool */
13+
public $summenfeldBenoetigt;
14+
15+
/** @var bool */
16+
public $einzelbuchungErlaubt;
17+
18+
/** @var string|null Max Length: 4096 */
19+
public $zulaessigePurposecodes;
20+
21+
/** @var string[]|null @Max(9) Max Length: 256 */
22+
public $unterstuetzteSEPADatenformate;
23+
}

lib/Fhp/Segment/BSE/HIBSESv1.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Fhp\Segment\BSE;
4+
5+
use Fhp\Segment\BaseGeschaeftsvorfallparameter;
6+
use Fhp\Segment\BaseSegment;
7+
use Fhp\Segment\DSE\HIDXES;
8+
use Fhp\Segment\DSE\SEPADirectDebitMinimalLeadTimeProvider;
9+
10+
/**
11+
* Segment: Terminierte SEPA-Einzellastschrift einreichen Parameter
12+
*
13+
* @link https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
14+
* Section: C.10.2.6.2.1 c)
15+
*/
16+
class HIBSESv1 extends BaseGeschaeftsvorfallparameter implements HIDXES
17+
{
18+
/** @var ParameterTerminierteSEPAFirmenEinzellastschriftEinreichenV1 */
19+
public $parameter;
20+
21+
public function getParameter(): SEPADirectDebitMinimalLeadTimeProvider
22+
{
23+
return $this->parameter;
24+
}
25+
26+
public function createRequestSegment(): BaseSegment
27+
{
28+
return HKBSEv1::createEmpty();
29+
}
30+
}

0 commit comments

Comments
 (0)