Fraud Pairs Function Block

What it is

The Fraud Pairs function block helps detect potentially fraudulent patterns where money is moved in and then quickly moved out, within a specified timeframe, and in matching amounts (or nearly matching amounts).

It is designed to highlight situations like:

  • cash-ins followed by suspiciously fast cash-outs

  • multiple credits paired with a matching debit

  • smurfing or money laundering patterns

The block can find pairs or groups of IN and OUT transactions that match closely on amount, within a defined time window.


How it works

The Fraud Pairs logic performs the following steps:

  1. Data standardization

    • Normalizes the amounts to absolute values

    • Normalizes transaction direction (IN/OUT)

    • Cleans missing or invalid fields

    • Generates a unique ID if none exists

  2. Rolling window search

    • For each IN transaction, a rolling time window is defined (for example, 4 days)

    • Only working days can be considered if specified

    • Within the window, candidate OUT transactions are collected

  3. Subsets and pairings

    • All possible groups of IN transactions up to a configurable limit (default max 5) are generated

    • The sum of each IN group is compared to possible OUT groups

    • The block looks for a matching OUT subset where the total amount is within a defined tolerance percentage (for example, ±0.5%)

  4. Fraud sets

    • Each successful match is stored as a fraud pair, with the matching IN and OUT sets

    • Transactions are then marked as used, to avoid duplicate matching

    • The rolling window advances for the next IN

  5. Result output

    • The block outputs all detected fraud pairs

    • Reports the total matched volume

    • Reports the number of fraud pairs found


Parameters

You can configure Fraud Pairs with the following parameters:

ParameterWhat it meansSample value
DirectionWhich field shows whether a transaction is incoming (IN) or outgoing (OUT).$.direction
AmountWhich field holds the transaction amount.$.amount
TimestampWhich field contains the date and time of the transaction.$.timestamp
Window sizeHow far ahead to look for a match, in units of time.1
Window unitThe unit of time for the window.day
Working days onlyWhether to skip weekends in the time window.true
Tolerance (%)The margin of allowed difference between IN and OUT amounts.1
Max transaction INThe maximum number of incoming transactions grouped together for matching.3
Max transaction OUTThe maximum number of outgoing transactions grouped together for matching.1

fraud-pairs-function-block-parameters.png


Technical explanation

Technically, the FraudPairs block:

  • Parses transactions into a standardized list with positive amounts and consistent direction

  • Uses a sliding time window, defined in days or hours, advancing per unique transaction date

  • Finds candidate IN/OUT combinations:

    • Generates combinations of IN transactions

    • Recursively searches for OUT transactions that together match the IN group’s sum within the tolerance

  • Caps the number of transactions per window and the number of subsets to avoid performance overload

  • Prunes impossible matches by:

    • skipping already-used transaction IDs

    • trimming oversized windows to the largest amounts instead of skipping them

    • sorting OUT transactions by amount for faster pruning

  • Supports working days only calculation, ignoring weekends if enabled

Each matched pair is then returned with details:

  • the original transaction data

  • the matched INs and OUTs

  • the matched volume

  • and a unique identifier

Hard-Coded Limits

To protect the system from performance or memory overload, the Fraud Pairs block applies built-in limits behind the scenes. These limits cannot be changed by rule editors in the user interface:

  • Maximum transactions per window: There is a ceiling of 100 transactions within any single time window. When a window holds more, the block keeps the 100 largest amounts and searches those, so the most material transactions are always examined.

  • Maximum number of IN groups to try: The block tests up to 2,000 different combinations of IN transactions within each time window, trying the smallest groups first. Simple one-to-one and one-to-many matches are therefore always covered before budget is spent on larger groupings.

  • Time budget: The search runs for at most 10 seconds. If the budget runs out, the block returns everything found so far instead of failing.

These safeguards help keep the rule engine fast and stable, even when dealing with high transaction volumes.

Best-effort coverage reporting

Whenever one of these limits reduces the search, the result carries an additional __coverage field describing exactly what was reduced: which windows were trimmed (windows_trimmed), where the combination budget ran out (windows_capped), and whether the time budget expired (stopped_early). A result without __coverage came from a complete search. You can reference this field in your rules, for example to route a case to manual review whenever __coverage is present.

If you need to increase these limits, please contact us.


What the block does with your rows

The block reads three fields from each row, by the paths you configure, and leaves everything else alone.

BehaviourWhat it means for your data
Amounts parse like rule conditions do1 234,56, 1,234.56, $1,234.56 and EUR 1234.56 are all read as 1234.56.
A negative amount reverses the direction-500 or (500.00) on an OUT row is treated as 500 coming in. The row itself is not changed.
Tolerance is measured on the inflowAt 0.5%, an inflow of 1005.02 matches an outflow of 1000, because 1000 lies within 0.5% of 1005.02.
A row without a readable amount, direction or date is skippedBank fee lines with an empty amount do not stop the run.
Your id field is passed through, never used for matchingRows are told apart by their position in the list. An id that repeats, an account or batch number for instance, costs no pairs.
Each pair carries your rows as you sent themEvery field comes back unchanged. An id is added only when you sent none.

At exact matching (tolerance 0) the result is the same whatever order the rows arrive in. At a looser tolerance with several transactions per side, a window can exceed the combination budget described in the limits above; the search then covers the rows in the order they arrived, and a statement whose rows carry only a date and no time can answer differently when its rows are reordered. __coverage is present whenever that budget was reached.

Best practices

  • Keep the window size small to maintain performance

  • Always test the tolerance_pct to match your fraud threshold

  • If you expect high transaction volumes, adjust the caps carefully

  • Use consistent direction fields (IN / OUT) in your data


Quick Example

“Detect suspicious cash-outs within 3 working days after cash-ins, with amounts within 1% difference.”

  • Configuration for this scenario:

    • Window size: 3

    • Window unit: day

    • Working days only: true

    • Tolerance (%): 1

    • Max transaction IN: 3

    • Max transaction OUT: 3

    This setup will look for up to 3 incoming transactions grouped together, then check if there are up to 3 outgoing transactions that match their total amount within 1% difference, all happening within 3 working days.