View Source QRNBU.Version behaviour (NBU payment QR v0.3.3)

Behaviour definition for NBU QR code version implementations.

This behaviour defines the contract that all version modules (V001, V002, V003) must implement. It ensures consistency across different QR code formats while allowing version-specific implementations.

Implementing Modules

  • QRNBU.V001 - Legacy format (9 fields)
  • QRNBU.V002 - URL-based format (9 fields)
  • QRNBU.V003 - Latest format (17 fields)

Callbacks

All version modules must implement:

  • version_number/0 - Returns the version number (1, 2, or 3)
  • validate/1 - Validates struct data according to version rules
  • to_data_string/2 - Converts struct to NBU-formatted string
  • from_data_string/2 - Parses NBU-formatted string to struct (optional for V001/V002)

Examples

defmodule QRNBU.V002 do
  @behaviour QRNBU.Version

  def version_number, do: 2

  def validate(%__MODULE__{} = data) do
    # Validation logic
  end

  def to_data_string(%__MODULE__{} = data, opts) do
    # Formatting logic
  end
end

Summary

Callbacks

Parses an NBU-formatted string back into struct data.

Converts struct data to NBU-formatted string ready for QR encoding.

Validates the struct data according to NBU specification for this version.

Returns the version number for this implementation.

Functions

Helper function to determine version from version number.

Helper to convert data to string using the appropriate version module.

Helper to validate data using the appropriate version module.

Types

@type error() :: {:error, String.t() | [String.t()]}
@type options() :: keyword()
@type version_data() :: struct()

Callbacks

Link to this callback

from_data_string(t, options)

View Source (optional)
@callback from_data_string(String.t(), options()) :: {:ok, version_data()} | error()

Parses an NBU-formatted string back into struct data.

Optional callback - primarily needed for V003 decoding. V001/V002 may implement basic parsing for compatibility.

Options may include:

  • :encoding - Expected character encoding
  • :strict - Whether to enforce strict validation (default: true)

Returns {:ok, struct} with parsed data, or {:error, reason} if parsing fails.

Link to this callback

to_data_string(version_data, options)

View Source
@callback to_data_string(version_data(), options()) :: {:ok, String.t()} | error()

Converts struct data to NBU-formatted string ready for QR encoding.

Options may include:

  • :encoding - :utf8 or :cp1251 (default: :utf8)
  • :format - :raw or :url (V002/V003 only, default: :url)
  • :line_ending - :crlf or :lf (auto-detected from version by default)

Returns {:ok, data_string} with formatted QR data, or {:error, reason} if formatting fails.

@callback validate(version_data()) :: {:ok, version_data()} | error()

Validates the struct data according to NBU specification for this version.

Should validate:

  • Required fields are present
  • Field lengths are within limits
  • Field formats are correct (IBAN, amounts, etc.)
  • Version-specific constraints (e.g., ICT only in V003)

Returns {:ok, validated_data} with potentially normalized data, or {:error, reasons} with validation error messages.

@callback version_number() :: 1 | 2 | 3

Returns the version number for this implementation.

Must return 1 for V001, 2 for V002, or 3 for V003.

Functions

Link to this function

module_for_version(version)

View Source
@spec module_for_version(pos_integer()) :: {:ok, module()} | {:error, String.t()}

Helper function to determine version from version number.

Examples

iex> QRNBU.Version.module_for_version(1)
{:ok, QRNBU.Versions.V001}

iex> QRNBU.Version.module_for_version(2)
{:ok, QRNBU.Versions.V002}

iex> QRNBU.Version.module_for_version(3)
{:ok, QRNBU.Versions.V003}

iex> {:error, msg} = QRNBU.Version.module_for_version(4)
iex> String.contains?(msg, "Unsupported version: 4")
true
Link to this function

to_data_string(data, opts \\ [])

View Source
@spec to_data_string(version_data(), options()) :: {:ok, String.t()} | error()

Helper to convert data to string using the appropriate version module.

Automatically determines which version module to use based on struct type.

See individual version module tests for examples.

@spec validate(version_data()) :: {:ok, version_data()} | error()

Helper to validate data using the appropriate version module.

Automatically determines which version module to use based on struct type.

See individual version module tests for examples.