-
Notifications
You must be signed in to change notification settings - Fork 37
Bill data validation
Before a QR bill payment part is generated, the bill data is validated and possibly modified to comply with the Swiss Implementation Guidelines QR-bill (IGQR). The validation returns:
- A list of messages (either errors or warnings)
- The bill data (possibly modified)
Each message consists of:
- Message key. The message key is a language-neutral key that specifies the error or warning. See below for all possible message keys.
- Field key. The field key refers to the affected field. See below for all possible field keys.
- Type. It is either error or warning. If the validation results in one or more errors, the payment part cannot be generated.
The validation can also be run independently from the payment part generation. In particular, it can also be run as part of decoding the text embedded in the QR code.
The following data modifications are made silently, i.e. without adding a message to the validation result:
- All text fields are trimmed, i.e. leading and trailing whitespace is removed.
- All text fields are normalized to Unicode Normalization Form C (NFC) before being converted to Latin 1. That way, German umlauts and accented characters represented by two combining code points are more likely to become valid characters.
Field | Modification | Remarks |
---|---|---|
IBAN | All whitespace removed | For the visible text on the payment part, spaces are inserted again to create groups of characters. |
Reference | All whitespace removed | For the visible text on the payment part, spaces are inserted again to create groups of characters. |
Reference | For QR references, leading 0s are added to increase the length to 27 characters | |
Currency | Converted to upper case | |
Amount | Rounded to a multiple of 0.01 CHF or EUR | |
Country | Converted to upper case |
The following modifications are made. For each affected field, a warning message is added to the validation result:
Message key | Error | Affected fields |
---|---|---|
replaced_unsupported_characters | Invalid characters have been replaced by either a space character (for invalid white space) or by a dot (for other invalid characters). | All text fields |
field_value_clipped | The field has been clipped to not exceed the maximum length | Unstructured message‡, all fields of creditors and debitors |
The following error messages are generated in case a validation fails:
Message key | Error | Affected fields |
---|---|---|
field_value_missing | The value is null or empty but the field is mandatory | Mandatory and dependent fields according to IGQR 4.3.3 |
field_value_too_long | The provided value exceeds the maximum length for this field | Bill information‡, alternative schemes data/instruction |
additional_info_too_long | The unstructured message and the bill information combined exceed the maximum length of 140 characters. This error is only generated if both fields are not empty. | bill information, unstructured message |
amount_outside_valid_range | The amount is either < 0.00 or > 999999999.99 | Amount |
currency_not_chf_or_eur | The currency is neither CHF nor EUR | Currency |
account_iban_not_from_ch_or_li | The IBAN does not start with CH or LI | IBAN |
account_iban_invalid | The IBAN is invalid: it uses invalid characters, has an invalid check digit or is not 21 characters long | IBAN |
ref_invalid | The reference is invalid. It is neither a valid QR reference nor a valid ISO 11640 reference. | Reference |
qr_ref_missing | QR reference is missing; it is mandatory for payments to a QR-IBAN account. | Reference |
cred_ref_invalid_use_for_qr_iban | For payments to a QR-IBAN account, a QR reference is required. An ISO 11649 reference may not be used. | Reference |
qr_ref_invalid_use_for_non_qr_iban | A QR reference is only allowed for payments to a QR-IBAN account. | Reference |
ref_type_invalid | Reference type should be one of "QRR", "SCOR" and "NON" and match the reference. | Reference type |
country_code_invalid | The country code is invalid. Expected format: two letters | Country of creditor and debitor |
address_type_conflict | In the creditor's and debtor's address, either the fields addressLine1 and addressLine2 are can be used or the fields street, houseNo, postalCode and town. Fields of both sets were used and therefore the address type (combined elements or structured) is conflicting. | Creditor and debitor |
alt_scheme_max_exceed | The maximum of two alternative schemes (procedures) has been exceeded | Alternative Schemes |
bill_info_invalid | The structured bill information is invalid. If provided, it must start with "//" and be at least 4 characters long. | Bill Information |
data_structure_invalid | The embedded QR code text has an invalid format | QR Type† |
version_unsupported | The embedded QR code text uses a version not supported by this library | Version† |
coding_type_unsupported | The embedded QR code text uses a coding type not supported by this library | Coding type† |
number_invalid | The amount is not a number (e.g. contains letters) | Amount† |
† Error messages marked with a dagger (†) can only occur when the embedded QR code text is parsed and validated. If the text has a completely invalid format, the message valid_data_structure is generated with a reference to the QR Type field.
‡ If both the unstructured message and the bill information are non empty, the combined length of 140 characters is checked and – if violated – two additional_info_too_long errors are raised. If the unstructured message is empty and the bill information is longer than 140 characters, the field_value_too_long error is raised. If the bill information is empty and the unstructured message exceeds 140 characters, it is truncated and the field_clipped warning is raised.
The creditor is mandatory and consists of eight fields. Out of this eight fields, name and country are mandatory and either addressLine2 or postalCode and town are mandatory. If the creditor is completely missing, five error messages will be added - one for each of the five mandatory fields.
The debtor is optional and consist of eight fields. If all the fields are empty or null, the debtor is assumed to be omitted and no error is generated. If a single field is not empty or null, then the debtor is assumed to be present and the five mandatory fields are checked: for each one that is empty or null, an error messages is added.
The specification says that line feeds are only allowed to separate lines but not at the end (cf 4.2.3). This is different from how a text editor usually saves text. It does not come as a surprise that QR bills with trailing line feeds have appeared. This library silently ignores the trailing line feeds even though they would be invalid.
Field | Field key |
---|---|
QR Type | qrText |
Version | version |
Coding type | codingType |
Currency | currency |
Amount | amount |
IBAN | account |
Creditor name | creditor.name |
Creditor street | creditor.addressLine1 |
Creditor house number | creditor.addressLine2 |
Creditor street | creditor.street |
Creditor house number | creditor.houseNo |
Creditor postal code | creditor.postalCode |
Creditor town | creditor.town |
Creditor country code | creditor.countryCode |
Reference | reference |
Reference type | referenceType |
Unstructured message | unstructuredMessage |
Bill information | billInformation |
Debtor name | debtor.name |
Debtor street | debtor.addressLine1 |
Debtor house number | debtor.addressLine2 |
Debtor street | debtor.street |
Debtor house number | debtor.houseNo |
Debtor postal code | debtor.postalCode |
Debtor town | debtor.town |
Debtor country code | debtor.countryCode |
Alternative Schemes | altSchemes |