soapdump.sh
edited
1#!/usr/bin/env nix-shell
2#! nix-shell -i bash -p gnugrep gnused coreutils
3
4# PayPal SOAP Log Parser - Structured Output
5# Usage: ./parse_paypal.sh [OPTIONS] <logfile>
6
7show_help() {
8 cat << EOF
9PayPal SOAP Log Parser
10
11USAGE:
12 $0 [OPTIONS] <logfile>
13
14OPTIONS:
15 -h, --help Show this help message
16 -s, --summary Show summary statistics only
17 -r, --raw Output raw structured data (default)
18
19OUTPUT FORMAT (tab-separated):
20 TRANS_NUM|AMOUNT|CURRENCY|FIRSTNAME|LASTNAME|STREET|CITY|STATE|ZIP|CCTYPE|CCLAST4|EXPMONTH|EXPYEAR|CVV|TRANSID|STATUS|CORRID|PROC_AMOUNT
21
22FIELD DESCRIPTIONS:
23 TRANS_NUM - Transaction sequence number
24 AMOUNT - Order total amount
25 CURRENCY - Currency code (USD, etc)
26 FIRSTNAME - Customer first name
27 LASTNAME - Customer last name
28 STREET - Street address
29 CITY - City name
30 STATE - State/Province code
31 ZIP - Postal code
32 CCTYPE - Credit card type (Visa, MasterCard, etc)
33 CCLAST4 - Last 4 digits of credit card
34 EXPMONTH - Card expiration month
35 EXPYEAR - Card expiration year
36 CVV - CVV code
37 TRANSID - PayPal transaction ID
38 STATUS - Transaction status (Success/Failure)
39 CORRID - Correlation ID
40 PROC_AMOUNT - Actually processed amount
41
42EXAMPLES:
43 # Get all transactions
44 $0 payments.log
45
46 # Get only successful transactions
47 $0 payments.log | grep Success
48
49 # Count transactions by state
50 $0 payments.log | cut -d'|' -f8 | sort | uniq -c | sort -nr
51
52 # Find largest transaction
53 $0 payments.log | sort -t'|' -k2 -nr | head -1
54
55 # Get transactions over \$500
56 $0 payments.log | awk -F'|' '\$2 > 500'
57
58 # Summary stats
59 $0 -s payments.log
60
61EOF
62}
63
64# Parse arguments
65SUMMARY_ONLY=false
66while [[ $# -gt 0 ]]; do
67 case $1 in
68 -h|--help)
69 show_help
70 exit 0
71 ;;
72 -s|--summary)
73 SUMMARY_ONLY=true
74 shift
75 ;;
76 -r|--raw)
77 SUMMARY_ONLY=false
78 shift
79 ;;
80 -*)
81 echo "Unknown option $1"
82 show_help
83 exit 1
84 ;;
85 *)
86 LOGFILE="$1"
87 break
88 ;;
89 esac
90done
91
92if [[ -z "$LOGFILE" ]]; then
93 echo "Error: No logfile specified"
94 show_help
95 exit 1
96fi
97
98if [[ ! -f "$LOGFILE" ]]; then
99 echo "Error: File '$LOGFILE' not found"
100 exit 1
101fi
102
103# Extract requests and responses
104REQUESTS=$(sed -nr 's/PPAPIService: Request: (.*)/\1/p' "$LOGFILE")
105RESPONSES=$(sed -nr 's/PPAPIService: Response: <\?.*\?>(.*)/\1/p' "$LOGFILE")
106
107if [[ "$SUMMARY_ONLY" == "true" ]]; then
108 echo "=== SUMMARY ==="
109 TOTAL=$(grep -c "PPAPIService: Request:" "$LOGFILE")
110 SUCCESSFUL=$(grep -c "Success" "$LOGFILE")
111 echo "Total Transactions: $TOTAL"
112 echo "Successful: $SUCCESSFUL"
113 echo "Failed: $((TOTAL - SUCCESSFUL))"
114 echo
115 echo "Top 5 States by Transaction Count:"
116 grep -oP '<ebl:StateOrProvince>\K[^<]+' "$LOGFILE" | sort | uniq -c | sort -nr | head -5
117 echo
118 echo "Transaction Amount Stats:"
119 AMOUNTS=$(grep -oP '<ebl:OrderTotal[^>]*>\K[0-9.]+' "$LOGFILE")
120 TOTAL_AMOUNT=$(echo "$AMOUNTS" | awk '{sum += $1} END {printf "%.2f", sum}')
121 LARGEST=$(echo "$AMOUNTS" | sort -nr | head -1)
122 SMALLEST=$(echo "$AMOUNTS" | sort -n | head -1)
123 echo " Total: \$${TOTAL_AMOUNT}"
124 echo " Largest: \$${LARGEST}"
125 echo " Smallest: \$${SMALLEST}"
126 exit 0
127fi
128
129# Convert responses to array for lookup
130declare -a response_array
131RESP_NUM=1
132while IFS= read -r response_xml; do
133 if [[ -n "$response_xml" ]]; then
134 TRANSID=$(echo "$response_xml" | grep -o '<TransactionID>[^<]*</TransactionID>' | sed 's/<[^>]*>//g' | tr -d '\n\r')
135 STATUS=$(echo "$response_xml" | grep -o '<Ack[^>]*>[^<]*</Ack>' | sed 's/<[^>]*>//g' | tr -d '\n\r')
136 CORRID=$(echo "$response_xml" | grep -o '<CorrelationID[^>]*>[^<]*</CorrelationID>' | sed 's/<[^>]*>//g' | tr -d '\n\r')
137 PROC_AMOUNT=$(echo "$response_xml" | grep -o '<Amount[^>]*>[^<]*</Amount>' | sed 's/<[^>]*>//g' | tr -d '\n\r')
138
139 response_array[$RESP_NUM]="$TRANSID|$STATUS|$CORRID|$PROC_AMOUNT"
140 RESP_NUM=$((RESP_NUM + 1))
141 fi
142done <<< "$RESPONSES"
143
144# Process each request and output structured data
145TRANS_NUM=1
146while IFS= read -r request_xml; do
147 if [[ -n "$request_xml" ]]; then
148 # Extract all fields
149 AMOUNT=$(echo "$request_xml" | grep -o '<ebl:OrderTotal[^>]*>[^<]*</ebl:OrderTotal>' | sed 's/.*>\([0-9.]*\)<.*/\1/')
150 CURRENCY=$(echo "$request_xml" | grep -o 'currencyID="[^"]*"' | sed 's/currencyID="\([^"]*\)"/\1/')
151 FIRSTNAME=$(echo "$request_xml" | grep -o '<ebl:FirstName>[^<]*</ebl:FirstName>' | sed 's/<[^>]*>//g')
152 LASTNAME=$(echo "$request_xml" | grep -o '<ebl:LastName>[^<]*</ebl:LastName>' | sed 's/<[^>]*>//g')
153 STREET=$(echo "$request_xml" | grep -o '<ebl:Street1>[^<]*</ebl:Street1>' | sed 's/<[^>]*>//g')
154 CITY=$(echo "$request_xml" | grep -o '<ebl:CityName>[^<]*</ebl:CityName>' | sed 's/<[^>]*>//g')
155 STATE=$(echo "$request_xml" | grep -o '<ebl:StateOrProvince>[^<]*</ebl:StateOrProvince>' | sed 's/<[^>]*>//g')
156 ZIP=$(echo "$request_xml" | grep -o '<ebl:PostalCode>[^<]*</ebl:PostalCode>' | sed 's/<[^>]*>//g')
157 CCTYPE=$(echo "$request_xml" | grep -o '<ebl:CreditCardType>[^<]*</ebl:CreditCardType>' | sed 's/<[^>]*>//g')
158 CCLAST4=$(echo "$request_xml" | grep -o '<ebl:CreditCardLastFourDigits>[^<]*</ebl:CreditCardLastFourDigits>' | sed 's/<[^>]*>//g')
159 EXPMONTH=$(echo "$request_xml" | grep -o '<ebl:ExpMonth>[^<]*</ebl:ExpMonth>' | sed 's/<[^>]*>//g')
160 EXPYEAR=$(echo "$request_xml" | grep -o '<ebl:ExpYear>[^<]*</ebl:ExpYear>' | sed 's/<[^>]*>//g')
161 CVV=$(echo "$request_xml" | grep -o '<ebl:CVV2>[^<]*</ebl:CVV2>' | sed 's/<[^>]*>//g')
162
163 # Get corresponding response data
164 RESPONSE_DATA="${response_array[$TRANS_NUM]}"
165 if [[ -n "$RESPONSE_DATA" ]]; then
166 IFS='|' read -r TRANSID STATUS CORRID PROC_AMOUNT <<< "$RESPONSE_DATA"
167 else
168 TRANSID=""
169 STATUS=""
170 CORRID=""
171 PROC_AMOUNT=""
172 fi
173
174 # Output structured line (pipe-separated for easy parsing)
175 echo "$TRANS_NUM|${AMOUNT}|${CURRENCY}|${FIRSTNAME}|${LASTNAME}|${STREET}|${CITY}|${STATE}|${ZIP}|${CCTYPE}|${CCLAST4}|${EXPMONTH}|${EXPYEAR}|${CVV}|${TRANSID}|${STATUS}|${CORRID}|${PROC_AMOUNT}"
176
177 TRANS_NUM=$((TRANS_NUM + 1))
178 fi
179done <<< "$REQUESTS"