Packages
ukraine_nbuqr
0.1.0
Library for generation National Bank of Ukraine payment Quick Response Codes
Current section
Files
Jump to
Current section
Files
lib/qr.ex
defmodule UkraineNbuqrEx.Qr do
@moduledoc """
This module is designed to generate Payment QR codes according to the National Bank of Ukraine (NBU) QR code standard.
"""
alias UkraineNbuqrEx.Qr.{Config, Encoding, Version}
alias UkraineNbuqrEx.QrData
import UkraineNbuqrEx.Commons, only: [ok: 1]
@default_options [
background_color: :transparent
]
@type output_data :: {:error, String.t()} | {:ok, String.t()}
@type input_data :: output_data | String.t()
@doc """
`to_string/2` converts QR data struct to string representation of open data of invoice
Combines QR data struct (service label, version, encoding, function, recipient, IBAN, amount, tax ID, purpose) into a string representation with newline separators.
Takes optional formatting options:
- **encoding** specifies encoding (defaults to value from Config.encoding())
- **version** specifies version (defaults to value from Config.version())
"""
@spec to_string(data :: QrData.t(), options :: Keyword.t()) :: output_data
def to_string(data, options \\ @default_options)
def to_string(data, options) do
encoding = Encoding.encoding(Keyword.get(options, :encoding, Config.encoding()))
version = Version.normalize(Keyword.get(options, :version, Config.version()))
[
Config.service_label(),
version,
encoding,
Config.function(),
"",
data.recipient,
data.iban,
data.amount,
data.tax_id,
"",
"",
data.purpose
]
|> Enum.join("\n")
|> ok()
end
@doc """
`encode/1` encodes the invoice string to Base64 format uses URL-safe Base64 encoding without padding
"""
@spec encode(data :: input_data()) :: output_data
def encode({:error, _error} = negative), do: negative
def encode({:ok, data}), do: encode(data)
def encode(data) do
data
|> Base.url_encode64(padding: false)
|> ok()
end
@doc """
Generates a complete QR link with encoded invoice data
"""
@spec to_link(encoded :: input_data()) :: output_data
def to_link({:error, _error} = negative), do: negative
def to_link({:ok, encoded}), do: to_link(encoded)
def to_link(encoded) do
ok(Config.base_url() <> encoded)
end
@doc """
`to_qr/2` generates a QR from the given data and options.
**format** option specifies the function for formatiing QR code.
The default is &Config.svg/2. Complete list of format functions returns by Config.formats:
- **&Config.svg/2** generates an SVG image
- **&Config.png/2** generates a PNG image
- **&Config.ascii/2** generates a text representation of the QR code
Available options for all formats:
- **color** in hexadecimal format. The default is #000
- **background_color** in hexadecimal format or :transparent. The default is #FFF.
- **width** the width of the QR code in pixel. Without the width attribute, the QR code size will be dynamically generated based on the input string.
Options avaliable for SVG format:
- **shape** only square or circle. The default is square
- **viewbox** when set to true, the SVG element will specify its height and width using viewBox, instead of explicit height and width tags.
Default options are
```elixir
[color: "#000", shape: "square", background_color: "#FFF"]
```
"""
@spec to_qr(link :: input_data(), options :: Keyword.t()) :: output_data
def to_qr(data, options \\ @default_options)
def to_qr({:error, _error} = negative, _options), do: negative
def to_qr({:ok, link}, options), do: to_qr(link, options)
def to_qr(link, options) do
format = Keyword.get(options, :format, &Config.default_format/2)
link
|> EQRCode.encode()
|> format.(options)
|> ok()
end
@doc """
Generates a QR code from the given data and options.
As opttions it accepts the same options as to_qr/2 and to_string/2 functions.
"""
@spec create(data :: QrData.t(), options :: Keyword.t()) :: output_data
def create(data, options \\ @default_options)
def create(data, options) do
data
|> __MODULE__.to_string(options)
|> encode()
|> to_link()
|> to_qr(options)
end
end