DIGITAL TRANSACTIONS FRAUD RISK ANALYSIS USING SAS
1. Introduction – Why Digital Transaction Analytics Matters
In today’s digital economy, billions of financial transactions happen every day through:
1.UPI
2.Credit Cards
3.Debit Cards
4.Net Banking
5.Mobile Wallets
6.Crypto platforms
**With the explosion of online payments, fraud detection has become one of the most critical analytics use cases in the world.
**Banks, fintech companies, and payment gateways continuously analyze:
1.Transaction amount
2.Time of transaction
3.Platform used
4.Risk patterns
5.User behavior
**In this blog, we will build a complete SAS-based Digital Transactions Analytics System that mimics how real financial institutions detect fraud risk.
We will use:
1.DATA Step
2.PROC SQL
3.PROC MEANS
4.PROC FREQ
5.PROC SGPLOT
6.Macros
7.INTCK, INTNX, MDY
8.MERGE, SET, APPEND, TRANSPOSE
2. Creating the Digital Transactions Dataset
We first create a raw dataset of transactions.
Structure
Each transaction contains:
|
Variable |
Meaning |
|
Transaction_ID |
Unique
transaction number |
|
Transaction_Type |
UPI,
Card, Wallet, etc |
|
Platform |
GooglePay,
PhonePe, Paytm, BankApp |
|
Amount |
Transaction
amount |
|
Trans_Date |
Date of
transaction |
|
Trans_Time |
Time of
transaction |
|
Fraud_Risk |
Risk
score (0–100) |
Data Creation
data digital_txn_raw;
format Trans_Date date9.;
input Transaction_ID Transaction_Type:$15. Platform:$15. Amount Trans_Date :date9.
Trans_Time $ Fraud_Risk;
datalines;
1 UPI GooglePay 1200 05JAN2025 09:12 25
2 Card Paytm 45000 05JAN2025 23:45 88
3 Wallet PhonePe 3200 06JAN2025 11:15 30
4 UPI BankApp 15000 06JAN2025 02:30 75
5 NetBanking BankApp 78000 07JAN2025 01:10 92
6 Card GooglePay 5600 07JAN2025 14:05 40
7 Wallet Paytm 300 07JAN2025 03:40 60
8 UPI PhonePe 2200 08JAN2025 19:20 20
9 Card BankApp 92000 08JAN2025 00:50 95
10 NetBanking GooglePay 41000 09JAN2025 22:15 85
11 UPI PhonePe 600 09JAN2025 10:10 15
12 Wallet Paytm 1800 10JAN2025 18:30 25
13 Card GooglePay 75000 10JAN2025 23:59 90
14 UPI BankApp 1300 11JAN2025 09:05 18
15 NetBanking PhonePe 55000 11JAN2025 01:40 89
;
run;
proc print data=digital_txn_raw;
run;
OUTPUT:
| Obs | Trans_Date | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Time | Fraud_Risk |
|---|---|---|---|---|---|---|---|
| 1 | 05JAN2025 | 1 | UPI | GooglePay | 1200 | 09:12 | 25 |
| 2 | 05JAN2025 | 2 | Card | Paytm | 45000 | 23:45 | 88 |
| 3 | 06JAN2025 | 3 | Wallet | PhonePe | 3200 | 11:15 | 30 |
| 4 | 06JAN2025 | 4 | UPI | BankApp | 15000 | 02:30 | 75 |
| 5 | 07JAN2025 | 5 | NetBanking | BankApp | 78000 | 01:10 | 92 |
| 6 | 07JAN2025 | 6 | Card | GooglePay | 5600 | 14:05 | 40 |
| 7 | 07JAN2025 | 7 | Wallet | Paytm | 300 | 03:40 | 60 |
| 8 | 08JAN2025 | 8 | UPI | PhonePe | 2200 | 19:20 | 20 |
| 9 | 08JAN2025 | 9 | Card | BankApp | 92000 | 00:50 | 95 |
| 10 | 09JAN2025 | 10 | NetBanking | GooglePay | 41000 | 22:15 | 85 |
| 11 | 09JAN2025 | 11 | UPI | PhonePe | 600 | 10:10 | 15 |
| 12 | 10JAN2025 | 12 | Wallet | Paytm | 1800 | 18:30 | 25 |
| 13 | 10JAN2025 | 13 | Card | GooglePay | 75000 | 23:59 | 90 |
| 14 | 11JAN2025 | 14 | UPI | BankApp | 1300 | 09:05 | 18 |
| 15 | 11JAN2025 | 15 | NetBanking | PhonePe | 55000 | 01:40 | 89 |
MDY() – Create financial reporting month
data digital_dates;
set digital_txn_raw;
Report_Month = mdy(month(Trans_Date),1,year(Trans_Date));
format Report_Month monyy7.;
run;
proc print data=digital_dates;
run;
OUTPUT:
| Obs | Trans_Date | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Time | Fraud_Risk | Report_Month |
|---|---|---|---|---|---|---|---|---|
| 1 | 05JAN2025 | 1 | UPI | GooglePay | 1200 | 09:12 | 25 | JAN2025 |
| 2 | 05JAN2025 | 2 | Card | Paytm | 45000 | 23:45 | 88 | JAN2025 |
| 3 | 06JAN2025 | 3 | Wallet | PhonePe | 3200 | 11:15 | 30 | JAN2025 |
| 4 | 06JAN2025 | 4 | UPI | BankApp | 15000 | 02:30 | 75 | JAN2025 |
| 5 | 07JAN2025 | 5 | NetBanking | BankApp | 78000 | 01:10 | 92 | JAN2025 |
| 6 | 07JAN2025 | 6 | Card | GooglePay | 5600 | 14:05 | 40 | JAN2025 |
| 7 | 07JAN2025 | 7 | Wallet | Paytm | 300 | 03:40 | 60 | JAN2025 |
| 8 | 08JAN2025 | 8 | UPI | PhonePe | 2200 | 19:20 | 20 | JAN2025 |
| 9 | 08JAN2025 | 9 | Card | BankApp | 92000 | 00:50 | 95 | JAN2025 |
| 10 | 09JAN2025 | 10 | NetBanking | GooglePay | 41000 | 22:15 | 85 | JAN2025 |
| 11 | 09JAN2025 | 11 | UPI | PhonePe | 600 | 10:10 | 15 | JAN2025 |
| 12 | 10JAN2025 | 12 | Wallet | Paytm | 1800 | 18:30 | 25 | JAN2025 |
| 13 | 10JAN2025 | 13 | Card | GooglePay | 75000 | 23:59 | 90 | JAN2025 |
| 14 | 11JAN2025 | 14 | UPI | BankApp | 1300 | 09:05 | 18 | JAN2025 |
| 15 | 11JAN2025 | 15 | NetBanking | PhonePe | 55000 | 01:40 | 89 | JAN2025 |
INTNX – Generate next review date
data digital_dates2;
set digital_dates;
Review_Date = intnx('day',Trans_Date,7,'same');
format Review_Date date9.;
run;
proc print data=digital_dates2;
run;
OUTPUT:
| Obs | Trans_Date | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Time | Fraud_Risk | Report_Month | Review_Date |
|---|---|---|---|---|---|---|---|---|---|
| 1 | 05JAN2025 | 1 | UPI | GooglePay | 1200 | 09:12 | 25 | JAN2025 | 12JAN2025 |
| 2 | 05JAN2025 | 2 | Card | Paytm | 45000 | 23:45 | 88 | JAN2025 | 12JAN2025 |
| 3 | 06JAN2025 | 3 | Wallet | PhonePe | 3200 | 11:15 | 30 | JAN2025 | 13JAN2025 |
| 4 | 06JAN2025 | 4 | UPI | BankApp | 15000 | 02:30 | 75 | JAN2025 | 13JAN2025 |
| 5 | 07JAN2025 | 5 | NetBanking | BankApp | 78000 | 01:10 | 92 | JAN2025 | 14JAN2025 |
| 6 | 07JAN2025 | 6 | Card | GooglePay | 5600 | 14:05 | 40 | JAN2025 | 14JAN2025 |
| 7 | 07JAN2025 | 7 | Wallet | Paytm | 300 | 03:40 | 60 | JAN2025 | 14JAN2025 |
| 8 | 08JAN2025 | 8 | UPI | PhonePe | 2200 | 19:20 | 20 | JAN2025 | 15JAN2025 |
| 9 | 08JAN2025 | 9 | Card | BankApp | 92000 | 00:50 | 95 | JAN2025 | 15JAN2025 |
| 10 | 09JAN2025 | 10 | NetBanking | GooglePay | 41000 | 22:15 | 85 | JAN2025 | 16JAN2025 |
| 11 | 09JAN2025 | 11 | UPI | PhonePe | 600 | 10:10 | 15 | JAN2025 | 16JAN2025 |
| 12 | 10JAN2025 | 12 | Wallet | Paytm | 1800 | 18:30 | 25 | JAN2025 | 17JAN2025 |
| 13 | 10JAN2025 | 13 | Card | GooglePay | 75000 | 23:59 | 90 | JAN2025 | 17JAN2025 |
| 14 | 11JAN2025 | 14 | UPI | BankApp | 1300 | 09:05 | 18 | JAN2025 | 18JAN2025 |
| 15 | 11JAN2025 | 15 | NetBanking | PhonePe | 55000 | 01:40 | 89 | JAN2025 | 18JAN2025 |
INTCK – Calculate days between transaction and review
data digital_dates3;
set digital_dates2;
Days_To_Review = intck('day',Trans_Date,Review_Date);
run;
proc print data=digital_dates3;
run;
OUTPUT:
| Obs | Trans_Date | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Time | Fraud_Risk | Report_Month | Review_Date | Days_To_Review |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 05JAN2025 | 1 | UPI | GooglePay | 1200 | 09:12 | 25 | JAN2025 | 12JAN2025 | 7 |
| 2 | 05JAN2025 | 2 | Card | Paytm | 45000 | 23:45 | 88 | JAN2025 | 12JAN2025 | 7 |
| 3 | 06JAN2025 | 3 | Wallet | PhonePe | 3200 | 11:15 | 30 | JAN2025 | 13JAN2025 | 7 |
| 4 | 06JAN2025 | 4 | UPI | BankApp | 15000 | 02:30 | 75 | JAN2025 | 13JAN2025 | 7 |
| 5 | 07JAN2025 | 5 | NetBanking | BankApp | 78000 | 01:10 | 92 | JAN2025 | 14JAN2025 | 7 |
| 6 | 07JAN2025 | 6 | Card | GooglePay | 5600 | 14:05 | 40 | JAN2025 | 14JAN2025 | 7 |
| 7 | 07JAN2025 | 7 | Wallet | Paytm | 300 | 03:40 | 60 | JAN2025 | 14JAN2025 | 7 |
| 8 | 08JAN2025 | 8 | UPI | PhonePe | 2200 | 19:20 | 20 | JAN2025 | 15JAN2025 | 7 |
| 9 | 08JAN2025 | 9 | Card | BankApp | 92000 | 00:50 | 95 | JAN2025 | 15JAN2025 | 7 |
| 10 | 09JAN2025 | 10 | NetBanking | GooglePay | 41000 | 22:15 | 85 | JAN2025 | 16JAN2025 | 7 |
| 11 | 09JAN2025 | 11 | UPI | PhonePe | 600 | 10:10 | 15 | JAN2025 | 16JAN2025 | 7 |
| 12 | 10JAN2025 | 12 | Wallet | Paytm | 1800 | 18:30 | 25 | JAN2025 | 17JAN2025 | 7 |
| 13 | 10JAN2025 | 13 | Card | GooglePay | 75000 | 23:59 | 90 | JAN2025 | 17JAN2025 | 7 |
| 14 | 11JAN2025 | 14 | UPI | BankApp | 1300 | 09:05 | 18 | JAN2025 | 18JAN2025 | 7 |
| 15 | 11JAN2025 | 15 | NetBanking | PhonePe | 55000 | 01:40 | 89 | JAN2025 | 18JAN2025 | 7 |
4. Fraud Risk Classification Using Macro
Macro for Risk Evaluation
%macro risk_eval;
data digital_risk;
length risk_level $10.;
set digital_dates3;
if Fraud_Risk >= 80 then Risk_Level="HIGH";
else if Fraud_Risk >= 40 then Risk_Level="MEDIUM";
else Risk_Level="LOW";
run;
proc print data=digital_risk;
run;
%mend;
%risk_eval;
OUTPUT:
| Obs | risk_level | Trans_Date | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Time | Fraud_Risk | Report_Month | Review_Date | Days_To_Review |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | LOW | 05JAN2025 | 1 | UPI | GooglePay | 1200 | 09:12 | 25 | JAN2025 | 12JAN2025 | 7 |
| 2 | HIGH | 05JAN2025 | 2 | Card | Paytm | 45000 | 23:45 | 88 | JAN2025 | 12JAN2025 | 7 |
| 3 | LOW | 06JAN2025 | 3 | Wallet | PhonePe | 3200 | 11:15 | 30 | JAN2025 | 13JAN2025 | 7 |
| 4 | MEDIUM | 06JAN2025 | 4 | UPI | BankApp | 15000 | 02:30 | 75 | JAN2025 | 13JAN2025 | 7 |
| 5 | HIGH | 07JAN2025 | 5 | NetBanking | BankApp | 78000 | 01:10 | 92 | JAN2025 | 14JAN2025 | 7 |
| 6 | MEDIUM | 07JAN2025 | 6 | Card | GooglePay | 5600 | 14:05 | 40 | JAN2025 | 14JAN2025 | 7 |
| 7 | MEDIUM | 07JAN2025 | 7 | Wallet | Paytm | 300 | 03:40 | 60 | JAN2025 | 14JAN2025 | 7 |
| 8 | LOW | 08JAN2025 | 8 | UPI | PhonePe | 2200 | 19:20 | 20 | JAN2025 | 15JAN2025 | 7 |
| 9 | HIGH | 08JAN2025 | 9 | Card | BankApp | 92000 | 00:50 | 95 | JAN2025 | 15JAN2025 | 7 |
| 10 | HIGH | 09JAN2025 | 10 | NetBanking | GooglePay | 41000 | 22:15 | 85 | JAN2025 | 16JAN2025 | 7 |
| 11 | LOW | 09JAN2025 | 11 | UPI | PhonePe | 600 | 10:10 | 15 | JAN2025 | 16JAN2025 | 7 |
| 12 | LOW | 10JAN2025 | 12 | Wallet | Paytm | 1800 | 18:30 | 25 | JAN2025 | 17JAN2025 | 7 |
| 13 | HIGH | 10JAN2025 | 13 | Card | GooglePay | 75000 | 23:59 | 90 | JAN2025 | 17JAN2025 | 7 |
| 14 | LOW | 11JAN2025 | 14 | UPI | BankApp | 1300 | 09:05 | 18 | JAN2025 | 18JAN2025 | 7 |
| 15 | HIGH | 11JAN2025 | 15 | NetBanking | PhonePe | 55000 | 01:40 | 89 | JAN2025 | 18JAN2025 | 7 |
5. Using PROC SQL for Business-Level Summaries
Fraud exposure by platform
proc sql;
create table platform_risk as
select Platform,
count(*) as Transactions,
sum(Amount) as Total_Amount,
avg(Fraud_Risk) as Avg_Risk
from digital_risk
group by Platform;
quit;
proc print data=platform_risk;
run;
OUTPUT:
| Obs | Platform | Transactions | Total_Amount | Avg_Risk |
|---|---|---|---|---|
| 1 | BankApp | 4 | 186300 | 70.0000 |
| 2 | GooglePay | 4 | 122800 | 60.0000 |
| 3 | Paytm | 3 | 47100 | 57.6667 |
| 4 | PhonePe | 4 | 61000 | 38.5000 |
6. PROC MEANS – Financial Statistics
proc means data=digital_risk mean min max sum;
class Risk_Level;
var Amount Fraud_Risk;
run;
OUTPUT:
The MEANS Procedure
| risk_level | N Obs | Variable | Mean | Minimum | Maximum | Sum |
|---|---|---|---|---|---|---|
| HIGH | 6 | Amount Fraud_Risk | 64333.33 89.8333333 | 41000.00 85.0000000 | 92000.00 95.0000000 | 386000.00 539.0000000 |
| LOW | 6 | Amount Fraud_Risk | 1716.67 22.1666667 | 600.0000000 15.0000000 | 3200.00 30.0000000 | 10300.00 133.0000000 |
| MEDIUM | 3 | Amount Fraud_Risk | 6966.67 58.3333333 | 300.0000000 40.0000000 | 15000.00 75.0000000 | 20900.00 175.0000000 |
-->Banks use this to understand:
1.Which risk band has highest money flow
2.How dangerous HIGH risk transactions are
7. PROC FREQ – Pattern Detection
proc freq data=digital_risk;
tables Transaction_Type*Risk_Level / nocol norow;
run;
OUTPUT:
The FREQ Procedure
|
| ||||||||||||||||||||||||||||||||||||||||
This tells us:
“Which transaction types generate most fraud?”
8. PROC SGPLOT – Visual Fraud Patterns
Amount vs Fraud Risk
proc sgplot data=digital_risk;
scatter x=Amount y=Fraud_Risk;
title "Transaction Amount vs Fraud Risk";
run;
OUTPUT:
-->High amounts clustering at high risk means fraud concentration.
9. MERGE – Joining Platform Risk Back
proc sort data=digital_risk; by Platform; run;
proc print data=digital_risk;
run;
OUTPUT:
| Obs | risk_level | Trans_Date | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Time | Fraud_Risk | Report_Month | Review_Date | Days_To_Review |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | MEDIUM | 06JAN2025 | 4 | UPI | BankApp | 15000 | 02:30 | 75 | JAN2025 | 13JAN2025 | 7 |
| 2 | HIGH | 07JAN2025 | 5 | NetBanking | BankApp | 78000 | 01:10 | 92 | JAN2025 | 14JAN2025 | 7 |
| 3 | HIGH | 08JAN2025 | 9 | Card | BankApp | 92000 | 00:50 | 95 | JAN2025 | 15JAN2025 | 7 |
| 4 | LOW | 11JAN2025 | 14 | UPI | BankApp | 1300 | 09:05 | 18 | JAN2025 | 18JAN2025 | 7 |
| 5 | LOW | 05JAN2025 | 1 | UPI | GooglePay | 1200 | 09:12 | 25 | JAN2025 | 12JAN2025 | 7 |
| 6 | MEDIUM | 07JAN2025 | 6 | Card | GooglePay | 5600 | 14:05 | 40 | JAN2025 | 14JAN2025 | 7 |
| 7 | HIGH | 09JAN2025 | 10 | NetBanking | GooglePay | 41000 | 22:15 | 85 | JAN2025 | 16JAN2025 | 7 |
| 8 | HIGH | 10JAN2025 | 13 | Card | GooglePay | 75000 | 23:59 | 90 | JAN2025 | 17JAN2025 | 7 |
| 9 | HIGH | 05JAN2025 | 2 | Card | Paytm | 45000 | 23:45 | 88 | JAN2025 | 12JAN2025 | 7 |
| 10 | MEDIUM | 07JAN2025 | 7 | Wallet | Paytm | 300 | 03:40 | 60 | JAN2025 | 14JAN2025 | 7 |
| 11 | LOW | 10JAN2025 | 12 | Wallet | Paytm | 1800 | 18:30 | 25 | JAN2025 | 17JAN2025 | 7 |
| 12 | LOW | 06JAN2025 | 3 | Wallet | PhonePe | 3200 | 11:15 | 30 | JAN2025 | 13JAN2025 | 7 |
| 13 | LOW | 08JAN2025 | 8 | UPI | PhonePe | 2200 | 19:20 | 20 | JAN2025 | 15JAN2025 | 7 |
| 14 | LOW | 09JAN2025 | 11 | UPI | PhonePe | 600 | 10:10 | 15 | JAN2025 | 16JAN2025 | 7 |
| 15 | HIGH | 11JAN2025 | 15 | NetBanking | PhonePe | 55000 | 01:40 | 89 | JAN2025 | 18JAN2025 | 7 |
proc sort data=platform_risk; by Platform; run;
proc print data=platform_risk;
run;
OUTPUT:
| Obs | Platform | Transactions | Total_Amount | Avg_Risk |
|---|---|---|---|---|
| 1 | BankApp | 4 | 186300 | 70.0000 |
| 2 | GooglePay | 4 | 122800 | 60.0000 |
| 3 | Paytm | 3 | 47100 | 57.6667 |
| 4 | PhonePe | 4 | 61000 | 38.5000 |
data digital_merge;
merge digital_risk platform_risk;
by Platform;
run;
proc print data=digital_merge;
run;
OUTPUT:
| Obs | risk_level | Trans_Date | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Time | Fraud_Risk | Report_Month | Review_Date | Days_To_Review | Transactions | Total_Amount | Avg_Risk |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | MEDIUM | 06JAN2025 | 4 | UPI | BankApp | 15000 | 02:30 | 75 | JAN2025 | 13JAN2025 | 7 | 4 | 186300 | 70.0000 |
| 2 | HIGH | 07JAN2025 | 5 | NetBanking | BankApp | 78000 | 01:10 | 92 | JAN2025 | 14JAN2025 | 7 | 4 | 186300 | 70.0000 |
| 3 | HIGH | 08JAN2025 | 9 | Card | BankApp | 92000 | 00:50 | 95 | JAN2025 | 15JAN2025 | 7 | 4 | 186300 | 70.0000 |
| 4 | LOW | 11JAN2025 | 14 | UPI | BankApp | 1300 | 09:05 | 18 | JAN2025 | 18JAN2025 | 7 | 4 | 186300 | 70.0000 |
| 5 | LOW | 05JAN2025 | 1 | UPI | GooglePay | 1200 | 09:12 | 25 | JAN2025 | 12JAN2025 | 7 | 4 | 122800 | 60.0000 |
| 6 | MEDIUM | 07JAN2025 | 6 | Card | GooglePay | 5600 | 14:05 | 40 | JAN2025 | 14JAN2025 | 7 | 4 | 122800 | 60.0000 |
| 7 | HIGH | 09JAN2025 | 10 | NetBanking | GooglePay | 41000 | 22:15 | 85 | JAN2025 | 16JAN2025 | 7 | 4 | 122800 | 60.0000 |
| 8 | HIGH | 10JAN2025 | 13 | Card | GooglePay | 75000 | 23:59 | 90 | JAN2025 | 17JAN2025 | 7 | 4 | 122800 | 60.0000 |
| 9 | HIGH | 05JAN2025 | 2 | Card | Paytm | 45000 | 23:45 | 88 | JAN2025 | 12JAN2025 | 7 | 3 | 47100 | 57.6667 |
| 10 | MEDIUM | 07JAN2025 | 7 | Wallet | Paytm | 300 | 03:40 | 60 | JAN2025 | 14JAN2025 | 7 | 3 | 47100 | 57.6667 |
| 11 | LOW | 10JAN2025 | 12 | Wallet | Paytm | 1800 | 18:30 | 25 | JAN2025 | 17JAN2025 | 7 | 3 | 47100 | 57.6667 |
| 12 | LOW | 06JAN2025 | 3 | Wallet | PhonePe | 3200 | 11:15 | 30 | JAN2025 | 13JAN2025 | 7 | 4 | 61000 | 38.5000 |
| 13 | LOW | 08JAN2025 | 8 | UPI | PhonePe | 2200 | 19:20 | 20 | JAN2025 | 15JAN2025 | 7 | 4 | 61000 | 38.5000 |
| 14 | LOW | 09JAN2025 | 11 | UPI | PhonePe | 600 | 10:10 | 15 | JAN2025 | 16JAN2025 | 7 | 4 | 61000 | 38.5000 |
| 15 | HIGH | 11JAN2025 | 15 | NetBanking | PhonePe | 55000 | 01:40 | 89 | JAN2025 | 18JAN2025 | 7 | 4 | 61000 | 38.5000 |
10. APPEND – Adding New Transactions
data new_txn;
input Transaction_ID Transaction_Type $ Platform $ Amount Trans_Date :date9. Trans_Time $ Fraud_Risk;
format Trans_Date date9.;
datalines;
16 Card PhonePe 89000 12JAN2025 00:30 93
;
run;
proc print data=new_txn;
run;
OUTPUT:
| Obs | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Date | Trans_Time | Fraud_Risk |
|---|---|---|---|---|---|---|---|
| 1 | 16 | Card | PhonePe | 89000 | 12JAN2025 | 00:30 | 93 |
proc append base=digital_txn_raw
data=new_txn force;
run;
proc print data=digital_txn_raw;
run;
OUTPUT:
| Obs | Trans_Date | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Time | Fraud_Risk |
|---|---|---|---|---|---|---|---|
| 1 | 05JAN2025 | 1 | UPI | GooglePay | 1200 | 09:12 | 25 |
| 2 | 05JAN2025 | 2 | Card | Paytm | 45000 | 23:45 | 88 |
| 3 | 06JAN2025 | 3 | Wallet | PhonePe | 3200 | 11:15 | 30 |
| 4 | 06JAN2025 | 4 | UPI | BankApp | 15000 | 02:30 | 75 |
| 5 | 07JAN2025 | 5 | NetBanking | BankApp | 78000 | 01:10 | 92 |
| 6 | 07JAN2025 | 6 | Card | GooglePay | 5600 | 14:05 | 40 |
| 7 | 07JAN2025 | 7 | Wallet | Paytm | 300 | 03:40 | 60 |
| 8 | 08JAN2025 | 8 | UPI | PhonePe | 2200 | 19:20 | 20 |
| 9 | 08JAN2025 | 9 | Card | BankApp | 92000 | 00:50 | 95 |
| 10 | 09JAN2025 | 10 | NetBanking | GooglePay | 41000 | 22:15 | 85 |
| 11 | 09JAN2025 | 11 | UPI | PhonePe | 600 | 10:10 | 15 |
| 12 | 10JAN2025 | 12 | Wallet | Paytm | 1800 | 18:30 | 25 |
| 13 | 10JAN2025 | 13 | Card | GooglePay | 75000 | 23:59 | 90 |
| 14 | 11JAN2025 | 14 | UPI | BankApp | 1300 | 09:05 | 18 |
| 15 | 11JAN2025 | 15 | NetBanking | PhonePe | 55000 | 01:40 | 89 |
| 16 | 12JAN2025 | 16 | Card | PhonePe | 89000 | 00:30 | 93 |
11. SET – Rebuilding Master Table
data digital_master;
set digital_txn_raw;
run;
proc print data=digital_master;
run;
OUTPUT:
| Obs | Trans_Date | Transaction_ID | Transaction_Type | Platform | Amount | Trans_Time | Fraud_Risk |
|---|---|---|---|---|---|---|---|
| 1 | 05JAN2025 | 1 | UPI | GooglePay | 1200 | 09:12 | 25 |
| 2 | 05JAN2025 | 2 | Card | Paytm | 45000 | 23:45 | 88 |
| 3 | 06JAN2025 | 3 | Wallet | PhonePe | 3200 | 11:15 | 30 |
| 4 | 06JAN2025 | 4 | UPI | BankApp | 15000 | 02:30 | 75 |
| 5 | 07JAN2025 | 5 | NetBanking | BankApp | 78000 | 01:10 | 92 |
| 6 | 07JAN2025 | 6 | Card | GooglePay | 5600 | 14:05 | 40 |
| 7 | 07JAN2025 | 7 | Wallet | Paytm | 300 | 03:40 | 60 |
| 8 | 08JAN2025 | 8 | UPI | PhonePe | 2200 | 19:20 | 20 |
| 9 | 08JAN2025 | 9 | Card | BankApp | 92000 | 00:50 | 95 |
| 10 | 09JAN2025 | 10 | NetBanking | GooglePay | 41000 | 22:15 | 85 |
| 11 | 09JAN2025 | 11 | UPI | PhonePe | 600 | 10:10 | 15 |
| 12 | 10JAN2025 | 12 | Wallet | Paytm | 1800 | 18:30 | 25 |
| 13 | 10JAN2025 | 13 | Card | GooglePay | 75000 | 23:59 | 90 |
| 14 | 11JAN2025 | 14 | UPI | BankApp | 1300 | 09:05 | 18 |
| 15 | 11JAN2025 | 15 | NetBanking | PhonePe | 55000 | 01:40 | 89 |
| 16 | 12JAN2025 | 16 | Card | PhonePe | 89000 | 00:30 | 93 |
12. PROC TRANSPOSE – Risk Profile by Platform
proc sql;
create table risk_summary as
select
Platform,
Risk_Level,
sum(Amount) as Total_Amount
from digital_risk
group by Platform, Risk_Level;
quit;
proc print data=risk_summary;
run;
OUTPUT:
| Obs | Platform | risk_level | Total_Amount |
|---|---|---|---|
| 1 | BankApp | HIGH | 170000 |
| 2 | BankApp | LOW | 1300 |
| 3 | BankApp | MEDIUM | 15000 |
| 4 | GooglePay | HIGH | 116000 |
| 5 | GooglePay | LOW | 1200 |
| 6 | GooglePay | MEDIUM | 5600 |
| 7 | Paytm | HIGH | 45000 |
| 8 | Paytm | LOW | 1800 |
| 9 | Paytm | MEDIUM | 300 |
| 10 | PhonePe | HIGH | 55000 |
| 11 | PhonePe | LOW | 6000 |
proc transpose data=risk_summary out=risk_wide(drop=_name_);
by Platform;
id Risk_Level;
var Total_Amount;
run;
proc print data=risk_wide;
run;
OUTPUT:
| Obs | Platform | HIGH | LOW | MEDIUM |
|---|---|---|---|---|
| 1 | BankApp | 170000 | 1300 | 15000 |
| 2 | GooglePay | 116000 | 1200 | 5600 |
| 3 | Paytm | 45000 | 1800 | 300 |
| 4 | PhonePe | 55000 | 6000 | . |
This converts rows into columns for dashboarding.
13. Conclusion
We now built a complete Digital Transactions Fraud Analytics System using SAS using:
PROC SQL
PROC MEANS
PROC FREQ
PROC SGPLOT
MACROS
INTNX, INTCK, MDY
MERGE, APPEND, SET, TRANSPOSE
This project is suitable for:
SAS Programmer Interviews
SAS Programmer Job Seekers
SAS Analysts
No comments:
Post a Comment