No format is privileged
Nothing in the message builder is hardcoded to a particular scheme. Field numbers, names, lengths, encodings and framing all come from the specification you are running.
Feature reference
FlexSim is a universal ISO 8583 simulator: one desktop window covering the message format, the card data, the calculations, the connection, the checking and the record — in either direction.
Scope
Most simulators are written around one network's message format and bend awkwardly to anything else. FlexSim treats the format as data you supply, so the link you have to test is a specification you describe rather than a feature request you file.
Nothing in the message builder is hardcoded to a particular scheme. Field numbers, names, lengths, encodings and framing all come from the specification you are running.
Point it at a switch, an issuer host or an acquirer front end — or let it be the thing being pointed at. The same specification serves both.
Specifications live together in one database with their own suites and cases. Switch the active one from the status bar without restarting the app.
Message format
A specification defines which data elements exist, how long each one is, how it is encoded, and what wraps the message on the wire. FlexSim ships working examples and gives you the editor to build your own.
| Setting | Options | Notes |
|---|---|---|
| Data elements | Any number, named and numbered | Add, remove and rename fields to match the document you were given. |
| Field encoding | ASCII, EBCDIC, Binary | Set per field, so a mostly-EBCDIC message can still carry binary chip data. |
| Length encoding | ASCII, EBCDIC, Binary | Applies to the length prefix of variable fields, independently of the data. |
| Length type | Fixed, LLVAR, LLLVAR | Two- or three-digit prefixes for variable fields. |
| Bitmap format | Binary, Hex | Hex writes the bitmap as characters rather than raw bytes. |
| MTI encoding | ASCII, EBCDIC, Binary | Chosen separately from the body of the message. |
| Application headers | Any number, per specification | Fixed-length headers written ahead of the MTI. |
| Subfields | Nested, to any depth | A subfield can hold subfields of its own; the parent's value is composed from them. |
| Framing | 2-byte, 4-byte, TPDU | The length header the socket adds around each message. |
Switching does not need a restart. The specification name in the status bar is a button. Changing it reloads the suite tree, because suites and cases belong to a specification — and it is refused while a run is in progress.
Composition is declared, not guessed. How a field turns its subfields into a value — joined, positional, tag-length-value, nested, or a counted buffer — is a setting on the field, so unusual framing is described rather than special-cased.
Modes
Each mode is named for the system you are testing, and FlexSim plays the other side of the link. The same test case definition works in both directions — what decides which way a case runs is whether you have given it a response definition: without one it sends, with one it listens and answers.
Acquirer mode
The app listens on a port and stands in for the issuer host. Use it when the thing you are testing is the terminal or the switch, and the real issuer is not something you can point at.
Issuer mode
The app connects out and drives the exchange as the acquirer. Use it to certify an issuer host, exercise a switch, or reproduce a message someone captured in production.
| Setting | Behaviour |
|---|---|
| Arming | Running a case that has a response definition starts listening instead of sending. Stop disarms it and releases the port. |
| Iterations | Becomes the number of requests to answer before the listener closes. |
| Response MTI | Left blank, the third digit of the request is stepped — 0200 becomes 0210. Set it and that value is used as given. |
| Explicit fields | Written with the value in the response definition. This is where the response code goes, so you can approve, decline or return anything you want handled. |
| Echoed fields | Copied straight from the incoming request. A field absent from the request is left out of the reply rather than sent empty. |
| Comparison | The request definition doubles as the expectation. Every field that differs is logged. |
| Rule sets | Arming loads every responder case in the suite as a rule, in order, so one suite can answer different requests differently. |
Matching is diagnostic, not gating. A mismatch tells you what the system under test actually sent; it does not abort the exchange, and the reply goes out either way. That is deliberate — a failed comparison is usually the thing you were trying to observe.
Composition
The test case editor lists every data element in the active specification. Tick the ones the message carries, set the values, and FlexSim builds the bitmap and the framing for you.
Search by field number or by name. Enabled fields stay distinct from the rest, so a long specification stays workable.
A field with structure is edited part by part and its value composed from them. Change a leaf and every level above it recomposes, right up to the field.
Any field can be typed, generated at send time, or resolved from the selected card. Generated values can read fields that were themselves just resolved.
| Kind | Examples |
|---|---|
| From the card | PAN, expiry, service code, sequence number, track 2, verification values |
| From the message | Amounts and transaction types that must agree with another field |
| From the clock | Transmission date and time, local date and time |
| From a counter | Trace numbers and transaction counters that survive restarts |
| From the keys | Verification values, PIN blocks, authentication codes, chip cryptograms |
| Random | Unpredictable numbers and any field where the value only has to vary |
A captured message is a starting point. Paste a hex dump and FlexSim parses it against the active specification, turning it into a test case with the fields already populated — including any structure inside them.
Test data
A saved card carries everything a message might need from it. Test cases reference the card rather than copying values out of it, so a card change lands in every case at once.
| Value | Used for |
|---|---|
| PAN | The account number, and the basis of most derived values |
| Expiry date | Its own field, and a component of the track and the verification values |
| Service code | Its own field, and a component of the verification values |
| PIN | PIN block and PIN verification value |
| Card sequence number | Chip key derivation and its own data element |
| CVV | Magnetic stripe card verification value, carried in track 2 |
| CVV2 | The printed value, for card-not-present tests |
| iCVV | The chip variant, substituted automatically on a chip transaction |
| PVV | PIN verification value, carried in track 2 |
| PVKI | PIN verification key index — a second PVV comes from a different index |
| Track 2 layout | The order and presence of each part, saved per card |
| Key references | Which stored key backs each calculation for this card |
The track is built from the card's own fields and the arrangement is saved with the card, so it reproduces exactly every time.
Calculation
Keys are stored once and referenced by the cards that use them. Anything derived from a key is then worked out on demand, so a test stays correct when the card, the amount or the key changes.
| Value | Needs |
|---|---|
| CVV / CVV2 / iCVV | The card and its card verification key |
| PVV | The PIN, the key index and the PIN verification key |
| PIN block | The PIN, the PAN and the PIN key |
| MAC | The assembled message and the authentication key |
| Request cryptogram | The card, its cryptogram master key and the chip data in the message |
| Response cryptogram | The incoming request and the response code being returned |
| Key check value | Shown per key as you type it, so a mistyped digit surfaces before it is saved |
Keys live in their own store with a type and a description; cards reference them by type-filtered picker. Rotate a key once and every card that uses it follows.
If a calculation needs something you have not supplied — a PIN, a key, a card — FlexSim names it instead of leaving the field blank or filling it with something that looks plausible.
Checking
Each case carries its own expectations of the reply, so a run reports pass or fail rather than handing you a log to read.
| Result | Meaning |
|---|---|
| Pass | A reply came back and every rule on that case was satisfied. |
| Fail | A reply came back and at least one rule was not. The rule that failed is named. |
| Sent | The case ran with checking switched off. Deliberately not counted as a pass — unchecked cases would otherwise inflate the number the run exists to produce. |
| Error | No usable reply: a timeout, a connection failure, or a message that would not parse. The elapsed time is recorded. |
The same message sent in two contexts can be judged by two different standards, because the rules belong to the case and not to the specification.
A case with checking off still runs and still sends; its reply simply is not judged. The rules stay put and come back when you switch it on.
Results stream in as each case finishes and export as a spreadsheet or a self-contained report that survives being emailed. Failures carry their raw bytes.
No rules means a reply that parses is a pass. The alternative — failing every case you have not configured yet — reports nothing useful on the day you start.
Transport
ISO 8583 says nothing about how a message is delimited on a stream, which is why every link does it differently. FlexSim makes framing a setting rather than an assumption, and works from either end of the socket.
Visibility
Everything the app does is written down three ways: parsed on screen as it happens, kept in a searchable history, and mirrored to a plain text file on disk.
Requests and responses broken out into named fields, colour-coded and readable without decoding anything yourself. Nothing is trimmed away mid-run, and a burst of traffic does not slow the window down.
Past exchanges stay in the database, grouped by specification, with time, direction, mode, message type and length. Select one and read the hex, the character rendering and the parsed elements together.
A plain text mirror of the on-screen log, rolling at a size you set and again at midnight, in a folder you choose. If that folder goes missing the app falls back to the default rather than losing lines quietly.
Appearance
Testing days are long, and the log is what you stare at. FlexSim lets you set how it looks and applies every change as you make it.
Working day
The parts that are not headline features but decide whether a testing day goes smoothly.
Cases live in suites per specification. Run one, run the lot, or set an iteration count to push volume through the same case. Responder cases are skipped in a send run, and the count is logged.
Suites round-trip through JSON and XML so a colleague can import yours. Card and key material is deliberately left out of the file.
Trace numbers and transaction counters persist across restarts, so a sequence does not reset itself between sessions.
| Tool | What it answers |
|---|---|
| Response codes | What a response code means. An unlisted one is reported as unknown rather than guessed. |
| Currencies | Currency codes and their minor units, so an amount is read with the right number of decimals. |
| Card numbers | Check digit validation and repair, and the scheme a number belongs to. |
| Encoding converter | Moves a value between ASCII, EBCDIC, hex and binary. |
| TLV decoder | Breaks a tag-length-value blob into its tags. |
| Key tools | Component combination, key generation and key wrapping. |
Storage
One file holds everything: specifications, suites, test cases, cards, keys, counters, settings and the message history.
Sensitive values are encrypted in the database. Nothing is sent anywhere — the app is offline unless you point it at a host yourself.
Set a master password and the stored secrets are re-encrypted under it in one step, with the app locked until it is entered. Switching back is just as reversible.
Move the database to another machine and your specifications, cards and suites come with it. The startup log prints the path in use.
| Platform | Path |
|---|---|
| Windows | %LOCALAPPDATA%\FlexSim\simulator.db |
| Linux | ~/.local/share/FlexSim/simulator.db |
| macOS | ~/Library/Application Support/FlexSim/simulator.db |
The same path in every build. It sits outside the folder you unzipped, so replacing the application with a newer one cannot reach your data.
Pick your platform, unzip, and point it at a test endpoint — or let it answer one.
Windows · macOS · Linux · x64 and ARM64