diff --git a/QRCoder/PayloadGenerator.cs b/QRCoder/PayloadGenerator.cs
index acc9d45d..ce465401 100644
--- a/QRCoder/PayloadGenerator.cs
+++ b/QRCoder/PayloadGenerator.cs
@@ -65,6 +65,18 @@ private static bool IsValidQRIban(string iban)
private static bool IsValidBic(string bic)
=> Regex.IsMatch(bic.Replace(" ", ""), @"^([a-zA-Z]{4}[a-zA-Z]{2}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?)$");
+ ///
+ /// Validates the structure of a BIC with optional requirement check.
+ ///
+ /// The BIC to validate.
+ /// Whether the BIC is required. If false, null/empty values are considered valid.
+ /// True if the BIC is valid; otherwise, false.
+ private static bool IsValidBic(string? bic, bool required)
+ {
+ if (string.IsNullOrEmpty(bic))
+ return !required;
+ return IsValidBic(bic!);
+ }
///
/// Converts a string to a specified encoding.
diff --git a/QRCoder/PayloadGenerator/Girocode.cs b/QRCoder/PayloadGenerator/Girocode.cs
index 66d4a7a7..54c06671 100644
--- a/QRCoder/PayloadGenerator/Girocode.cs
+++ b/QRCoder/PayloadGenerator/Girocode.cs
@@ -36,16 +36,16 @@ public class Girocode : Payload
/// Girocode version. Either 001 or 002. Default: 001.
/// Encoding of the Girocode payload. Default: ISO-8859-1
/// Thrown when the input values are not valid according to the Girocode specification.
- public Girocode(string iban, string bic, string name, decimal amount, string remittanceInformation = "", TypeOfRemittance typeOfRemittance = TypeOfRemittance.Unstructured, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", GirocodeVersion version = GirocodeVersion.Version1, GirocodeEncoding encoding = GirocodeEncoding.ISO_8859_1)
+ public Girocode(string iban, string? bic, string name, decimal amount, string remittanceInformation = "", TypeOfRemittance typeOfRemittance = TypeOfRemittance.Unstructured, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", GirocodeVersion version = GirocodeVersion.Version1, GirocodeEncoding encoding = GirocodeEncoding.ISO_8859_1)
{
_version = version;
_encoding = encoding;
if (!IsValidIban(iban))
throw new GirocodeException("The IBAN entered isn't valid.");
_iban = iban.Replace(" ", "").ToUpper();
- if (!IsValidBic(bic))
+ if (!IsValidBic(bic, _version == GirocodeVersion.Version1))
throw new GirocodeException("The BIC entered isn't valid.");
- _bic = bic.Replace(" ", "").ToUpper();
+ _bic = bic?.Replace(" ", "").ToUpper() ?? string.Empty;
if (name.Length > 70)
throw new GirocodeException("(Payee-)Name must be shorter than 71 chars.");
_name = name;
diff --git a/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20+netstandard21/QRCoder.approved.txt b/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20+netstandard21/QRCoder.approved.txt
index ef3ca5d7..a700b557 100644
--- a/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20+netstandard21/QRCoder.approved.txt
+++ b/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20+netstandard21/QRCoder.approved.txt
@@ -456,7 +456,7 @@ namespace QRCoder
}
public class Girocode : QRCoder.PayloadGenerator.Payload
{
- public Girocode(string iban, string bic, string name, decimal amount, string remittanceInformation = "", QRCoder.PayloadGenerator.Girocode.TypeOfRemittance typeOfRemittance = 1, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", QRCoder.PayloadGenerator.Girocode.GirocodeVersion version = 0, QRCoder.PayloadGenerator.Girocode.GirocodeEncoding encoding = 1) { }
+ public Girocode(string iban, string? bic, string name, decimal amount, string remittanceInformation = "", QRCoder.PayloadGenerator.Girocode.TypeOfRemittance typeOfRemittance = 1, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", QRCoder.PayloadGenerator.Girocode.GirocodeVersion version = 0, QRCoder.PayloadGenerator.Girocode.GirocodeEncoding encoding = 1) { }
public override QRCoder.QRCodeGenerator.ECCLevel EccLevel { get; }
public override string ToString() { }
public enum GirocodeEncoding
diff --git a/QRCoderApiTests/net60-windows/QRCoder.approved.txt b/QRCoderApiTests/net60-windows/QRCoder.approved.txt
index 10d94672..d50a8826 100644
--- a/QRCoderApiTests/net60-windows/QRCoder.approved.txt
+++ b/QRCoderApiTests/net60-windows/QRCoder.approved.txt
@@ -461,7 +461,7 @@ namespace QRCoder
}
public class Girocode : QRCoder.PayloadGenerator.Payload
{
- public Girocode(string iban, string bic, string name, decimal amount, string remittanceInformation = "", QRCoder.PayloadGenerator.Girocode.TypeOfRemittance typeOfRemittance = 1, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", QRCoder.PayloadGenerator.Girocode.GirocodeVersion version = 0, QRCoder.PayloadGenerator.Girocode.GirocodeEncoding encoding = 1) { }
+ public Girocode(string iban, string? bic, string name, decimal amount, string remittanceInformation = "", QRCoder.PayloadGenerator.Girocode.TypeOfRemittance typeOfRemittance = 1, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", QRCoder.PayloadGenerator.Girocode.GirocodeVersion version = 0, QRCoder.PayloadGenerator.Girocode.GirocodeEncoding encoding = 1) { }
public override QRCoder.QRCodeGenerator.ECCLevel EccLevel { get; }
public override string ToString() { }
public enum GirocodeEncoding
diff --git a/QRCoderApiTests/net60/QRCoder.approved.txt b/QRCoderApiTests/net60/QRCoder.approved.txt
index 76a2b1aa..1db2dc0a 100644
--- a/QRCoderApiTests/net60/QRCoder.approved.txt
+++ b/QRCoderApiTests/net60/QRCoder.approved.txt
@@ -419,7 +419,7 @@ namespace QRCoder
}
public class Girocode : QRCoder.PayloadGenerator.Payload
{
- public Girocode(string iban, string bic, string name, decimal amount, string remittanceInformation = "", QRCoder.PayloadGenerator.Girocode.TypeOfRemittance typeOfRemittance = 1, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", QRCoder.PayloadGenerator.Girocode.GirocodeVersion version = 0, QRCoder.PayloadGenerator.Girocode.GirocodeEncoding encoding = 1) { }
+ public Girocode(string iban, string? bic, string name, decimal amount, string remittanceInformation = "", QRCoder.PayloadGenerator.Girocode.TypeOfRemittance typeOfRemittance = 1, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", QRCoder.PayloadGenerator.Girocode.GirocodeVersion version = 0, QRCoder.PayloadGenerator.Girocode.GirocodeEncoding encoding = 1) { }
public override QRCoder.QRCodeGenerator.ECCLevel EccLevel { get; }
public override string ToString() { }
public enum GirocodeEncoding
diff --git a/QRCoderApiTests/netstandard13/QRCoder.approved.txt b/QRCoderApiTests/netstandard13/QRCoder.approved.txt
index 5c13586a..d8a1d7e6 100644
--- a/QRCoderApiTests/netstandard13/QRCoder.approved.txt
+++ b/QRCoderApiTests/netstandard13/QRCoder.approved.txt
@@ -399,7 +399,7 @@ namespace QRCoder
}
public class Girocode : QRCoder.PayloadGenerator.Payload
{
- public Girocode(string iban, string bic, string name, decimal amount, string remittanceInformation = "", QRCoder.PayloadGenerator.Girocode.TypeOfRemittance typeOfRemittance = 1, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", QRCoder.PayloadGenerator.Girocode.GirocodeVersion version = 0, QRCoder.PayloadGenerator.Girocode.GirocodeEncoding encoding = 1) { }
+ public Girocode(string iban, string? bic, string name, decimal amount, string remittanceInformation = "", QRCoder.PayloadGenerator.Girocode.TypeOfRemittance typeOfRemittance = 1, string purposeOfCreditTransfer = "", string messageToGirocodeUser = "", QRCoder.PayloadGenerator.Girocode.GirocodeVersion version = 0, QRCoder.PayloadGenerator.Girocode.GirocodeEncoding encoding = 1) { }
public override QRCoder.QRCodeGenerator.ECCLevel EccLevel { get; }
public override string ToString() { }
public enum GirocodeEncoding
diff --git a/QRCoderTests/PayloadGeneratorTests/GirocodeTests.cs b/QRCoderTests/PayloadGeneratorTests/GirocodeTests.cs
index 82df3eac..95d40c6d 100644
--- a/QRCoderTests/PayloadGeneratorTests/GirocodeTests.cs
+++ b/QRCoderTests/PayloadGeneratorTests/GirocodeTests.cs
@@ -321,4 +321,138 @@ public void girocode_generator_sets_encoding_parameters()
payload.EciMode.ShouldBe(EciMode.Default);
payload.Version.ShouldBe(-1);
}
+
+ [Fact]
+ public void girocode_generator_version2_with_null_bic_should_succeed()
+ {
+ var iban = "NL86INGB0002445588";
+ var name = "a name";
+ var remittanceInformation = "some info";
+ var amount = 1337.99m;
+
+ var payload = new PayloadGenerator.Girocode(
+ iban: iban,
+ bic: null,
+ name: name,
+ amount: amount,
+ remittanceInformation: remittanceInformation,
+ version: PayloadGenerator.Girocode.GirocodeVersion.Version2,
+ encoding: PayloadGenerator.Girocode.GirocodeEncoding.UTF_8);
+
+ payload
+ .ToString()
+ .ShouldBe("BCD\n002\n1\nSCT\n\na name\nNL86INGB0002445588\nEUR1337.99\n\n\nsome info\n");
+ }
+
+ [Fact]
+ public void girocode_generator_version2_with_empty_bic_should_succeed()
+ {
+ var iban = "NL86INGB0002445588";
+ var name = "a name";
+ var remittanceInformation = "some info";
+ var amount = 1337.99m;
+
+ var payload = new PayloadGenerator.Girocode(
+ iban: iban,
+ bic: string.Empty,
+ name: name,
+ amount: amount,
+ remittanceInformation: remittanceInformation,
+ version: PayloadGenerator.Girocode.GirocodeVersion.Version2,
+ encoding: PayloadGenerator.Girocode.GirocodeEncoding.UTF_8);
+
+ payload
+ .ToString()
+ .ShouldBe("BCD\n002\n1\nSCT\n\na name\nNL86INGB0002445588\nEUR1337.99\n\n\nsome info\n");
+ }
+
+ [Fact]
+ public void girocode_generator_version2_with_valid_bic_should_succeed()
+ {
+ var iban = "NL86INGB0002445588";
+ var bic = "INGBNL2A";
+ var name = "a name";
+ var remittanceInformation = "some info";
+ var amount = 1337.99m;
+
+ var payload = new PayloadGenerator.Girocode(
+ iban: iban,
+ bic: bic,
+ name: name,
+ amount: amount,
+ remittanceInformation: remittanceInformation,
+ version: PayloadGenerator.Girocode.GirocodeVersion.Version2,
+ encoding: PayloadGenerator.Girocode.GirocodeEncoding.UTF_8);
+
+ payload
+ .ToString()
+ .ShouldBe("BCD\n002\n1\nSCT\nINGBNL2A\na name\nNL86INGB0002445588\nEUR1337.99\n\n\nsome info\n");
+ }
+
+ [Fact]
+ public void girocode_generator_version2_with_invalid_bic_should_throw_exception()
+ {
+ var iban = "NL86INGB0002445588";
+ var bic = "INVALID";
+ var name = "a name";
+ var remittanceInformation = "some info";
+ var amount = 1337.99m;
+
+ var exception = Record.Exception(() => new PayloadGenerator.Girocode(
+ iban: iban,
+ bic: bic,
+ name: name,
+ amount: amount,
+ remittanceInformation: remittanceInformation,
+ version: PayloadGenerator.Girocode.GirocodeVersion.Version2,
+ encoding: PayloadGenerator.Girocode.GirocodeEncoding.UTF_8));
+
+ Assert.NotNull(exception);
+ Assert.IsType(exception);
+ exception.Message.ShouldBe("The BIC entered isn't valid.");
+ }
+
+ [Fact]
+ public void girocode_generator_version1_with_null_bic_should_throw_exception()
+ {
+ var iban = "NL86INGB0002445588";
+ var name = "a name";
+ var remittanceInformation = "some info";
+ var amount = 1337.99m;
+
+ var exception = Record.Exception(() => new PayloadGenerator.Girocode(
+ iban: iban,
+ bic: null,
+ name: name,
+ amount: amount,
+ remittanceInformation: remittanceInformation,
+ version: PayloadGenerator.Girocode.GirocodeVersion.Version1,
+ encoding: PayloadGenerator.Girocode.GirocodeEncoding.UTF_8));
+
+ Assert.NotNull(exception);
+ Assert.IsType(exception);
+ exception.Message.ShouldBe("The BIC entered isn't valid.");
+ }
+
+ [Fact]
+ public void girocode_generator_version1_with_empty_bic_should_throw_exception()
+ {
+ var iban = "NL86INGB0002445588";
+ var name = "a name";
+ var remittanceInformation = "some info";
+ var amount = 1337.99m;
+
+ var exception = Record.Exception(() => new PayloadGenerator.Girocode(
+ iban: iban,
+ bic: string.Empty,
+ name: name,
+ amount: amount,
+ remittanceInformation: remittanceInformation,
+ version: PayloadGenerator.Girocode.GirocodeVersion.Version1,
+ encoding: PayloadGenerator.Girocode.GirocodeEncoding.UTF_8));
+
+ Assert.NotNull(exception);
+ Assert.IsType(exception);
+ exception.Message.ShouldBe("The BIC entered isn't valid.");
+ }
}