Brasilex.Boleto (Brasilex v0.3.0)

Copy Markdown View Source

Represents a parsed Brazilian boleto (bank slip).

Fields

  • :type - Either :banking (bank collection) or :convenio (utility/tax)
  • :raw - Original linha digitável string (sanitized, digits only)
  • :barcode - 44-digit barcode representation
  • :bank_code - 3-digit bank code (banking boletos only)
  • :currency_code - Currency indicator (banking: "9" = BRL)
  • :amount - Amount in reais (Decimal) or nil if not specified
  • :due_date - Due date as Date or nil if not specified
  • :segment - Segment identifier (convenio boletos only)
  • :company_id - Company/CNPJ identifier (convenio boletos only)
  • :free_field - Bank-defined or company-defined content

Examples

iex> boleto = %Brasilex.Boleto{
...>   type: :banking,
...>   raw: "23793381286000000000300000000400184340000019900",
...>   barcode: "23791843400000199003381260000000000000000040",
...>   bank_code: "237",
...>   currency_code: "9",
...>   amount: Decimal.new("199.00"),
...>   due_date: ~D[2020-07-04],
...>   free_field: "3381260000000000000000004"
...> }
iex> Brasilex.Boleto.banking?(boleto)
true

Summary

Functions

Returns true if this is a bank collection boleto (47 digits).

Returns true if this is a utility/tax boleto (48 digits).

Parses a boleto linha digitável or barcode into a structured Brasilex.Boleto.

Same as parse/1 but raises Brasilex.ValidationError on error.

Validates a boleto linha digitável or barcode.

Types

boleto_type()

@type boleto_type() :: :banking | :convenio

t()

@type t() :: %Brasilex.Boleto{
  amount: Decimal.t() | nil,
  bank_code: String.t() | nil,
  barcode: String.t(),
  company_id: String.t() | nil,
  currency_code: String.t() | nil,
  due_date: Date.t() | nil,
  free_field: String.t(),
  raw: String.t(),
  segment: String.t() | nil,
  type: boleto_type()
}

validation_error()

@type validation_error() ::
  :invalid_length
  | :invalid_format
  | :invalid_checksum
  | {:invalid_field_checksum, pos_integer()}
  | :unknown_type

Functions

banking?(boleto)

@spec banking?(t()) :: boolean()

Returns true if this is a bank collection boleto (47 digits).

Examples

iex> boleto = %Brasilex.Boleto{type: :banking, raw: "", barcode: "", free_field: ""}
iex> Brasilex.Boleto.banking?(boleto)
true

iex> boleto = %Brasilex.Boleto{type: :convenio, raw: "", barcode: "", free_field: ""}
iex> Brasilex.Boleto.banking?(boleto)
false

convenio?(boleto)

@spec convenio?(t()) :: boolean()

Returns true if this is a utility/tax boleto (48 digits).

Examples

iex> boleto = %Brasilex.Boleto{type: :convenio, raw: "", barcode: "", free_field: ""}
iex> Brasilex.Boleto.convenio?(boleto)
true

iex> boleto = %Brasilex.Boleto{type: :banking, raw: "", barcode: "", free_field: ""}
iex> Brasilex.Boleto.convenio?(boleto)
false

parse(input)

@spec parse(String.t()) :: {:ok, t()} | {:error, validation_error()}

Parses a boleto linha digitável or barcode into a structured Brasilex.Boleto.

Accepts both formats:

  • Linha digitável: 47 digits (banking) or 48 digits (convenio)
  • Barcode: 44 digits

Validates the input before parsing. Returns {:ok, boleto} on success or {:error, reason} on failure.

Examples

iex> Brasilex.Boleto.parse("12345")
{:error, :invalid_length}

Parsed Fields

For banking boletos (47-digit linha digitável or 44-digit barcode):

  • :bank_code - 3-digit bank code
  • :currency_code - Currency indicator ("9" = BRL)
  • :amount - Amount in reais as float (or nil if "any amount")
  • :due_date - Due date (or nil if "no due date")
  • :free_field - Bank-defined content (25 digits)

For convenio boletos (48-digit linha digitável or 44-digit barcode starting with "8"):

  • :segment - Segment identifier
  • :amount - Amount in reais as float (or nil)
  • :company_id - Company/CNPJ identifier
  • :free_field - Segment-specific content

parse!(input)

@spec parse!(String.t()) :: t()

Same as parse/1 but raises Brasilex.ValidationError on error.

Examples

iex> Brasilex.Boleto.parse!("12345")
** (Brasilex.ValidationError) Invalid length: wrong number of digits

validate(input)

@spec validate(String.t()) :: :ok | {:error, validation_error()}

Validates a boleto linha digitável or barcode.

Accepts both formats:

  • Linha digitável: 47 digits (banking) or 48 digits (convenio)
  • Barcode: 44 digits

Returns :ok if valid, or {:error, reason} if invalid.

Examples

iex> Brasilex.Boleto.validate("12345")
{:error, :invalid_length}

iex> Brasilex.Boleto.validate("")
{:error, :invalid_format}

Error Reasons

  • :invalid_length - Wrong number of digits (expected 44, 47, or 48)
  • :invalid_format - Contains non-digit characters
  • :invalid_checksum - General check digit validation failed
  • {:invalid_field_checksum, n} - Field n check digit validation failed
  • :unknown_type - Could not determine boleto type

validate!(input)

@spec validate!(String.t()) :: :ok

Same as validate/1 but raises Brasilex.ValidationError on error.

Examples

iex> Brasilex.Boleto.validate!("12345")
** (Brasilex.ValidationError) Invalid length: wrong number of digits