Skip to content

Commit 743b52f

Browse files
bug #29755 Improved BIC + IBAN validator for some special cases (javiereguiluz)
This PR was squashed before being merged into the 4.3-dev branch (closes #29755). Discussion ---------- Improved BIC + IBAN validator for some special cases | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | - | License | MIT | Doc PR | - While blogging about [Improved Financial Constraints in Symfony 4.3](https://symfony.com/blog/new-in-symfony-4-3-improved-financial-constraints) I found this resource that mentions some exceptions when validating BIC + IBAN: https://wiki.xmldation.com/index.php?title=Support/EPC/IBAN_%26_BIC_relation I don't know if that resource is fully reliable ... but I checked it in the official "European Banking Resources" website (https://www.ecbs.org/iban/) and most of it matches, so I think we can safely make this change. Commits ------- 88a1696 Improved BIC + IBAN validator for some special cases
2 parents 3860d68 + 88a1696 commit 743b52f

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

src/Symfony/Component/Validator/Constraints/BicValidator.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@
2929
*/
3030
class BicValidator extends ConstraintValidator
3131
{
32+
private const BIC_COUNTRY_TO_IBAN_COUNTRY_MAP = array(
33+
// Reference: https://www.ecbs.org/iban/france-bank-account-number.html
34+
'GF' => 'FR', // French Guiana
35+
'PF' => 'FR', // French Polynesia
36+
'TF' => 'FR', // French Southern Territories
37+
'GP' => 'FR', // Guadeloupe
38+
'MQ' => 'FR', // Martinique
39+
'YT' => 'FR', // Mayotte
40+
'NC' => 'FR', // New Caledonia
41+
'RE' => 'FR', // Reunion
42+
'PM' => 'FR', // Saint Pierre and Miquelon
43+
'WF' => 'FR', // Wallis and Futuna Islands
44+
// Reference: https://www.ecbs.org/iban/united-kingdom-uk-bank-account-number.html
45+
'JE' => 'GB', // Jersey
46+
'IM' => 'GB', // Isle of Man
47+
'GG' => 'GB', // Guernsey
48+
'VG' => 'GB', // British Virgin Islands
49+
);
50+
3251
private $propertyAccessor;
3352

3453
public function __construct(PropertyAccessor $propertyAccessor = null)
@@ -126,7 +145,7 @@ public function validate($value, Constraint $constraint)
126145
return;
127146
}
128147
$ibanCountryCode = substr($iban, 0, 2);
129-
if (ctype_alpha($ibanCountryCode) && substr($canonicalize, 4, 2) !== $ibanCountryCode) {
148+
if (ctype_alpha($ibanCountryCode) && !$this->bicAndIbanCountriesMatch(substr($canonicalize, 4, 2), $ibanCountryCode)) {
130149
$this->context->buildViolation($constraint->ibanMessage)
131150
->setParameter('{{ value }}', $this->formatValue($value))
132151
->setParameter('{{ iban }}', $iban)
@@ -146,4 +165,9 @@ private function getPropertyAccessor(): PropertyAccessor
146165

147166
return $this->propertyAccessor;
148167
}
168+
169+
private function bicAndIbanCountriesMatch(string $bicCountryCode, string $ibanCountryCode): bool
170+
{
171+
return $ibanCountryCode === $bicCountryCode || $ibanCountryCode === (self::BIC_COUNTRY_TO_IBAN_COUNTRY_MAP[$bicCountryCode] ?? null);
172+
}
149173
}

src/Symfony/Component/Validator/Tests/Constraints/BicValidatorTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,41 @@ public function getInvalidBics()
221221
array('DEUTAT2lxxx', Bic::INVALID_CASE_ERROR),
222222
);
223223
}
224+
225+
/**
226+
* @dataProvider getValidBicSpecialCases
227+
*
228+
* Some territories have their own ISO country code but can use another country code
229+
* for IBAN accounts. Example: "French Guiana" (country code "GF") can use FR too.
230+
*/
231+
public function testValidBicSpecialCases(string $bic, string $iban)
232+
{
233+
$constraint = new Bic(array('iban' => $iban));
234+
$this->validator->validate($bic, $constraint);
235+
236+
$this->assertNoViolation();
237+
}
238+
239+
public function getValidBicSpecialCases()
240+
{
241+
// FR related special cases
242+
yield array('BNPAGFGX', 'FR14 2004 1010 0505 0001 3M02 606');
243+
yield array('BNPAPFGX', 'FR14 2004 1010 0505 0001 3M02 606');
244+
yield array('BNPATFGX', 'FR14 2004 1010 0505 0001 3M02 606');
245+
yield array('BNPAGPGX', 'FR14 2004 1010 0505 0001 3M02 606');
246+
yield array('BNPAMQGX', 'FR14 2004 1010 0505 0001 3M02 606');
247+
yield array('BNPAYTGX', 'FR14 2004 1010 0505 0001 3M02 606');
248+
yield array('BNPANCGX', 'FR14 2004 1010 0505 0001 3M02 606');
249+
yield array('BNPAREGX', 'FR14 2004 1010 0505 0001 3M02 606');
250+
yield array('BNPAPMGX', 'FR14 2004 1010 0505 0001 3M02 606');
251+
yield array('BNPAWFGX', 'FR14 2004 1010 0505 0001 3M02 606');
252+
253+
// GB related special cases
254+
yield array('BARCJESA', 'GB12 CPBK 0892 9965 0449 911');
255+
yield array('BARCIMSA', 'GB12 CPBK 0892 9965 0449 911');
256+
yield array('BARCGGSA', 'GB12 CPBK 0892 9965 0449 911');
257+
yield array('BARCVGSA', 'GB12 CPBK 0892 9965 0449 911');
258+
}
224259
}
225260

226261
class BicComparisonTestClass

0 commit comments

Comments
 (0)