ISO 8583 is the wire format behind most card transactions worldwide.
Despite that, many open-source Go implementations are surprisingly limited:
hardcoded field descriptors, primary-bitmap only, no BCD encoding, and
error messages that make debugging painful.
I rebuilt one from scratch with a few design goals:
• Spec-driven: the library contains no hardcoded field definitions. You pass a Spec struct to Parse/Build. Different parts of the same application can use different specs simultaneously with no global state.
• Correct bitmap handling: primary (1–64) and secondary (65–128) bitmaps are supported. Bit 1 is managed automatically when building messages.
• BCD encoding support: two decimal digits per byte. Odd-length values get a leading zero nibble during encode that is removed on decode.
• Typed errors: failures return `*FieldError{Field int, Err error}` so you know exactly which field failed and why. Works with `errors.As` and `errors.Is`.
• Zero external dependencies.
The test suite includes round-trip tests verifying that Build→Parse preserves field values and Parse→Build produces byte-identical wire output.
Two things I’d particularly appreciate feedback on:
1. Whether the Spec / FieldSpec API feels ergonomic in real integrations.
2. Whether BCD-encoded variable-length fields should be handled differently than I currently do.
araujo88•1h ago
I rebuilt one from scratch with a few design goals:
• Spec-driven: the library contains no hardcoded field definitions. You pass a Spec struct to Parse/Build. Different parts of the same application can use different specs simultaneously with no global state.
• Correct bitmap handling: primary (1–64) and secondary (65–128) bitmaps are supported. Bit 1 is managed automatically when building messages.
• BCD encoding support: two decimal digits per byte. Odd-length values get a leading zero nibble during encode that is removed on decode.
• Typed errors: failures return `*FieldError{Field int, Err error}` so you know exactly which field failed and why. Works with `errors.As` and `errors.Is`.
• Zero external dependencies.
The test suite includes round-trip tests verifying that Build→Parse preserves field values and Parse→Build produces byte-identical wire output.
Repo: https://github.com/leo-aa88/go-iso8583
Two things I’d particularly appreciate feedback on:
1. Whether the Spec / FieldSpec API feels ergonomic in real integrations. 2. Whether BCD-encoded variable-length fields should be handled differently than I currently do.