| Crates.io | mx-message |
| lib.rs | mx-message |
| version | 3.1.4 |
| created_at | 2025-05-27 08:42:43.538058+00 |
| updated_at | 2025-10-14 04:51:22.582293+00 |
| description | A fast, type-safe Rust implementation of MXMessage for parsing MX messages. |
| homepage | https://github.com/GoPlasmatic/MXMessage |
| repository | https://github.com/GoPlasmatic/MXMessage |
| max_upload_size | |
| id | 1690795 |
| size | 5,338,879 |
A Rust library for parsing, validating, and serializing ISO 20022 (MX) financial messages.
Full CBPR+ compliance with comprehensive validation and test data generation.
MXMessage is a comprehensive Rust library for handling ISO 20022 (MX) financial messages. It provides type-safe parsing, validation, and serialization for CBPR+ compliant messages, with powerful test data generation capabilities for all supported message types.
to_json and to_xml) handle all message types with automatic envelope generation.All message types are automatically generated from official ISO 20022 XSD schemas.
use mx_message::document::Document;
use mx_message::pacs_008_001_08::*;
// Create a strongly-typed payment message
let payment = FIToFICustomerCreditTransferV08 {
grp_hdr: GroupHeader93 {
msg_id: "MSGID123456".to_string(),
cre_dt_tm: "2024-01-15T10:30:00Z".to_string(),
nb_of_txs: "1".to_string(),
// ... other fields
},
cdt_trf_tx_inf: vec![/* transactions */],
splmtry_data: None,
};
// Automatic validation
match Document::FIToFICustomerCreditTransferV08(Box::new(payment)).validate() {
Ok(_) => println!("โ Valid CBPR+ compliant message"),
Err(e) => println!("โ Validation error: {} (code: {})", e.message, e.code),
}
// Payment messages
use mx_message::document::Document;
use mx_message::pacs_008_001_08::*; // Customer Credit Transfer
use mx_message::pacs_009_001_08::*; // Financial Institution Credit Transfer
// Cash management messages
use mx_message::camt_053_001_08::*; // Bank to Customer Statement
use mx_message::camt_056_001_08::*; // Payment Cancellation Request
// Payment initiation messages
use mx_message::pain_001_001_09::*; // Customer Credit Transfer Initiation
use mx_message::pain_008_001_08::*; // Customer Direct Debit Initiation
MXMessage provides seamless serialization between JSON and XML formats with enhanced XML capabilities.
use mx_message::document::Document;
use mx_message::xml::{XmlConfig, to_mx_xml};
use serde_json;
// Parse from JSON
let doc: Document = serde_json::from_str(json_str)?;
// Serialize to pretty JSON
let json_output = serde_json::to_string_pretty(&doc)?;
// Enhanced XML serialization with configuration
let xml_config = XmlConfig {
include_declaration: true,
pretty_print: true,
indent: " ".to_string(),
include_schema_location: true,
};
// Generate complete MX XML with envelope
let xml_output = to_mx_xml(&doc, header, "pacs.008.001.08", Some(xml_config))?;
Example JSON Output:
{
"FIToFICstmrCdtTrf": {
"GrpHdr": {
"MsgId": "MSGID123456",
"CreDtTm": "2024-01-15T10:30:00Z",
"NbOfTxs": "1",
"TtlIntrBkSttlmAmt": {
"@Ccy": "EUR",
"$value": 1000.00
}
},
"CdtTrfTxInf": [{
"PmtId": {
"EndToEndId": "E2E123456",
"UETR": "12345678-1234-5678-1234-567812345678"
},
"IntrBkSttlmAmt": {
"@Ccy": "EUR",
"$value": 1000.00
}
}]
}
}
Add mx-message to your Cargo.toml:
[dependencies]
mx-message = "3.1"
serde_json = "1.0" # For JSON support
quick-xml = { version = "0.38", features = ["serialize"] } # For XML support
# Optional: For dataflow pipeline integration
dataflow-rs = "2.0" # For async processing pipelines
datalogic-rs = "4.0" # For validation logic
use mx_message::{to_json, to_xml};
use mx_message::document::Document;
use mx_message::pacs_008_001_08::*;
// Create a payment message
let payment = FIToFICustomerCreditTransferV08 {
grp_hdr: GroupHeader93 {
msg_id: "MSGID123456".to_string(),
cre_dt_tm: "2024-01-15T10:30:00Z".to_string(),
nb_of_txs: "1".to_string(),
// ... other fields
},
cdt_trf_tx_inf: vec![/* transactions */],
splmtry_data: None,
};
let document = Document::FIToFICustomerCreditTransferV08(Box::new(payment));
// Validate against CBPR+ SR2025 rules
match document.validate() {
Ok(_) => println!("โ Message is valid"),
Err(e) => eprintln!("โ Validation failed: {}", e.message),
}
// Convert to JSON (simplified v3 API)
let json = to_json(&document)?;
println!("{}", json);
// Convert to XML with automatic envelope (simplified v3 API)
let xml = to_xml(&document)?;
println!("{}", xml);
use mx_message::sample::generate_sample;
// Generate test data from scenario files
let sample = generate_sample("pacs008", Some("cbpr_cross_border_payment"))?;
println!("Generated sample: {}", serde_json::to_string_pretty(&sample)?);
// Scenarios support fake data generation
// See test_scenarios/ directory for examples
Generate ISO 20022 compliant XML with proper envelope and Business Application Header using the simplified v3 API:
use mx_message::{to_json, to_xml};
use mx_message::document::Document;
// Create or load your message
let document = Document::FIToFICustomerCreditTransferV08(/* ... */);
// Convert to JSON - simple one-liner
let json = to_json(&document)?;
println!("{}", json);
// Convert to XML with automatic envelope generation
let xml = to_xml(&document)?;
println!("{}", xml);
The v3 API automatically:
Note: The simplified API uses sensible defaults. For advanced customization of headers and envelopes, the lower-level APIs are still available:
use mx_message::mx_envelope::create_mx_envelope;
use mx_message::header::head_001_001_02::BusinessApplicationHeaderV02;
// Create custom header for advanced use cases
let custom_header = BusinessApplicationHeaderV02 {
fr: Party44Choice {
fiid: Some(FinancialInstitutionIdentification18 {
bicfi: Some("BANKUS33XXX".to_string()),
..Default::default()
}),
..Default::default()
},
to: Party44Choice {
fiid: Some(FinancialInstitutionIdentification18 {
bicfi: Some("BANKGB22XXX".to_string()),
..Default::default()
}),
..Default::default()
},
biz_msg_idr: "MSG-2024-001".to_string(),
msg_def_idr: "pacs.008.001.08".to_string(),
biz_svc: Some("swift.cbprplus.02".to_string()),
cre_dt: "2024-01-15T10:30:00Z".to_string(),
..Default::default()
};
// Create envelope with custom header
let envelope = create_mx_envelope(custom_header, document)?;
let xml = quick_xml::se::to_string(&envelope)?;
use mx_message::document::Document;
match document.validate() {
Ok(_) => println!("โ Valid"),
Err(e) => {
match e.code {
1001 => println!("Field too short: {}", e.message),
1002 => println!("Field too long: {}", e.message),
1005 => println!("Invalid pattern: {}", e.message),
_ => println!("Validation error: {}", e.message),
}
}
}
MXMessage now provides seamless integration with dataflow-rs for building async processing pipelines with a clean, refactored plugin architecture:
use mx_message::plugin::register_mx_functions;
use dataflow_rs::Engine;
// Register MX message functions with dataflow engine
let functions = register_mx_functions();
let mut engine = Engine::new();
for (name, handler) in functions {
engine.register_function(name, handler);
}
// Create a pipeline workflow
let workflow = r#"
{
"name": "mx-processing-pipeline",
"tasks": [
{
"id": "generate",
"function": "generate_mx",
"params": {
"message_type": "pacs.008",
"scenario": "cbpr_business_payment"
}
},
{
"id": "validate",
"function": "validate_mx",
"inputs": ["generate.output"]
},
{
"id": "publish",
"function": "publish_mx",
"params": {
"format": "xml"
},
"inputs": ["validate.output"]
}
]
}
"#;
// Execute the pipeline asynchronously
let result = engine.execute(workflow).await?;
Available dataflow functions:
parse_mx: Parse MX messages from JSON/XMLvalidate_mx: Validate against schema and business rulesgenerate_mx: Generate sample data from scenariospublish_mx: Serialize to JSON/XML formatsThe plugin architecture has been refactored for better maintainability:
plugin::common) provides shared functionalityMXMessage supports collecting all validation errors instead of stopping at the first error:
use mx_message::validation::Validate;
use mx_message::parse_result::{ParserConfig, ErrorCollector};
use mx_message::pacs_008_001_08::FIToFICustomerCreditTransferV08;
// Create a message with multiple validation issues
let payment = FIToFICustomerCreditTransferV08 {
grp_hdr: GroupHeader93 {
msg_id: "ID", // Too short (min 5 chars)
cre_dt_tm: "invalid-date", // Wrong format
nb_of_txs: "ABC", // Should be numeric
// ... other fields
},
// ... other fields
};
// Collect all validation errors
let config = ParserConfig::default();
let mut collector = ErrorCollector::new();
payment.validate("", &config, &mut collector);
// Process all errors at once
if collector.has_errors() {
println!("Found {} validation errors:", collector.errors().len());
for error in collector.errors() {
println!(" - {}: {} (code: {})",
error.path.as_ref().unwrap_or(&"root".to_string()),
error.message,
error.code
);
}
} else {
println!("โ Message is valid");
}
MXMessage uses comprehensive testing with 168 real-world scenarios migrated from MT messages, covering cross-border payments, securities, cash management, and more.
datafake library# Run all test scenarios
cargo test round_trip_scenarios
# Test specific message type
TEST_MESSAGE_TYPE=pacs.008 cargo test round_trip_scenarios
# Debug a specific scenario
TEST_MESSAGE_TYPE=pacs.008 TEST_SCENARIO=cbpr_cross_border_payment TEST_DEBUG=1 cargo test round_trip_scenarios -- --nocapture
For detailed test scenarios and MT to MX mapping, see the Test Scenarios Documentation.
This library implements CBPR+ SR2025 (Central Bank Payment Regulation Plus Standards Release 2025) compliant schemas, providing:
swift.cbprplus.02 for SR2025 complianceContributions are welcome! If you'd like to help, please feel free to fork the repository, make your changes, and submit a pull request. We ask that you:
MXMessage is developed by Plasmatic, an organization focused on building open-source tools for financial infrastructure. We believe in transparency, security, and performance.
Check out our other projects:
This library is licensed under the Apache License, Version 2.0. See the LICENSE file for details.
Built with โค๏ธ by the Plasmatic team