It is difficult to know the actual status of a transaction when only receiving partial or incomplete invoice data. This creates uncertainty about whether a payment is moving forward or stuck.
It looks at structured invoice data and uses a probability model to estimate the likelihood of different transaction outcomes. It provides a score showing how likely a transaction is to be processing, disputed, or completed.
It provides a clear way to quantify the uncertainty of a transaction's progress based on available data.
It was run inside an isolated container with no network access. This is the exact command and the real output it produced — captured process output, not written by a model.
$ python3 probabilistic_invoice_scorer.py Invoice integrity score: 80.00% Transaction state probabilities: Processing 47.80% Disputed 26.10% Completed 26.10%
A screenshot of that run.
A clean run proves this does what is shown above, in a CPU-only sandbox. It is a small research demo — not a production tool, and nothing here was published anywhere.
All of it — 95 lines, one file, standard library only.
# Probabilistic Invoice State Space Scorer
import json
from dataclasses import dataclass
from typing import Optional, List, Dict
import random
class InvoiceValidator:
"""
Recursively validates invoice structure against Factur-X/ZUGFeRD schema
"""
@staticmethod
def validate(invoice: Dict) -> float:
"""
Returns integrity score [0.0-1.0] based on schema compliance
"""
required_fields = ['profileDescription', 'seller', 'buyer', 'invoiceDate', 'dueDate', 'lineAmounts']
score = 1.0
for field in required_fields:
if field not in invoice:
score *= 0.7 # Penalize missing core fields
continue
if field == 'lineAmounts' and len(invoice[field]) < 1:
score *= 0.5 # Needs at least one line item
# Check nested structures recursively
for item in invoice.get('lineAmounts', []):
if 'tax' not in item or 'value' not in item:
score *= 0.8 # Penalize incomplete line items
return max(score, 0.2) # Never go below 20% integrity
@dataclass
class StateSpaceModel:
"""
Dynamax-inspired Probabilistic State Space Model
"""
TRANSITIONS = {
'pending': {'processing': 0.6, 'disputed': 0.2, 'completed': 0.2},
'processing': {'completed': 0.7, 'disputed': 0.2, 'pending': 0.1},
'disputed': {'resolved': 0.4, 'pending': 0.3, 'cancelled': 0.3},
'completed': {'refunded': 0.1, 'archived': 0.9}
}
def calculate(self, invoice_score: float) -> Dict:
"""
Returns current state probabilities based on invoice integrity
"""
# Adjust transition probabilities based on invoice quality
adjusted = {} # Will contain state: probability
current_state = 'pending' # Starting assumption
# Scale probabilities by invoice integrity score
base_prob = invoice_score * 0.8 # 80% weight to invoice quality
for next_state, prob in self.TRANSITIONS[current_state].items():
adjusted[next_state] = prob * base_prob + (1 - base_prob) * 0.5 # Mix with uniform distribution
# Normalize probabilities
total = sum(adjusted.values())
return {k: v/total for k, v in adjusted.items()}
def main():
"""
Example usage with dummy data
"""
# Sample invoice data (in practice would be read from PDF/XML)
invoice = {
'profileDescription': 'ZUGFeRD 1.0 Basic severely damaged',
'seller': {'name': 'Acme Corporation', 'taxId': 'DE123456789'},
'buyer': {'name': 'Customer GmbH', 'taxId': 'AT987654321'},
'invoiceDate': '2023-01-15',
'dueDate': '2023-02-15',
'lineAmounts': [
{'value': 100.0, 'tax': 19.0}, # Valid line item
{'value': 50.0} # Incomplete entry
]
}
# Validate invoice structure
validator = InvoiceValidator()
integrity_score = validator.validate(invoice)
print(f'Invoice integrity score: {integrity_score:.2%}')
# Calculate state probabilities
ssm = StateSpaceModel()
probabilities = ssm.calculate(integrity_score)
print('\nTransaction state probabilities:')
for state, prob in probabilities.items():
print(f'{state.capitalize():<12} {prob:.2%}')
if __name__ == '__main__':
main()