Documentation
¶
Overview ¶
blocks/cnab/block.go
Package cnab provides a declarative CNAB 240 and CNAB 400 file reader block.
CNAB (Centro Nacional de Automação Bancária) is the Brazilian banking file interchange standard. The two variants differ only in line width and record structure:
CNAB 240 — 240 chars/line; Header de Arquivo, Header de Lote,
Segmentos (A, B, C…), Trailer de Lote, Trailer de Arquivo.
CNAB 400 — 400 chars/line; Header, Detalhe, Trailer.
The block is configured by declaring field layouts that mirror the bank's technical specification document — field names, column positions (1-indexed), and data types. No parsing code needs to be written by the caller.
CNAB 240 example ¶
reader := cnab.New("remessa-itau",
cnab.WithFormat(cnab.Format240),
cnab.WithFileHeader(
cnab.NumericField("banco_codigo", 1, 3).Describe("Código do banco"),
cnab.NumericField("lote", 4, 7),
cnab.NumericField("tipo_registro", 8, 8),
cnab.Field("nome_empresa", 73, 102),
cnab.DateField("data_geracao", 144, 151),
cnab.NumericField("sequencia", 158, 163),
),
cnab.WithSegment("A",
cnab.NumericField("banco_codigo_favorecido", 21, 23),
cnab.NumericField("agencia", 24, 28),
cnab.Field("nome_favorecido", 43, 72),
cnab.DecimalField("valor", 120, 134, 2),
cnab.DateField("data_pagamento", 145, 152),
),
cnab.WithSegment("B",
cnab.Field("logradouro", 19, 53),
cnab.Field("cidade", 64, 83),
cnab.Field("cep", 84, 91),
cnab.Field("uf", 92, 93),
),
cnab.WithFileTrailer(
cnab.NumericField("total_lotes", 18, 23),
cnab.NumericField("total_registros", 24, 29),
),
)
CNAB 400 example ¶
reader := cnab.New("retorno-bradesco",
cnab.WithFormat(cnab.Format400),
cnab.WithHeader(
cnab.NumericField("tipo_registro", 1, 1),
cnab.NumericField("codigo_retorno", 2, 2),
cnab.Field("nome_banco", 77, 94),
cnab.DateField("data_geracao", 95, 100, "020106"),
),
cnab.WithDetail(
cnab.NumericField("tipo_registro", 1, 1),
cnab.NumericField("codigo_ocorrencia", 109, 110),
cnab.Field("nome_pagador", 218, 257),
cnab.DecimalField("valor_titulo", 153, 165, 2),
cnab.DateField("data_vencimento", 120, 125, "020106"),
cnab.DateField("data_credito", 296, 301, "020106"),
),
cnab.WithTrailer(
cnab.NumericField("tipo_registro", 1, 1),
cnab.NumericField("total_registros", 395, 400),
),
)
Parsing ¶
// From a file path
result, err := reader.ParseFile(ctx, "/data/retorno.txt")
// From any io.Reader (uploaded file, S3 object, etc.)
result, err := reader.Parse(ctx, s3Body)
// Navigate results
fmt.Println(result.FileHeader["nome_empresa"])
for _, batch := range result.Batches {
for _, seg := range batch.Segments {
if seg.Code == "A" {
fmt.Println(seg.Data["nome_favorecido"], seg.Data["valor"])
}
}
}
for _, detail := range result.Details {
fmt.Println(detail["nome_pagador"], detail["valor_titulo"])
}
blocks/cnab/options.go
blocks/cnab/parser.go
blocks/cnab/types.go
Index ¶
- type Batch
- type Block
- func (b *Block) Init(_ context.Context) error
- func (b *Block) Layout() map[string]RecordLayout
- func (b *Block) Name() string
- func (b *Block) Parse(_ context.Context, r io.Reader) (*ParseResult, error)
- func (b *Block) ParseFile(ctx context.Context, path string) (*ParseResult, error)
- func (b *Block) Shutdown(_ context.Context) error
- type FieldDef
- type FieldType
- type Format
- type Option
- func WithBatchHeader(fields ...FieldDef) Option
- func WithBatchTrailer(fields ...FieldDef) Option
- func WithDateLocation(loc *time.Location) Option
- func WithDetail(fields ...FieldDef) Option
- func WithFileHeader(fields ...FieldDef) Option
- func WithFileTrailer(fields ...FieldDef) Option
- func WithFormat(f Format) Option
- func WithHeader(fields ...FieldDef) Option
- func WithSegment(code string, fields ...FieldDef) Option
- func WithSkipUnknownSegments() Option
- func WithTrailer(fields ...FieldDef) Option
- type ParseError
- type ParseResult
- type Record
- type RecordLayout
- type Segment
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Batch ¶
type Batch struct {
// Header holds the parsed Lote Header (record type 1).
Header Record
// Segments is an ordered list of all detail segments in this batch.
Segments []Segment
// Trailer holds the parsed Lote Trailer (record type 5).
Trailer Record
// LineStart is the 1-indexed line number of the batch header in the file.
LineStart int
}
Batch groups the header, detail segments and trailer of one CNAB 240 lote.
type Block ¶
type Block struct {
// contains filtered or unexported fields
}
Block is a CNAB file reader block. It holds the field layouts declared via options and exposes Parse / ParseFile methods that return a fully typed ParseResult.
func New ¶
New creates a new CNAB Block.
reader := cnab.New("remessa",
cnab.WithFormat(cnab.Format240),
cnab.WithFileHeader( ... ),
cnab.WithSegment("A", ... ),
cnab.WithFileTrailer( ... ),
)
func (*Block) Layout ¶
func (b *Block) Layout() map[string]RecordLayout
Layout returns the configured field definitions for documentation or front-end form generation purposes. The returned map keys are record identifiers:
- "file_header", "batch_header", "batch_trailer", "file_trailer" (CNAB 240)
- "segment_A", "segment_B", … (CNAB 240 segments)
- "header", "detail", "trailer" (CNAB 400)
func (*Block) Parse ¶
Parse reads CNAB data from r and returns the fully typed ParseResult. The caller is responsible for closing r after Parse returns.
// From an S3 object obj, _ := assets.GetObject(ctx, "retorno.txt") defer obj.Close() result, err := cnabBlock.Parse(ctx, obj)
type FieldDef ¶
type FieldDef struct {
Name string
Start int // 1-indexed, inclusive
End int // 1-indexed, inclusive
Type FieldType
DecimalPlaces int // Decimal fields only
DateFormat string // Date fields only; default "02012006" (DDMMYYYY)
Description string // Optional documentation
}
FieldDef describes one field inside a CNAB record.
Positions are 1-indexed to match bank documentation directly. A field spanning columns 1–3 means Start=1, End=3 (3 bytes).
func BoolField ¶
BoolField creates a FieldDef with Boolean type.
cnab.BoolField("indicativo_pix", 198, 198)
func DateField ¶
DateField creates a FieldDef with Date type. format follows Go's time.Parse convention; defaults to "02012006" (DDMMYYYY).
cnab.DateField("data_pagamento", 94, 101) // DDMMYYYY
cnab.DateField("data_vencimento", 94, 101, "020106") // DDMMYY
func DecimalField ¶
DecimalField creates a FieldDef with Decimal type and the given decimal places.
cnab.DecimalField("valor", 153, 167, 2) // 15 digits, 2 decimal places
func Field ¶
Field creates a FieldDef with Alpha type. This is the most common field type.
cnab.Field("nome_empresa", 73, 102)
func NumericField ¶
NumericField creates a FieldDef with Numeric type.
cnab.NumericField("numero_documento", 74, 93)
type FieldType ¶
type FieldType int
FieldType determines how raw bytes are converted to a Go value.
const ( // Alpha is a left-aligned, space-padded string field. Alpha FieldType = iota // Numeric is a right-aligned, zero-padded integer field. Numeric // Decimal is a numeric field with an implicit decimal separator. // Use WithDecimalPlaces to set how many digits are fractional. // E.g. "000001234" with 2 decimal places → 12.34 Decimal // Date parses the field as a date. Default format is DDMMYYYY. // Use WithDateFormat to override. Date // Boolean treats "1" or "S" as true, anything else as false. Boolean )
type Format ¶
type Format int
Format identifies the CNAB line width standard.
const ( // Format240 is the CNAB 240 standard (FEBRABAN) — 240 characters per line. // Structure: FileHeader | BatchHeader | Segments (A, B, C…) | BatchTrailer | FileTrailer Format240 Format = 240 // Format400 is the CNAB 400 standard — 400 characters per line. // Structure: FileHeader | Details | FileTrailer Format400 Format = 400 )
type Option ¶
type Option func(*blockConfig)
Option configures a CNAB Block.
func WithBatchHeader ¶
WithBatchHeader defines the fields for the CNAB 240 lote header (registro tipo 1).
func WithBatchTrailer ¶
WithBatchTrailer defines the fields for the CNAB 240 lote trailer (registro tipo 5).
func WithDateLocation ¶
WithDateLocation sets the time.Location used when parsing Date fields. Defaults to time.UTC.
func WithDetail ¶
WithDetail defines the fields for CNAB 400 detail records. Detail records are identified by record type "1" in column 1.
cnab.WithDetail(
cnab.NumericField("tipo_registro", 1, 1),
cnab.Field("nome_pagador", 218, 257),
cnab.DecimalField("valor_titulo", 153, 165, 2),
cnab.DateField("data_vencimento", 120, 125, "020106"),
cnab.NumericField("codigo_ocorrencia", 109, 110),
)
func WithFileHeader ¶
WithFileHeader defines the fields for the CNAB 240 file header (registro tipo 0).
cnab.WithFileHeader(
cnab.NumericField("banco_codigo", 1, 3).Describe("Código do banco"),
cnab.NumericField("lote", 4, 7).Describe("Lote de serviço"),
cnab.NumericField("tipo_registro", 8, 8).Describe("Tipo de registro"),
cnab.Field("nome_empresa", 73, 102).Describe("Nome da empresa"),
cnab.DateField("data_geracao", 144, 151).Describe("Data de geração"),
)
func WithFileTrailer ¶
WithFileTrailer defines the fields for the CNAB 240 file trailer (registro tipo 9).
func WithFormat ¶
WithFormat sets the CNAB line width. Required. Use Format240 for FEBRABAN CNAB 240 or Format400 for CNAB 400.
func WithHeader ¶
WithHeader defines the fields for the CNAB 400 file header. The header record is identified by record type "0" in column 1.
cnab.WithHeader(
cnab.NumericField("tipo_registro", 1, 1),
cnab.NumericField("codigo_retorno", 2, 2),
cnab.Field("nome_banco", 77, 94),
cnab.DateField("data_geracao", 95, 100, "020106"), // DDMMYY
)
func WithSegment ¶
WithSegment defines the fields for a CNAB 240 detalhe segment identified by its code letter (A, B, C, J, O, N, …). The segment code is read from column 14 of each detail line.
cnab.WithSegment("A",
cnab.NumericField("banco_codigo_favorecido", 21, 23),
cnab.NumericField("agencia", 24, 28),
cnab.Field("nome_favorecido", 43, 72),
cnab.DecimalField("valor", 120, 134, 2),
)
func WithSkipUnknownSegments ¶
func WithSkipUnknownSegments() Option
WithSkipUnknownSegments instructs the parser to silently ignore CNAB 240 segments whose code is not registered via WithSegment, instead of recording a ParseError. Useful when you only care about a subset of segments.
func WithTrailer ¶
WithTrailer defines the fields for the CNAB 400 file trailer. The trailer record is identified by record type "9" in column 1.
type ParseError ¶
ParseError describes a non-fatal error on a specific line.
type ParseResult ¶
type ParseResult struct {
// Format is the detected (or configured) CNAB format.
Format Format
// FileHeader holds the parsed file header record (record type 0 for CNAB 240).
FileHeader Record
// Batches holds the parsed batches (CNAB 240 only).
Batches []Batch
// Details holds the parsed detail records (CNAB 400 only).
Details []Record
// FileTrailer holds the parsed file trailer record (record type 9).
FileTrailer Record
// TotalLines is the number of lines read from the file.
TotalLines int
// ParseErrors contains non-fatal per-line errors encountered during parsing.
ParseErrors []ParseError
}
ParseResult is the top-level result of parsing a CNAB file.
type Record ¶
Record is a single parsed CNAB record: a map of field name → Go value. Values are typed according to their FieldDef:
- Alpha → string
- Numeric → int64
- Decimal → float64
- Date → time.Time
- Boolean → bool
type RecordLayout ¶
type RecordLayout struct {
Fields []FieldDef
}
RecordLayout holds the field definitions for one record type.