A customer sends €20.00, but pays the fee twice. Another payment appears to fail, then completes after the reserved money has become available to spend again. Both problems can remain hidden if testing checks only the confirmation message.
FinTech software testing covers the behaviour, reliability, and security of financial applications. The focus here is transaction logic: whether each operation applies the agreed rules and records the correct financial effect, including after a failure or retry.
This guide helps you assess whether your team has tested the financial risks that matter before launch. It includes 15 practical scenarios, the evidence to request, and the conditions that should stop a release. It also explains how SDK.finance, a FinTech software development company, supports the development and testing of financial products.
Talk to our team and get a development approach tailored to your business model.
Get a FinTech development estimateWhere transaction testing fits in launch readiness
Financial correctness is one part of a wider testing plan. For each area, agree what the team must demonstrate before launch:
- Financial logic: the right accounts, amounts, fees, and balances after each payment or failure.
- Integration: your system and its providers interpret requests, responses, and payment status consistently.
- Performance: the service handles expected demand and recovers from overload without losing or duplicating financial records.
- Security: only authorised users and systems can access data or initiate financial actions.
- User acceptance testing (UAT): business users can complete their work and handle exceptions.
This guide concentrates on financial logic and its connections to the other areas. Passing these tests does not replace a separate assessment of applicable regulatory obligations.
Agree the financial rules and testing scope
Start with the rules that every transaction must follow. Agree them with engineering, finance, and product owners during the FinTech discovery phase. Turn each rule into a clear pass or fail condition. A double-entry ledger is the system’s accounting record; its individual entries are called postings. Even when those entries balance, a payment can still reach the wrong account or include the wrong fee.
- Correct accounting entries. Money must be recorded against the right accounts, amounts, currencies, and transaction references. Within each currency, total debits and credits must balance.
- Accurate balances. The recorded balance must match the opening balance plus completed account movements. The amount available to spend must also account for reserved funds and any agreed overdraft.
- No duplicate charges. A repeated request or provider notification must not create an extra transfer, fee, or refund.
- Correct fees and rounding. Amounts must follow the agreed calculation rules, including what is stored, shown to the customer, and sent to a provider.
- Traceable refunds and corrections. Each correction must link to the original payment and return the right amount, including fees where the policy requires it.
Some payments remain pending while the system waits for a provider’s answer. Agree how long this is acceptable, who investigates overdue cases, and what the customer sees. A timeout means no response arrived in time; it does not prove that no money moved.

Financial correctness needs its own checks alongside performance and security testing. Processing payments quickly does not prove that each customer is charged correctly. When defining a FinTech MVP, include the complete money flow and a way to recover from failures.
Prepare accounts, events and expected results
Ask the team to use test accounts and a repeatable starting setup. Record the software version, settings, currency rules, and test environment so a failed scenario can be repeated after a fix. Agree the required proof using the test-record checklist later in this guide.
Choose the right test environment
A simulator lets the team create controlled failures, such as a late or repeated payment confirmation. A provider sandbox is a separate environment for trying the provider’s supported payment scenarios without using the live service. Both are useful, but neither reproduces every production condition. Agree which tests run in each environment and what remains untested.
Record differences between the test environment and the planned release, including provider versions, limits, fee settings, and notification behaviour. Assign someone to review provider changes and update the affected tests. A simulator based on an outdated provider response can keep passing while the live integration has changed.
Trigger the payment or failure
Each payment needs a reference that stays the same throughout processing. An idempotency key identifies a request so that retrying it need not charge the customer again. A provider event ID identifies an incoming notification. Ask the team to test both repeated requests and repeated notifications, including cases where they arrive late or in the wrong order.
Agree the expected financial result
Calculate the expected result independently before running the test. A sender starts with €100.00 and sends €20.00 with a €0.50 fee, leaving €79.50. The recipient receives €20.00 and fee income increases by €0.50. The accounting record must explain the full €20.50 deduction. Using the same calculation code for the payment and its test can hide an error.

Check normal payments and limits
Start with successful funding, transfers, payments with fees, and merchant payments. Confirm who pays, who receives money, and what each balance becomes. This provides a clear baseline for reviewing failure scenarios.
Check amounts just below, at, and above each fee or transaction limit. Include insufficient funds after fees, the smallest permitted amount, and invalid amounts. Also test whether someone without permission can debit an account. That attempt should be rejected and recorded, with no money moved.
An amount can be rounded differently for calculation, storage, display, or transmission to a provider. Ask the team to check each relevant value against the agreed rules. A correct-looking balance on screen is not enough.
15 transaction test cases and expected results
The table uses a simplified euro wallet example. A is the sender’s account, B the recipient’s, M the merchant’s, F the fee-income account, and C the provider-clearing account used to record external funding. A, B, and M represent money owed to users. A debit reduces those balances and a credit increases them; for the asset account C, a debit increases the balance.
Unless a row says otherwise, each test starts with €100.00 in A and zero in B, M, and F. The corresponding opening accounting entries are a €100.00 debit to C and credit to A. No funds are reserved and no overdraft is allowed. Transfers have no fee unless specified. Top-ups are recorded only after confirmed success.
In this example, amounts use two decimal places. Percentage fees round to the nearest cent, with exact half-cent values rounded up, known as HALF_UP. The sender pays any transfer fee on top of the amount sent. Partial merchant refunds return the purchase amount only. Your team should replace these assumptions with your product’s approved rules.
Use these 15 scenarios to review coverage with your team. Each row starts from the setup above unless it refers to an earlier row. The accounting shorthand is Dr for debit and Cr for credit. “No postings” means no new committed accounting entries, although the rejected attempt should still be recorded. All amounts are EUR.
| Scenario and starting state | Event | Expected postings and closing balances | Evidence to retain |
|---|---|---|---|
| 01 · Confirmed top-up A 100.00; C 100.00 |
Confirm a new 25.00 top-up. | Dr C 25.00; Cr A 25.00. A 125.00; C 125.00. |
Provider confirmation, one linked journal, before/after balances. |
| 02 · Internal transfer A 100.00; B 0.00 |
Transfer 20.00 from A to B. | Dr A 20.00; Cr B 20.00. A 80.00; B 20.00. |
Operation reference, both entries, final state. |
| 03 · Sender-paid fee A 100.00; B and F 0.00 |
Transfer 20.00 plus a 0.50 fee. | Dr A 20.50; Cr B 20.00; Cr F 0.50. A 79.50; B 20.00; F 0.50. |
Fee rule version, account mapping, journal and balances. |
| 04 · Rounding boundary Fresh baseline for each input |
Transfer 2.49, 2.50, then 2.51 in separate runs; fee 1%. | Fees: 0.02, 0.03, 0.03. Dr A 2.51 / 2.53 / 2.54; Cr B principal; Cr F fee. A 97.49 / 97.47 / 97.46. |
Exact decimal inputs, unrounded fee, rounding mode, posted amounts. |
| 05 · Fee makes funds insufficient A 20.00; C 20.00; B and F 0.00 |
Request a 20.00 transfer plus a 0.50 fee. | Reject; no postings or holds. A 20.00; B and F 0.00. |
Rejection reason and unchanged journal and balances. |
| 06 · Merchant payment A 100.00; M 0.00 |
Pay M 20.00 internally, without fees. | Dr A 20.00; Cr M 20.00. A 80.00; M 20.00. |
Payment reference, merchant mapping, journal. |
| 07 · Duplicate callback After row 01: A and C 125.00 |
Deliver the same successful top-up callback twice more. | No additional postings. A and C remain 125.00. |
All deliveries, duplicate handling, exactly one top-up journal. |
| 08 · Request retry After row 02: A 80.00; B 20.00 |
Repeat the transfer using the same valid idempotency key and payload. | Return the original operation outcome under this fixture’s contract; no new postings. A 80.00; B 20.00. |
Both requests, key scope, shared operation ID, journal count. |
| 09 · Stale event After row 01, top-up is completed |
Deliver an older pending event for that top-up. | No new postings and no regression from completed to pending. A and C remain 125.00. |
Event versions, arrival order, state history. |
| 10 · Concurrent spending A 100.00; B 0.00 |
Submit two distinct 80.00 transfers to B concurrently. | Exactly one completes; the other is rejected under the no-overdraft rule. Dr A 80.00; Cr B 80.00. A 20.00; B 80.00. |
Controlled overlap, both outcomes, one journal, no residual hold. |
| 11 · Timeout after commit A 100.00; B 0.00 |
Commit a 20.00 transfer, drop its response, then retry with the same key. | Only the original Dr A 20.00 / Cr B 20.00 remains. A 80.00; B 20.00. |
Fault injection point, commit evidence, retry result, journal count. |
| 12 · Partial refund and replay After row 06: A 80.00; M 20.00 |
Refund 7.00; then repeat the same refund reference. | Dr M 7.00; Cr A 7.00 once. A 87.00; M 13.00; remaining refundable principal 13.00. |
Original payment link, refund ID, both deliveries, cumulative refunded amount. |
| 13 · Refund exceeds remainder After row 12 |
Request a new 14.00 refund. | Reject; no additional postings. A 87.00; M 13.00; refunded total remains 7.00. |
Remaining-amount check, rejection, unchanged journal. |
| 14 · Full corrective reversal After row 03 |
Reverse the transfer and fee under an explicitly approved full-reversal policy. | Dr B 20.00; Dr F 0.50; Cr A 20.50. A 100.00; B and F 0.00. Retain the original entries. |
Original and corrective journals, linkage, approval, reason. |
| 15 · External amount mismatch After row 01: A and C 125.00 |
Compare the internal 25.00 top-up with a provider record showing 24.00 for the same reference, currency, and gross-amount basis. | Flag a 1.00 mismatch; no automatic adjustment in this fixture. A and C remain 125.00. |
Both source records, matching rule, exception ID, unchanged journal. |
Check financial correctness under peak load
Ask the team to repeat the critical payment scenarios at expected peak demand, with a realistic mix of transfers, refunds, and provider responses. A fast response is not enough: completed payments must still produce the right balances and account entries.
Agree the load profile and acceptance limits before testing. Review duplicate or missing entries, unexplained balance differences, payments pending beyond their deadline, and the time needed to clear delayed work after demand falls. Separate expected declines from technical failures. Use a controlled environment for load tests and follow each provider’s testing limits.
Test repeated, delayed, and simultaneous requests
A system may handle two requests correctly when they arrive one after another, yet fail when they arrive together. Ask the team to test overlapping requests against the same balance. The result must respect available funds and avoid duplicate charges, even when the system is busy.
Provider behaviour should come from the integration contract. For example, Stripe documents duplicate webhook deliveries and does not guarantee event order. Its idempotent request documentation separately defines key reuse and parameter checks. Those are provider-specific behaviours, not universal SDK.finance guarantees.
Test what happens when a retry changes the amount, uses the same key for another account, or arrives after the key’s retention period has ended. The expected result must follow the agreed rules: reject the request, return the earlier result, or treat it as a new operation. These distinctions determine whether the customer can be charged again.

Test a failure both before and after the system saves the payment’s accounting entries, a step engineers call a commit. Before that point, a failed internal transfer should not leave a partial debit. After that point, recovery should find the completed transfer without charging again. External payments need a separate check because a provider may have completed its part while the local system is still waiting.
A hold is money temporarily reserved for a payment. With a €100.00 recorded balance and a €30.00 hold, only €70.00 is available to spend. A completed no-fee payment should leave a €70.00 balance and remove the hold. A confirmed cancellation should restore the available amount to €100.00.
Also test a provider confirmation that arrives after the hold expires. The system must follow the agreed recovery process, including what happens if the customer no longer has enough funds. It must not reserve or debit the same amount twice.
Check refunds, corrections, and unmatched records
A partial refund returns part of a purchase. A reversal corrects an earlier operation. A chargeback follows a payment dispute. Agree the amount each can return and whether it includes fees. In the table, row 14 returns the transfer fee under the example’s full-reversal policy; the merchant payment in row 12 has no fee.
Two refunds can each look valid on their own but exceed the refundable amount together. After row 12, only €13.00 remains refundable. If two €7.00 requests arrive together, only one should complete, leaving A at €94.00 and M at €6.00. The other must be rejected without moving money. Also test what happens when the merchant has insufficient funds.
Payment reconciliation compares internal financial records with provider records. Test a missing record, a duplicate, and an incorrect amount separately. Each difference should be flagged for investigation without silently changing the original payment. An approved adjustment needs its own reason and accounting entries.
Keep amount comparisons like for like. A gross payment and a net settlement after fees can differ legitimately. Define the comparison basis before treating a difference as an exception.
Repeat key tests and agree when to stop a release
Regression testing means rerunning checks after a change to catch problems in existing functionality. Prioritise fees, duplicate charges, simultaneous spending, recovery, and refund limits. Make this part of the FinTech software development life cycle. Every confirmed defect should become a repeatable test once the correct behaviour is agreed.
Automate repeatable checks for calculations, balances, duplicate protection, and refunds where the expected result is clear. Use human review to explore unfamiliar failure paths and assess customer messages and operational decisions. Ask the team to justify coverage of the highest financial risks, rather than reporting only the number of automated tests.
A practical example: did the retry charge twice?
Consider row 11: a customer with €100.00 sends €20.00, with no fee. The system records the transfer, but the response is lost. The customer tries again using the same request reference.
Ask the team to demonstrate four outcomes: the retry returns the original payment; only one transfer is recorded; the sender has €80.00 and the recipient €20.00; no funds remain reserved for this completed payment.
A passing result shows that the customer can recover from a lost response without paying twice.
Set checkpoints throughout delivery
Before a code change is accepted: the team runs checks for affected calculations, permissions, and payment flows. A failed required check should prevent the change from moving forward.
During regular regression runs: the team tests a wider set of journeys, including simultaneous requests, late confirmations, and controlled failures. Failures that occur only sometimes still need investigation and a way to reproduce them.
Before launch: test complete customer journeys using the release settings and relevant provider sandbox scenarios. Confirm recovery deadlines and exception handling, then prepare the test record for business acceptance.
Stop the release if tests reveal duplicate charges, missing or wrongly assigned account entries, incorrect balances, excessive refunds, or failed recovery. A pending payment is acceptable only within its agreed deadline and handling process. Every other known limitation needs an owner and a clear release decision.
Request a clear test record
For each test, ask for:
- The scenario, software version, settings, and starting account balances
- The sequence of requests and responses, including the simulated failure
- Expected and actual account entries, balances, reserved funds, and payment status
- Supporting results from the simulator or provider sandbox
- Any failed checks, the linked issue, and the result after the fix
Set a deadline for each test that waits for an external response. If it expires, retain the last known status for investigation. Check the account history as well as the final balance: a duplicate debit followed by a correction can hide a defect.
Confirm business readiness through UAT
UAT checks whether business users can operate the tested journeys, including approvals, customer messages, and exceptions. It complements the technical evidence that the software applies the agreed financial rules.
Give business users the tested version, results, known limitations, and unresolved issues with named owners. Product and operations teams can then assess whether the service is ready to use. A successful UAT session does not override an unresolved defect that can duplicate a charge or lose an accounting entry.

For each UAT journey, record the business acceptance criterion and decision owner. For example, an unresolved external payment should show an accurate customer message and reach the designated operations queue within the agreed deadline. Record acceptance against that criterion and the tested build.
Talk to our team and get a development approach tailored to your business model.
Get a FinTech development estimateKeep financial checks visible after launch
Assign an owner for alerts about duplicate payments, unexplained balance differences, overdue pending payments, and reconciliation exceptions. Agree who investigates, how affected customers are handled, and when a payment flow should be paused. Feed confirmed production defects and provider changes back into the regression tests. Monitoring complements pre-launch testing; it cannot replace it.
Test transaction logic with SDK.finance

SDK.finance is a FinTech software development company backed by 15+ years of FinTech experience and a team of 40+ professionals. It helps banks, FinTech businesses, and payment providers build and evolve financial products, combining custom development with experience in payment flows, transaction accounting, reconciliation, and integrations.
SDK.finance develops and tests financial software as part of agreed implementation projects. Its documented platform QA workflow includes smoke, regression, and API testing. As part of the SDK.finance implementation process, agree the scope of financial checks, UAT support, and release responsibilities. The engagement can cover:
- Agree financial requirements and test scope. Define the transfer, fee, limit, and refund rules with your team, then agree which acceptance criteria and failure scenarios the project will cover.
- Develop and test product-specific logic. Implement custom workflows and integrations, with checks defined by the agreed scope. When extending a ready-made FinTech backend, agree which affected components need regression testing.
- Build on reusable transaction components. Where the SDK.finance Transaction Platform fits your requirements, use its accounts, balances, transfers, fees, and payment workflows as the foundation. Focus implementation tests on the configured rules and the additional behaviour your product introduces.
- Plan integration checks and operational handover. Agree the provider responses, transaction references, and error scenarios to test, together with the evidence, unresolved issues, and responsibilities needed for UAT and launch.
The Platform is available through two delivery models, with different implications for customisation and testing:
- SaaS: SDK.finance manages application hosting and platform updates, with configuration and integration work defined by the agreed scope. Focus your acceptance tests on configured money flows, connected services, and the impact of updates on your product.
- Source Code Licence: access the platform source code and deploy it in your own infrastructure. Your team controls code changes and the release cycle and manages deployment and maintenance. Agree who tests customisations and integrations, with support defined by the licence and project agreement.
Make financial correctness a condition of launch
Before approving launch, ask three questions: Do the key payment scenarios produce the right financial result? Can the team show the evidence? Is there a clear owner and process for unresolved payments? Repeat these checks as the product changes, and use UAT to confirm that business users can operate it.
Discuss transaction scenarios and testing requirements for your implementation. Bring your money-flow diagram, fee rules, and highest-risk failure scenarios to the SDK.finance team to define the testing scope.
Talk to our team and get a development approach tailored to your business model.
Get a FinTech development estimate
