Skip to content

Packages

Isopace is layered with a strict, one-directional dependency rule: the core model knows the wire format only through the *Schema it references, codecs implement interfaces declared in the core, and every renderer consumes one read-only View. The Architecture guide covers the design in depth; this page is a tour of each package and where to read more.

Authoritative API reference

The complete, always-current symbol reference is the GoDoc on pkg.go.dev/github.com/teqpace-services/isopace. The pages below summarize each package's purpose and entry points.

Layer Package Purpose
Messaging iso8583 Immutable, zero-copy Message; Codec; Schema; typed Get[T] and struct binding
Codecs fieldcodec, lengthcodec Orthogonal value × length codecs resolvable by name
Profiles packager ISO 8583:1987/1993 profiles, scheme overlays, declarative loader
Rendering render/* One message, many formats — from a read-only View
Transport link, listener, mux Framed TCP (+TLS), graceful server, request/response switch
Runtime runtime Component host & lifecycle, deploy descriptors, hot redeploy
Processing flow Two-phase transaction pipeline
Coordination space Keyed tuple space + durable store-and-forward
Security vault PIN, MAC/CMAC, DUKPT, TR-31, EMV behind a Vault façade
Enterprise/Ops rbac, store, ops Auth, persistence, health/metrics/admin, clustering

iso8583 — the messaging core

The core public API, depending only on the standard library and internal/. It holds the in-memory model and the marshal/unmarshal engine.

Key types

  • Message — lazy, immutable, copy-on-write field set over a retained wire buffer. Safe to publish to many goroutines with zero locking.
  • Value — a zero-copy view into the source buffer; Bytes() is the documented hot-path primitive, String()/Int()/Decimal() decode lazily.
  • Codec — drives a Message through a Schema: Unmarshal (structural, zero-copy), Marshal (append-style, bitmap auto-derived), Validate (exhaustive).
  • Schema / FieldDef / SchemaBuilder — immutable, build-time-validated message definitions.
  • FieldPath — one grammar ("55.9F26") used by the dynamic API, struct tags, validation errors, and JSON keys.
  • Decimal / Amount — exact fixed-point money; no float64 ever touches an amount.
  • Bitmap — a 192-bit presence set, always derived at marshal time.
  • Binder[T] — cached struct-binding over iso:"..." tags.
  • FieldError / Violation / ValidationError — structured errors carrying the field path and byte offset.
s := packager.ISO87A()
c := iso8583.NewCodec(s)

m := iso8583.New(s)
_ = m.Set(0, "0200")
_ = m.Set(2, "4111111111111111")
_ = m.Set(4, iso8583.NewDecimal(1099, 2))   // $10.99, exact
wire, _ := c.Marshal(m, nil)

got, _ := c.Unmarshal(wire)                  // structural only; bodies decode on demand
pan, _ := iso8583.Get[string](got, 2)        // no casting
amt, _ := iso8583.Get[iso8583.Decimal](got, 4)

Core types & the dual field API · pkg.go.dev


fieldcodec & lengthcodec — the codec catalog

The defining structural improvement over jPOS: length handling is a separate, independently-registered LengthCodec, composed orthogonally with the value FieldCodec. A field's wire behaviour is the pair (LengthCodec, FieldCodec) — not a monolithic class. This collapses jPOS's combinatorial IF* zoo into ≈6 length × ≈12 value codecs that compose freely.

Value codecschar.ascii, char.ebcdic.cp037, char.ebcdic.cp1047, char.utf8, b.raw, b.hex, num.ascii, num.ebcdic, num.bcd, num.rbcd, num.bin, amount.ascii, amount.bcd, amount.bin.

Bitmap codecsbitmap.bin, bitmap.hex, bitmap.ebcdic.

Length codecslen.fixed, len.ll.asciilen.llllll.ascii, len.ll.bcd, len.lll.bcd, len.ll.bin, len.lll.bin, len.ll.ebcdic, len.lll.ebcdic.

Registries are populated by an explicit builderDefaultRegistry() — not by init() side effects, so global state stays visible and import order never matters. Custom codecs are added by name and referenced from schemas or declarative profiles, with no fork of the engine:

reg := fieldcodec.DefaultRegistry()
reg.Register(myMMDDHHMMSS{})   // Name() == "date.mmddhhmmss.ascii"

Registry & catalog · fieldcodec · lengthcodec


packager — profiles

A profile is just an assembled, immutable *Schema — there is no special "packager" type, which keeps profiles composable. Scheme dialects are deltas applied with Derive/Override.

  • ISO 8583:1987 — variants A (ASCII), B (binary/BCD), C (EBCDIC).
  • ISO 8583:1993 — variants A and B.
  • Card-scheme overlays — Visa Base I and Mastercard, as deltas over the 1993 base.
  • Site profiles — concrete, field-pinned layouts validated against live switches: Postilion(), CoralPay(), Zone().
  • Declarative loaderpackager/generic resolves codec/length names from JSON, producing an identical *Schema.
  • Profiles() returns the registry of named profiles ("iso87-a", "coralpay", "zone", …).
s := packager.ISO87A()           // assembled *iso8583.Schema
c := iso8583.NewCodec(s)

Packager profiles · pkg.go.dev


render — alternate renderings

Because the model is decoupled from the wire codec, rendering to another format is a visitor over the schema-typed Value tree — it never re-parses the wire. Every renderer consumes one read-only View, so adding a format never touches the core or any codec. The same *Message round-trips through every backend.

  • render/jsonio — schema-aware JSON; numerics stay strings to preserve leading zeros and amount scale. Options like UseNames() and MaskPAN().
  • render/protobuf — descriptor-driven (un)marshal (DE → field number).
  • render/iso20022 — bridge to pacs / pain / camt via a declarative map[FieldPath]xpath table.
b, _ := jsonio.Marshal(msg, jsonio.UseNames(), jsonio.MaskPAN())

Alternate renderings (View) · pkg.go.dev


The wire-facing layer: framed TCP with optional TLS, a graceful server, a connection pool, and a request/response multiplexer that correlates replies to requests.

  • link — a framed connection (link.Dial); the framer (e.g. a 2-byte length prefix), TLS, and MAC filters are link options.
  • listener — a graceful TCP server.
  • mux — request/response switching, correlating by a keyer (e.g. STAN + terminal).
cl, _ := link.Dial("tcp", "127.0.0.1:8583")
x := mux.New(cl, mux.FieldKeyer(c, 11, 41), mux.WithTimeout(5*time.Second))
resp, _ := x.Request(context.Background(), wire)

Core API in a nutshell · link · mux


runtime — the component host

runtime.Host is the component container (the jPOS Q2 analog): it supervises components with a start-in-order / stop-in-reverse lifecycle, supports live Deploy/Undeploy, and a Deployer turns a directory of declarative JSON descriptors into running components and hot-(re)deploys them as the files change. Config, structured logging (slog), and an observability facade are wired in.

The higher-level teq container wraps runtime.Host and adds self-healing upstream Switch connections.

Component host · pkg.go.dev


flow — the transaction pipeline

A two-phase Flow/Stage/Exchange transaction manager. A prepare pass validates, routes, and reserves; a commit pass captures, or an abort pass releases the hold and carries a decline. Routing, journaling, retry, idempotent retransmission, and a per-stage profiler are built in.

Transaction flow · pkg.go.dev


space — coordination

A keyed tuple space plus a durable, crash-safe store-and-forward queue. Inside the container, components decouple through a shared space — for example a connector routes server-initiated advices to a queue via its unsolicited_queue.

pkg.go.dev


vault — security

PIN blocks, message MAC / CMAC, DUKPT, TR-31 key blocks, and EMV ARQC/ARPC behind a single Vault façade. vault.SHA256MAC / VerifySHA256MAC provide the prefix-keyed SHA-256 message hash used by some acquirer links (e.g. CoralPay).

Software backend is for development and testing only

The built-in software Vault is for development and testing. Production PIN and key handling require a certified HSM. Cryptographic and key-management components are security-critical — see the security policy.

pkg.go.dev


rbac, store & ops — enterprise & ops

The operational layer that turns the framework into a deployable service.

  • rbac — role-based access control with PBKDF2 authentication.
  • store — persistence.
  • ops — health and readiness checks, metrics, an admin API, and cluster membership.

rbac · store · ops