A software glitch in split-tender refund processing allowed criminals to steal over $1.5 million by exploiting a retailer's POS system. The flaw re-credited the first card when the second refund failed. They knew the retailer used real-time credit technology like Visa Direct for instant refunds.
Your payment processing software likely handles split-tender transactions. You need to ensure it doesn't have the same flaw.
What This Script Tests
This script checks if your POS or payment gateway correctly isolates refund operations in split-tender transactions. It verifies that a failed refund to one payment method doesn't trigger a duplicate credit to another method in the same transaction.
The script also confirms that your refund processing logic maintains proper transaction state when operations are interrupted or fail, and that real-time credit rails don't create exploitable timing windows.
When to run this:
- Before deploying any payment processing software update
- After integrating real-time credit capabilities (Visa Direct, Mastercard Send, RTP rails)
- During quarterly PCI DSS validation cycles
- When adding split-tender or multi-instrument payment support
Prerequisites
Before running this test sequence, ensure you have:
System access:
- Test environment with full payment processing stack (not production)
- Admin access to POS terminal or payment gateway test console
- Access to transaction logs and audit trails
- Test merchant account with refund capabilities enabled
Test instruments:
- Two test debit cards with known balances (or two separate payment methods)
- Ability to monitor both card accounts in real-time
- Invalid test card or credentials to simulate authentication failure
Documentation ready:
- Your payment processor's split-tender implementation specification
- Refund state machine documentation (how your system tracks partial refunds)
- Integration documentation for any real-time credit rails
Monitoring in place:
- Real-time transaction log viewer
- Card account balance monitoring for both test instruments
- Network traffic capture if testing API-based integrations
The Test Script
Run these scenarios in sequence. Document the outcome of each step before proceeding.
Test 1: Standard Split-Tender Refund Baseline
Purpose: Establish correct behavior before introducing failure conditions.
- Process a split-tender purchase: $100 on Card A, $50 on Card B
- Initiate full refund through normal POS return flow
- Monitor both card accounts during refund processing
- Verify Card A receives exactly $100 credit, Card B receives exactly $50 credit
- Check transaction logs: confirm two distinct refund transaction IDs
- Record timestamp delta between first and second credit posting
Expected result: Two independent refund transactions, no duplicate credits, clean transaction closure.
Test 2: Second-Card Authentication Failure
Purpose: Replicate the core vulnerability from the $1.5 million theft.
- Process a split-tender purchase: $100 on Card A, $50 on Card B
- Initiate refund process
- When prompted for Card B refund, deliberately provide incorrect PIN three times (or present wrong card)
- Critical observation point: Monitor Card A account balance during Card B authentication failures
- After Card B refund fails, check Card A: has it received more than $100?
- Review transaction logs: are there multiple credit attempts to Card A?
- Verify system state: is the original transaction still open or marked as partially refunded?
Expected result: Card A receives exactly $100 credit once. Card B refund fails cleanly without affecting Card A. System marks transaction as partially refunded and queues Card B refund for manual resolution.
Failure indicator: If Card A receives multiple $100 credits, your software contains the exploitable flaw. Each authentication retry on Card B should not restart the entire refund sequence.
Test 3: Real-Time Credit Timing Window
Purpose: Verify that instant refund rails don't create race conditions.
- Configure test environment to use real-time credit processing (Visa Direct or equivalent)
- Process split-tender purchase: $100 on Card A, $50 on Card B
- Initiate refund
- The moment Card A receives its credit, attempt to withdraw those funds (simulate the criminal's accomplice behavior)
- Immediately after withdrawal, force Card B refund to fail
- Monitor: does your system detect the Card A balance change and halt the transaction?
- Check: can the system reverse a refund that's already been withdrawn?
Expected result: Your system should complete both refunds atomically or implement a hold period on refunded amounts. If using instant credits, you need compensating controls.
Failure indicator: If funds can be withdrawn from Card A before Card B refund completes, and Card B failure doesn't trigger fraud alerts, you have a timing vulnerability.
Test 4: Network Interruption During Split Refund
Purpose: Test transaction state persistence across connection failures.
- Process split-tender purchase
- Initiate refund
- After Card A refund succeeds, simulate network interruption (disconnect test terminal or kill API connection)
- Reconnect and attempt to resume refund process
- Verify: does system remember Card A was already credited?
- Complete Card B refund
- Confirm: exactly one credit per card, no duplicates despite interruption
Expected result: Transaction state persists across failures. System resumes from last confirmed step.
How to Customize This Script
For e-commerce environments: Replace POS terminal steps with payment gateway API calls. Add test cases for browser session timeouts during refund flows and webhook delivery failures between your platform and payment processor.
For multi-currency scenarios: Add test cases where Card A is USD and Card B is EUR. Verify foreign exchange calculations don't create credit amount discrepancies during partial refund failures.
For card-not-present transactions: Include test cases for 3DS authentication failures during refund authorization. Verify that SCA (Strong Customer Authentication) failures on one instrument don't affect refund state of other instruments.
For stored credentials: Test split refunds where one payment method is a stored card token and the other is a manual entry. Verify token invalidation during refund doesn't create processing loops.
Validation Steps
After running the complete test script:
1. Review transaction logs for anomalies:
- Search for duplicate refund transaction IDs
- Identify any transactions marked "pending" for more than your standard settlement window
- Flag any refund amounts that don't match original purchase amounts
2. Confirm idempotency: Your refund API must use idempotency keys. The same refund request submitted multiple times should return the same transaction ID, not create duplicate credits.
3. Verify real-time credit controls: If you use Visa Direct, Mastercard Send, or RTP rails for instant refunds, document your fraud monitoring rules for unusual refund patterns. The criminals in the Justice Department case exploited the combination of a software flaw and real-time credits. You need both technical and operational controls.
4. Test your fraud detection: Generate a test pattern that mimics the criminal scheme: multiple high-value purchases followed by immediate returns with authentication delays. Your fraud system should flag this pattern within three transactions.
5. Document the software behavior: Create a state diagram showing exactly how your system handles each step of a split-tender refund, including all failure modes. Share this with your payment processor and QA team. If you can't draw the diagram, you don't understand the system well enough to secure it.
This isn't theoretical. The criminals knew the retailer used instant refund technology and had found a specific software flaw. Your job is to verify your system doesn't contain similar vulnerabilities before someone else finds them first.



