Finance Test Data: A Field Set and Sample Schema for Payment and Banking Systems
A finance test dataset that passes a real validator needs more than plausible numbers. It needs check-digit-valid routing numbers, the correct NACHA entry-detail field positions, and ISO 20022 message identifiers that follow the immutability rules across interbank hops. This page names all 16 required fields, shows a 3-table sample schema, and lists 5 test scenarios.
Field set (16) for payment and banking systems
Cover ACH batch and entry-detail fields (including check-digit-valid routing/account illustrations), card authorization fields using processor-published test PANs only, and ISO 20022 EndToEndId as an immutable correlation key. Every value is synthetic or sandbox-published; none are live PANs.
| # | Field | Type | Format / constraint | Check digit / membership / parent |
|---|---|---|---|---|
| 1 | msg_id | string | Max35Text, 1 to 35 chars, mandatory in GrpHdr | New per message at each hop |
| 2 | instr_id | string | Max35Text, optional, PmtId/InstrId | May change per hop |
| 3 | end_to_end_id | string | Max35Text, mandatory; NOTPROVIDED when none supplied | Immutable across the whole chain |
| 4 | tx_id | string | Max35Text, mandatory, PmtId/TxId | Constant in interbank space |
| 5 | uetr | uuid | UUID v4, optional in PmtId | Unchanged across all legs |
| 6 | debtor_iban | string | ISO 13616; max 34 | MOD 97-10 check digits (pos 3 to 4) |
| 7 | creditor_iban | string | same as debtor_iban | same |
| 8 | rdfi_routing_number | string(9) | 9 digits; pos 9 check digit | ABA 3-7-1 mod 10 = 0 |
| 9 | dfi_account_number | string(17) | NACHA entry detail pos 13 to 29 | Parent: receiving institution (field 8) |
| 10 | ach_transaction_code | string(2) | Positions 02 to 03 | 22/27/32/37; prenotes 23/28/33/38 |
| 11 | amount_cents | integer | Positions 30 to 39; zero for prenotes | Unsigned, zero-padded, no decimal |
| 12 | trace_number | string(15) | Positions 80 to 94 | Must ascend within a batch |
| 13 | card_pan | string | Max 19 digits | Luhn modulus-10 (sandbox PANs only) |
| 14 | card_expiry | string | MM/YY | Cardholder data with full PAN |
| 15 | cardholder_name | string | free text | Cardholder data with full PAN |
| 16 | charge_bearer | enum | DEBT, CRED, SHAR, SLEV | pacs.008 ChrgBr membership |
Compliance framing (PCI DSS 6.5.5)
Sample schema: ACH batch, entry detail, and card authorization
Model ach_batch as parent, ach_entry_detail as child keyed by batch_id, and card_authorization as an independent table that uses only processor-published test PANs. Keep EndToEndId stable across retries.
ach_batch
| batch_id | odfi_routing_number | company_name | effective_entry_date |
|---|---|---|---|
| 1 | 123456780 | ACME SYNTH CO | 2026-08-03 |
| 2 | 098765438 | ACME SYNTH CO | 2026-08-04 |
ach_entry_detail
Row 3 is a prenote (code 23) with zero amount. Trace numbers ascend within each batch.
| trace_number | batch_id | transaction_code | rdfi_routing_number | dfi_account_number | amount_cents | individual_name |
|---|---|---|---|---|---|---|
| 123456780000001 | 1 | 22 | 222333445 | 000100002345 | 0000125000 | AVERY SYNTHFIELD |
| 123456780000002 | 1 | 27 | 222333445 | 000100002346 | 0000004999 | BRIN TESTWORTHY |
| 123456780000003 | 1 | 23 | 098765438 | 000100009001 | 0000000000 | CASS NULLINGTON |
| 098765438000001 | 2 | 32 | 123456780 | 000100007777 | 0000250000 | DEV PLACEHOLDER |
card_authorization (sandbox PANs)
Rows 1 to 2 are Stripe published test Visa numbers; rows 3 to 4 are Authorize.net sandbox numbers (docs retrieved 2026-08-01). Not issued cards.
| auth_id | card_pan | card_expiry | cardholder_name | amount_cents | charge_bearer |
|---|---|---|---|---|---|
| 1 | 4242424242424242 | 12/30 | AVERY SYNTHFIELD | 125000 | SHAR |
| 2 | 4000000000000002 | 12/30 | BRIN TESTWORTHY | 4999 | DEBT |
| 3 | 370000000000002 | 12/30 | CASS NULLINGTON | 250000 | CRED |
| 4 | 5424000000000015 | 12/30 | DEV PLACEHOLDER | 899 | SLEV |
Fixed-position record layout and EndToEndId immutability
NACHA files are fixed-position. A single off-by-one shift corrupts every downstream field. pacs.008 EndToEndId must remain immutable for the life of the payment so reconciliations and duplicate detection stay honest.
| Positions | Field | Note |
|---|---|---|
| 02 to 03 | ach_transaction_code | Mandatory 2-digit code |
| 13 to 29 | dfi_account_number | Left justified, space padded, leftmost 17 |
| 30 to 39 | amount_cents | 10 digits; must be zero for prenote codes |
| 80 to 94 | trace_number | ODFI routing 8 + 7-digit ascending sequence |
Worked ABA 3-7-1 for illustrative routing 123456780: 3(1+4+7) + 7(2+5+8) + (3+6+0) = 36 + 105 + 9 = 150; 150 mod 10 = 0 (check passes). Shape-valid only; not claimed as an assigned institution. Luhn on Stripe sandbox PAN 4242424242424242 is the published success card (docs.stripe.com/testing, retrieved 2026-08-01).
Test scenarios
- End-to-end reconciliation: msg_id/instr_id change per hop; end_to_end_id/tx_id/uetr stay byte-identical (assert join finds one payment).
- Prenote amount invariant: codes 23/28/33/38 with non-zero amount_cents must fail (row 3 pattern).
- Check-digit rejection: transpose one digit in rdfi_routing_number; ABA 3-7-1 rejects before submit.
- Trace-number ordering: insert a descending trace inside a batch; batch validator flags it.
- Replay with the same EndToEndId (pass) vs minting a new EndToEndId on retry (immutability fail).
Generate a larger version
Frequently asked questions
Can production data be used in testing?
PCI DSS v4.0.1 Requirement 6.5.5 states that live PANs are not used in pre-production environments, except where those environments are included in the CDE and protected in accordance with all applicable PCI DSS requirements ([Cloudaware PCI DSS v4.0.1 index](https://ce.prod.cloudaware.com/frameworks/pci-dss-v4.0.1/06/05/05/), retrieval date 2026-08-01). In practice, payment testing uses processor-published test card numbers that work only in sandbox environments and are not issued cards. For ACH testing, production routing numbers and account numbers are replaced with illustrative values that satisfy the check-digit formula without belonging to any real institution or account.
How do you verify that production data is not used in test environments?
Common approaches include confirming that card values are drawn from a processor's published sandbox list and that the test environment has no network path to the production CDE. Synthetic payment records generated from a schema rather than extracted from production contain no real customer account data and address this separation at the data layer. The obligation to scope, assess, and document the control set belongs to each organisation; this is a general industry framing, not compliance guidance.
How should development and production environments be separated?
PCI DSS Requirement 6.5.5 addresses this at the data layer: live PANs are not used in pre-production environments unless those environments sit inside the CDE and carry the same controls ([Cloudaware PCI DSS v4.0.1 index](https://ce.prod.cloudaware.com/frameworks/pci-dss-v4.0.1/06/05/05/), retrieval date 2026-08-01; [WithPCI 6.5 summary](https://withpci.com/requirements/6/6.5), retrieval date 2026-08-01). Both are third-party indexes of the standard; the requirement text was not read from a PCI Security Standards Council document, so quote the requirement number rather than presenting wording as verbatim standard text. Synthetic records are generated rather than copied, so no real PAN, expiry date, or cardholder name moves between environments. Each organisation is responsible for its own scope and control set; this page provides a general framing only, and Generate-Data makes no compliance guarantee.