I. Business and merchant
Businesses are a common vehicle for money laundering: a shop, a restaurant or an import business can mix illicit money with real takings, and invoices can be used to justify payments that have nothing to do with trade. The rules in this category compare what a business (or a personal account) says it does with what its money actually does.
They run as scheduled sweeps: once a day, each looks back over a period of up to three months.
I1, I2 and I3 ship in both the gh-psp and gh-bank packs; I4 ships in gh-bank. If you
install both packs, the shared rules are added once, by whichever pack you install first. See
Scheduled rules for how runs, catch-up and re-alerting work.
Rules in this category
Section titled “Rules in this category”| ID | Rule | Mode | Status |
|---|---|---|---|
| I1 | Merchant volume far above declared turnover | SCH | Ships (gh-psp, gh-bank, daily) |
| I2 | Merchant with refunds/chargebacks above ratio | SCH | Ships (gh-psp, gh-bank, daily) |
| I3 | Personal account receiving business-like volume | SCH | Ships (gh-psp, gh-bank, daily) |
| I4 | Trade-based: cross-border payments to unrelated sectors | SCH | Ships (gh-bank, daily) |
I1 Merchant volume far above declared turnover
Section titled “I1 Merchant volume far above declared turnover”What it looks for: a merchant receiving far more money than the turnover it declared at onboarding. A small provisions shop that declared GHS 20,000 a month and is suddenly receiving GHS 400,000 may be mixing in money from elsewhere, or collecting for others.
Example
With the defaults (period_days 30, multiplier 2, min_volume 20,000, money in only,
businesses only):
- ✅ Fires: declared monthly turnover GHS 20,000; GHS 85,000 received in the last 30 days.
- ❌ Does not fire: GHS 35,000 in the Christmas month (under 2 ×).
- ❌ Does not fire: a business with no declared turnover: it is skipped.
Parameters
| Parameter | Meaning | How to tune |
|---|---|---|
period_days |
The period, in days (7 to 92). Takings are scaled to 30 days | 30 for monthly; 90 smooths seasonal trade |
multiplier |
How many times the declared monthly turnover counts as too much (1 to 100) | 2–5 are typical values to test |
min_volume |
Takings over the period at or above (base currency) | |
direction |
Count money in, out or any |
in for takings |
customer_types |
business by default |
|
segments |
Only these segments; empty means all | |
occupation_caps |
Not used by default (empty), so customers without a declaration are skipped |
I1 runs the same check as F5, tuned for businesses and money in. A turnover declared in a currency other than your base currency is ignored.
Mode and pack: scheduled, every day at 04:30 (daily 04:30), in gh-psp 1.2.0 and
gh-bank 1.0.0.
False positives: growing businesses whose declarations were never updated. When growth is confirmed, update the declared volume on the customer record.
Data it needs: type: business and declared_monthly_volume_minor (in your base currency) on
the customer, and their incoming transactions.
I2 Merchant with refunds or chargebacks above ratio
Section titled “I2 Merchant with refunds or chargebacks above ratio”What it looks for: a merchant whose refunds or chargebacks are a high share of its sales: refund fraud, collusive merchants cashing out stolen cards, or a merchant about to fail.
Example
With the defaults (period_days 30, max_ratio 0.1, min_sales 50):
- ✅ Fires: 400 sales, 30 refunds and 15 chargebacks in 30 days: 45 against 400 is 11%.
- ❌ Does not fire: 30 sales and 6 refunds (fewer than
min_sales).
Parameters
| Parameter | Meaning | How to tune |
|---|---|---|
period_days |
The period, in days (1 to 92) | |
max_ratio |
Refunds and chargebacks per sale, above which it fires: 0.1 is 10% | Depends on the sector: fashion e-commerce has naturally higher returns than a pharmacy |
min_sales |
Sales in the period, at least | Stops tiny merchants alerting on one refund |
The ratio counts transactions, not money: a sale is an incoming payment or transfer, a
refund is an outgoing refund, and every chargeback counts. The alert also shows how much
was paid back. A merchant is a business customer, or any customer with an account of type
merchant.
Mode and pack: scheduled, every day at 05:30 (daily 05:30), in gh-psp 1.2.0 and
gh-bank 1.0.0.
False positives: sectors with high natural returns, and seasonal returns after a sale. Tune
max_ratio per segment by giving those merchants their own version of the rule.
Data it needs: refunds sent as type: refund and chargebacks as type: chargeback.
I3 Personal account receiving business-like volume
Section titled “I3 Personal account receiving business-like volume”What it looks for: a personal (individual) account receiving payments from many different payers, the way a shop or a collection account does. It may be an unregistered business, or an account collecting money from fraud victims.
Example
With the defaults (period_days 30, min_distinct_payers 40, min_inflow 20,000):
- ✅ Fires: a personal wallet receives GHS 46,000 from 140 different people in a month.
- ❌ Does not fire: 140 cash-ins at agents: the agent is the counterparty of a cash-in, so cash-ins aren’t counted as payers.
Parameters
| Parameter | Meaning | How to tune |
|---|---|---|
period_days |
The period, in days (1 to 92) | |
min_distinct_payers |
Different payers, at least | High enough to ignore family and friends |
min_inflow |
Money in over the period at or above (base currency) |
Incoming transfer, payment and deposit transactions that name a counterparty count.
Mode and pack: scheduled, every day at 04:45 (daily 04:45), in gh-psp 1.2.0 and
gh-bank 1.0.0.
False positives: informal traders, which are very common. The usual outcome is asking the customer to open a business or merchant account, and updating their segment and declared activity.
Data it needs: type: individual on the customer, and the counterparty on incoming payments.
I4 Trade-based: cross-border payments to unrelated sectors
Section titled “I4 Trade-based: cross-border payments to unrelated sectors”What it looks for: a business making cross-border payments for goods or services that have nothing to do with its own line of business, for example a pharmacy paying a mining-equipment supplier abroad. It is a signal of trade-based money laundering, where over- or phantom invoicing is used to move value across borders.
Example
With the defaults (window_days 7, threshold_amount 50,000, min_total 100,000), for a pharmacy
whose industry_code is 4772:
- ✅ Fires: a GHS 300,000 payment to China whose transaction carries
"sector": "2824"(mining machinery). The map expects a retailer (47) to pay sectors such as10,20,21or46, but not28. - ❌ Does not fire: a GHS 300,000 payment with
"sector": "2100"(pharmaceuticals). - ❌ Does not fire: a payment with no
sectororisicattribute: it isn’t judged.
Parameters
| Parameter | Meaning | How to tune |
|---|---|---|
window_days |
The period, in days (1 to 92) | |
home_country |
Your country’s ISO code; payments to other countries count | GH |
threshold_amount |
Each payment at or above (base currency) | Significant trade payments only |
min_total |
The customer’s mismatched payments together at or above (base currency) | |
sector_map |
For each customer industry (an ISIC code prefix), the sectors (ISIC prefixes) it plausibly pays | Start from the defaults and extend them for your book |
How the map is read. The customer’s industry_code is matched against the map’s keys by prefix,
and the longest matching key wins: 4772 matches 47. The payment’s sector must start with one of
that key’s values. Customers whose industry isn’t in the map at all are not judged. The default map
covers eight industries: crop farming (01), food manufacturing (10), construction (41, 42),
wholesale (46), retail (47), IT services (62) and health (86).
Mode and pack: scheduled, every day at 05:15 (daily 05:15), in gh-bank 1.0.0. The
original catalogue planned I4 as post-event; it runs on a schedule because it compares several
payments with the customer’s declared industry. It also counts payments a real-time decision
blocked: an attempted payment abroad outside the customer’s sector is itself the warning sign.
Data it needs: type: business and industry_code (ISIC) on the
customer; counterparty_country, and the sector of what is paid for as
a sector or isic attribute on each payment.
Related
Section titled “Related”- F. Customer risk and designations — F5 declared profile
- D. Mule and network patterns — fan-in on personal accounts
- G. Mobile money and agents
- Tuning and calibration