DEV Community

Thesius Code
Thesius Code

Posted on • Originally published at datanest-stores.pages.dev

Payment Reconciliation Toolkit

Payment Reconciliation Toolkit

Multi-gateway payment reconciliation with automated matching, discrepancy detection, refund tracking, and dispute management. Close your books faster with confidence.

Key Features

  • Multi-Gateway Support — Reconcile Stripe, PayPal, Square, and bank deposits
  • Automated Matching — Match gateway transactions to orders with fuzzy logic
  • Discrepancy Detection — Flag mismatches in amounts, currencies, and timing
  • Refund Tracking — Full refund lifecycle from initiation to settlement
  • Dispute Management — Track chargebacks, evidence submission deadlines, outcomes
  • Financial Reports — Daily settlement, monthly reconciliation, and aging reports

Quick Start

# 1. Extract and configure
unzip payment-reconciliation-toolkit.zip
cd payment-reconciliation-toolkit
cp config.example.yaml config.yaml

# 2. Import gateway export files
python -m payment_reconciliation_toolkit.core --import-gateway stripe --file exports/stripe_march.csv

# 3. Run reconciliation
python -m payment_reconciliation_toolkit.core --reconcile --period 2026-03
Enter fullscreen mode Exit fullscreen mode

Architecture

src/payment_reconciliation_toolkit/
├── __init__.py          # Package metadata
├── core.py              # Reconciliation engine: import → match → report
├── matchers.py          # Transaction matching algorithms (exact, fuzzy, date-window)
├── gateways/
│   ├── stripe.py        # Stripe export parser
│   ├── paypal.py        # PayPal export parser
│   └── square.py        # Square export parser
├── disputes.py          # Chargeback tracking and deadline management
└── utils.py             # Currency conversion, date normalization, CSV helpers
Enter fullscreen mode Exit fullscreen mode

Reconciliation Flow: Gateway Exports → Normalize → Match to Orders → Flag Discrepancies → Report

Usage Examples

Run Full Reconciliation

from payment_reconciliation_toolkit.core import Reconciler

recon = Reconciler(config_path="config.yaml")

# Import gateway data
recon.import_gateway("stripe", "exports/stripe_march.csv")
recon.import_gateway("paypal", "exports/paypal_march.csv")

# Import order data
recon.import_orders("exports/orders_march.csv")

# Run matching
result = recon.reconcile(period="2026-03")
print(f"Matched: {result['matched']}, Unmatched: {result['unmatched']}, "
      f"Discrepancies: {result['discrepancies']}")
# Matched: 1,247, Unmatched: 13, Discrepancies: 8
Enter fullscreen mode Exit fullscreen mode

Find Discrepancies

for d in result["discrepancy_details"]:
    print(f"Order {d['order_id']}: expected ${d['expected']:.2f}, "
          f"received ${d['actual']:.2f} via {d['gateway']} "
          f"(diff: ${d['difference']:.2f})")
Enter fullscreen mode Exit fullscreen mode

Reconciliation Status Query

-- Monthly reconciliation summary
SELECT
    DATE_TRUNC('month', t.transaction_date)    AS month,
    t.gateway,
    COUNT(*)                                    AS total_transactions,
    SUM(CASE WHEN t.match_status = 'matched'
             THEN 1 ELSE 0 END)                AS matched,
    SUM(CASE WHEN t.match_status = 'unmatched'
             THEN 1 ELSE 0 END)                AS unmatched,
    SUM(t.amount)                              AS total_amount,
    SUM(t.fee)                                 AS total_fees,
    SUM(t.amount) - SUM(t.fee)                 AS net_settled
FROM gateway_transactions t
WHERE t.transaction_date >= '2026-01-01'
GROUP BY DATE_TRUNC('month', t.transaction_date), t.gateway
ORDER BY month DESC, gateway;
Enter fullscreen mode Exit fullscreen mode

Track Disputes

from payment_reconciliation_toolkit.disputes import DisputeTracker

tracker = DisputeTracker(config_path="config.yaml")
open_disputes = tracker.get_open()

for dispute in open_disputes:
    print(f"Dispute {dispute['id']}: ${dispute['amount']:.2f} "
          f"via {dispute['gateway']} — respond by {dispute['deadline']}")
Enter fullscreen mode Exit fullscreen mode

Configuration

gateways:
  stripe:
    enabled: true
    export_format: "csv"           # csv | json
    date_column: "created"
    amount_column: "amount"
    fee_column: "fee"
    currency: "USD"
  paypal:
    enabled: true
    export_format: "csv"
    date_column: "Date"
    amount_column: "Gross"
    fee_column: "Fee"
  square:
    enabled: false

matching:
  strategy: "fuzzy"                # exact | fuzzy | date_window
  amount_tolerance: 0.01           # Allow $0.01 rounding differences
  date_window_days: 3              # Match transactions within N days of order
  match_fields: ["order_id", "amount", "email"]

disputes:
  alert_days_before_deadline: 5    # Alert N days before evidence deadline
  auto_track: true

reports:
  output_dir: "./reports"
  formats: ["csv", "json"]
Enter fullscreen mode Exit fullscreen mode

Best Practices

  1. Reconcile daily — Don't wait until month-end; catch issues early
  2. Set tight tolerances — Start with $0.01 tolerance; widen only if needed
  3. Track fees separately — Gateway fees explain most amount discrepancies
  4. Monitor dispute deadlines — Missing a chargeback deadline means automatic loss
  5. Archive matched data — Keep 7 years of reconciliation records for audit compliance

Troubleshooting

Issue Cause Fix
High unmatched count Order ID format differs between systems Normalize IDs in gateway parser
Amount mismatches Gateway reports gross, orders track net Ensure consistent gross/net handling
Duplicate matches Same transaction matched to multiple orders Enable deduplicate: true in config
Missing refunds Refunds exported separately by gateway Import refund export file as well

This is 1 of 11 resources in the Retail Automation Pro toolkit. Get the complete [Payment Reconciliation Toolkit] with all files, templates, and documentation for $39.

Get the Full Kit →

Or grab the entire Retail Automation Pro bundle (11 products) for $139 — save 30%.

Get the Complete Bundle →


Related Articles

Top comments (0)