Fix(finstripe): resolve duplicate payment on same invoice_id with idempotency guard#474
Open
Jean-Regis-M wants to merge 1 commit intoGenAI-Security-Project:mainfrom
Open
Fix(finstripe): resolve duplicate payment on same invoice_id with idempotency guard#474Jean-Regis-M wants to merge 1 commit intoGenAI-Security-Project:mainfrom
Jean-Regis-M wants to merge 1 commit intoGenAI-Security-Project:mainfrom
Conversation
Root cause: create_transfer called repo.create_transaction() unconditionally; list_for_invoice() existed but was never used as a write guard. Solution: Check for existing completed transaction before creating a new one. Returns error dict if invoice already paid. No DB write occurs. Impact: Idempotent on repeat calls. First payment unaffected. Zero API breakage. Signed-off-by: JEAN REGIS <240509606@firat.edu.tr>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #342
Problem
create_transferhad no idempotency guard on the write path. Calling it twice with the sameinvoice_idsilently created two completed transactions, causing direct double-payment of invoices.PaymentTransactionRepository.list_for_invoice()already existed in the repo layer it was simply never called insidecreate_transfer.Root Cause
Bug class: Validation gap missing idempotency guard on write path.
Solution
Added a read-before-write guard inside the same
db_sessionblock, immediately beforerepo.create_transaction():If a completed transaction already exists for the given
invoice_id, the function returns an error dict and aborts with no DB write. First-time payments are completely unaffected.Diff
File:
finbot/mcp/servers/finstripe/server.pycreate_transfer3 lines added. 0 lines removed. 1 location touched.
Edge Cases
Impact
dict[str, Any]; callers already handle{"error": ...}(consistent withget_transferpattern)list_for_invoiceis an existing method onPaymentTransactionRepositoryVerification
Tasks
create_transferlist_for_invoice()exists onPaymentTransactionRepositoryand requires no changesdb_sessionblock no session scope changes{"error": ...}dict matching existing tool response patternstest_mcp_dup_001_same_invoice_paid_twice_should_raisepassestest_mcp_float_001_valid_transfer_creates_transactioncontinues to pass