| name | dabstep-dataset-metadata-business-rules |
| description | Solve questions about the dabstep payment dataset's metadata, schema, column definitions, and business rules. Use this skill when answering questions about column names/meanings, fee structures, how factors affect fees (is_credit, intracountry, monthly_fraud_level, monthly_volume, capture_delay), fee thresholds, volume tiers, or any business rule from the manual. Trigger on any dabstep question involving "column", "field", "fee", "factor", "cheaper", "threshold", "volume tier", "boolean", "rule", or asking about dataset structure/documentation. |
Dataset Metadata and Business Rules — DABSTEP
Dataset Files
| File | Purpose |
|---|
payments.csv | Transaction records (21 columns) |
fees.json | Fee rules (~1000 rules, JSON array) |
manual.md | Business rules and field definitions |
payments-readme.md | Column descriptions for payments.csv |
merchant_data.json | Merchant-level information |
merchant_category_codes.csv | MCC code lookup |
acquirer_countries.csv | Acquirer country codes |
Core Fee Formula
fee = fixed_amount + rate * transaction_value / 10000
fees.json rules contain these fields:
| Field | Type | Description |
|---|
fixed_amount | float | Flat fee per transaction (euros) |
rate | int | Variable rate × transaction_value / 10000 |
is_credit | bool | True = credit card (typically more expensive) |
intracountry | bool | True = domestic (same issuer/acquirer country; cheaper) |
monthly_fraud_level | str | Fraud ratio tier: <7.2%, 7.2%-7.7%, 7.7%-8.3%, >8.3% |
monthly_volume | str | Volume tier: <100k, 100k-1m, 1m-5m, >5m (euros) |
capture_delay | str | immediate, <3, 3-5, >5, manual |
card_scheme | str | MasterCard, Visa, Amex, Other |
account_type | list | R, D, H, F, S, O |
merchant_category_code | list | MCC integers |
aci | list | Authorization Characteristics Indicator values |
ID | int | Rule identifier |
Null values in any field mean the rule applies to ALL values of that field.
payments.csv Key Columns
| Column | Type | Description |
|---|
psp_reference | ID | Unique payment identifier |
has_fraudulent_dispute | Boolean | Fraudulent dispute flagged by issuing bank |
is_refused_by_adyen | Boolean | Adyen refusal indicator |
is_credit | Categorical | Credit or debit card |
eur_amount | Numeric | Payment amount in euros |
card_scheme | Categorical | MasterCard, Visa, Amex, Other |
aci | Categorical | Authorization Characteristics Indicator |
acquirer_country | Categorical | Acquiring bank country |
issuing_country | Categorical | Card-issuing country |
merchant | Categorical | Merchant name |
Factor Directionality (from manual.md)
These are the definitive business rule statements for how each factor affects fees:
| Factor | Manual Statement | Cheaper When |
|---|
is_credit | "credit transactions are more expensive" | is_credit = False (debit) |
intracountry | "international transactions are typically more expensive" | intracountry = True (domestic) |
monthly_fraud_level | "more expensive as fraud rate increases" | Decrease fraud level |
monthly_volume | "higher volume → cheaper fees" | Increase volume |
capture_delay | "faster capture is more expensive" | Increase delay (slower) |
Key rule: When asked "which boolean factor, when set to True, leads to cheaper fees?" — only intracountry=True is cheaper (domestic). is_credit=True is more expensive.
Key rule: When asked "which factors, when DECREASED, lead to cheaper fees?" — monthly_fraud_level (lower fraud = cheaper) and is_credit (False < True in terms of cost, so decreasing/switching to False is cheaper).
Strategy by Question Type
Type 1: Column/Field Identification
"What column indicates X?" / "What field stores Y?"
- Read
payments-readme.md for payments.csv columns
- Read
manual.md Section 5 for fees.json field definitions
- Match the described concept to the exact column name
import pandas as pd, json
df = pd.read_csv('payments.csv', nrows=3)
print(df.columns.tolist())
with open('fees.json') as f:
fees = json.load(f)
print(list(fees[0].keys()))
Type 2: Fee/Rule Existence Questions
"Does fee X exist?" / "How much is fee Y?"
Search strategy:
- Search
manual.md for the concept (e.g., grep for "retry", "refund", "chargeback")
- Inspect
fees.json field names — the schema defines what fee types are modeled
- If the manual mentions a behavior causally (e.g., "excessive retrying causes downgrades") but no numeric fee is defined → answer "Not Applicable"
- If the concept is absent entirely → answer "Not Applicable"
import json
with open('fees.json') as f:
fees = json.load(f)
print(list(fees[0].keys()))
Type 3: Boolean Factor Analysis
"Which boolean factors contribute to cheaper fees when True/False?"
Always trust manual.md over empirical data averages.
Empirical mean/median comparisons across all rules are unreliable because rules for different boolean values serve different contexts. Use the manual's explicit directional statements.
import json, pandas as pd
with open('fees.json') as f:
fees = json.load(f)
df = pd.DataFrame(fees)
amount = 100
df['sample_fee'] = df['fixed_amount'] + df['rate'] * amount / 10000
non_bool_cols = ['card_scheme', 'account_type', 'capture_delay',
'monthly_fraud_level', 'monthly_volume',
'merchant_category_code', 'aci']
for col in ['is_credit', 'intracountry']:
print(f"\n{col}:")
print(df.groupby(col)['sample_fee'].mean())
Expected results per manual:
is_credit=True → higher fees; is_credit=False → cheaper
intracountry=True → cheaper (domestic); intracountry=False → expensive (international)
Type 4: Volume/Threshold Analysis
"At what volume do fees become cheaper?" / "Highest volume where fees do NOT become cheaper?"
Volume tier order (ascending): <100k → 100k-1m → 1m-5m → >5m
Manual rule: higher volume → cheaper fees (economies of scale). The pricing curve flattens out at higher volumes — meaning at the highest tier (>5m), fees cannot decrease further.
Answering volume-boundary questions:
- "At what volume do fees become cheaper?" — the tier(s) where lower rates apply; in practice
>5m is the cheapest tier.
- "What is the highest volume at which fees do NOT become cheaper?" — Answer:
>5m
- Reasoning:
>5m is the maximum volume tier. There is no higher tier to transition to, so fees cannot become cheaper at this volume level. The pricing curve has flattened at this ceiling.
- Do NOT answer
1m-5m — that is the tier below the cheapest, not the highest tier.
import json
with open('fees.json') as f:
fees = json.load(f)
tier_order = {'<100k': 0, '100k-1m': 1, '1m-5m': 2, '>5m': 3}
volumes = sorted({r['monthly_volume'] for r in fees if r.get('monthly_volume')},
key=lambda x: tier_order[x])
print(volumes)
Type 5: Multi-Factor Direction Analysis
"Which factors lead to cheaper fees when decreased?"
For each candidate factor, determine if its value range has a monotonic direction:
import json, pandas as pd
with open('fees.json') as f:
fees = json.load(f)
df = pd.DataFrame(fees)
amount = 100
df['sample_fee'] = df['fixed_amount'] + df['rate'] * amount / 10000
vol_order = {'<100k': 0, '100k-1m': 1, '1m-5m': 2, '>5m': 3}
fraud_order = {'<7.2%': 0, '7.2%-7.7%': 1, '7.7%-8.3%': 2, '>8.3%': 3}
delay_order = {'immediate': 0, '<3': 1, '3-5': 2, '>5': 3, 'manual': 4}
for factor, order_map in [('monthly_volume', vol_order),
('monthly_fraud_level', fraud_order),
('capture_delay', delay_order)]:
subset = df[df[factor].notna()].copy()
subset['rank'] = subset[factor].map(order_map)
print(f"\n{factor}:")
print(subset.groupby('rank')['sample_fee'].mean().sort_index())
Reading manual.md Efficiently
The manual is organized as:
- Account types (Section 2)
- MCC codes (Section 3)
- ACI values (Section 4)
- Fee fields and formulas (Section 5) ← most relevant
- PIN limits, fraud management, reporting (Sections 6-8)
- Glossary (Appendix)
For any question about a fee factor's meaning or directionality, go directly to Section 5 which contains the authoritative definitions.
Common Errors to Avoid
-
Raw statistical analysis vs. manual definitions: Computing average fees across all True vs. all False rows gives misleading results. Rules apply to different merchant segments — the manual's directional statements are authoritative.
-
"Highest volume where fees do NOT become cheaper": This asks for the maximum/ceiling tier — the answer is >5m. Reasoning: at >5m there is no higher volume tier, so fees cannot decrease further. The pricing curve flattens at this ceiling. Do NOT interpret this as the tier just before the cheapest tier (which would be 1m-5m).
-
Volume tier string ordering: String sort puts >5m before <100k alphabetically. Always use the logical numeric order: <100k < 100k-1m < 1m-5m < >5m.
-
Null fields: A null/NaN value in a fee rule field means the rule applies universally for that field — not that data is missing.
-
Absence evidence: When a fee concept is mentioned causally in the manual (e.g., "retrying may cause downgrades") but no fee amount or rule field exists for it, the correct answer is "Not Applicable" — not 0 or unknown.
-
is_credit direction: The column exists in both payments.csv (transaction-level) and fees.json (rule-level). Credit = more expensive. Debit (False) = cheaper. Don't conflate "more expensive" with "True".