Component: finbot/mcp/servers/finstripe/server.py → create_transfer
Root cause:
No check for an existing completed transaction before calling repo.create_transaction. PaymentTransactionRepository.list_for_invoice exists but is never called.
Steps to reproduce:
- Call create_transfer(invoice_id=X, ...) — succeeds
- Call create_transfer(invoice_id=X, ...) again
Expected: error on second call — duplicate payment rejected
Actual: second transfer created successfully
How to execute:
pytest tests/unit/mcp/test_finstripe.py::TestDuplicatePayments::test_mcp_dup_001_same_invoice_paid_twice_should_raise -v
Proposed fix: Before creating the transaction, check for an existing completed payment:
existing = repo.list_for_invoice(invoice_id)
if any(t.status == "completed" for t in existing):
return {"error": f"Invoice {invoice_id} has already been paid"}
Impact: Double-payment of invoices causes direct financial loss.
Acceptance criteria:
- test_mcp_dup_001_same_invoice_paid_twice_should_raise passes
- test_mcp_float_001_valid_transfer_creates_transaction continues to pass (first payment still works)
B
Component: finbot/mcp/servers/finstripe/server.py → create_transfer
Root cause:
No check for an existing completed transaction before calling repo.create_transaction. PaymentTransactionRepository.list_for_invoice exists but is never called.
Steps to reproduce:
Expected: error on second call — duplicate payment rejected
Actual: second transfer created successfully
How to execute:
Proposed fix: Before creating the transaction, check for an existing completed payment:
Impact: Double-payment of invoices causes direct financial loss.
Acceptance criteria:
B