diff --git a/modules/billing/PAYPAL_DEBUGGING_GUIDE.md b/modules/billing/PAYPAL_DEBUGGING_GUIDE.md new file mode 100644 index 00000000..4ca1a132 --- /dev/null +++ b/modules/billing/PAYPAL_DEBUGGING_GUIDE.md @@ -0,0 +1,316 @@ +# PayPal Payment Flow Debugging Guide + +## Overview + +This guide explains how to diagnose and troubleshoot PayPal payment errors using the comprehensive logging system that has been added to the payment flow. + +## Problem Being Addressed + +Users were experiencing intermittent errors when clicking "Pay from PayPal" button: +- JSON parsing errors +- HTTP ERROR 500 +- "Currently unable to handle this request" errors + +These errors would "flip-flop" between different error types, making it difficult to diagnose the root cause. + +## Log Files Location + +All logs are stored in: `/modules/billing/logs/` + +### Available Log Files + +1. **`paypal_create_order.log`** - Logs all PayPal order creation requests + - When: Created when user clicks "Pay with PayPal" button + - Contains: Request data, OAuth tokens, PayPal API responses + +2. **`paypal_capture.log`** - Logs all payment capture attempts + - When: Created when PayPal redirects user back after approving payment + - Contains: Capture requests, database operations, order creation + +3. **`client_errors.log`** - Logs JavaScript errors from browser + - When: Created when browser encounters errors during checkout + - Contains: Client-side errors, PayPal SDK issues, network failures + +## How to Debug Payment Issues + +### Step 1: Identify the Request + +Each request has a unique ID for tracking: +- Create order requests: `req_XXXXX` +- Capture order requests: `cap_XXXXX` + +Look for these IDs in error messages shown to users. + +### Step 2: Check the Logs + +#### For "Failed to create order" errors: + +```bash +tail -100 /modules/billing/logs/paypal_create_order.log +``` + +Look for: +- `JSON_DECODE_ERROR` - Invalid input from cart.php +- `OAUTH_CURL_ERROR` or `OAUTH_HTTP_ERROR` - Can't connect to PayPal +- `CREATE_ORDER_HTTP_ERROR` - PayPal rejected the order + +#### For "Payment capture failed" errors: + +```bash +tail -100 /modules/billing/logs/paypal_capture.log +``` + +Look for: +- `OAUTH_*_ERROR` - Authentication issues +- `CAPTURE_HTTP_ERROR` - PayPal rejected capture +- `DB_CONNECTION_FAILED` - Database issues +- `UPDATE_INVOICES_FAILED` - Can't mark invoices as paid +- `ORDER_CREATE_FAILED` - Can't create order record + +#### For client-side errors: + +```bash +tail -100 /modules/billing/logs/client_errors.log +``` + +Look for: +- Network errors (fetch failed) +- PayPal SDK errors +- JSON parsing errors + +### Step 3: Common Issues and Solutions + +#### Issue: OAuth fails (OAUTH_HTTP_ERROR) + +**Log entry example:** +``` +[2025-10-29 21:30:00] [req_12345] OAUTH_HTTP_ERROR +http_code => 401 +``` + +**Cause:** Invalid PayPal credentials + +**Solution:** Check that `$client_id` and `$client_secret` in `api/create_order.php` and `api/capture_order.php` are correct. + +--- + +#### Issue: JSON decode error + +**Log entry example:** +``` +[2025-10-29 21:30:00] [req_12345] JSON_DECODE_ERROR +error => Syntax error +``` + +**Cause:** Malformed JSON from cart.php or corrupted request + +**Solution:** +1. Check the `RAW_INPUT` entry before the error +2. Verify cart.php is sending valid JSON +3. Check for PHP errors that might corrupt the output + +--- + +#### Issue: PayPal returns error creating order + +**Log entry example:** +``` +[2025-10-29 21:30:00] [req_12345] CREATE_ORDER_HTTP_ERROR +http_code => 400 +response => {"name":"INVALID_REQUEST","details":[{"issue":"..."}]} +``` + +**Cause:** Invalid order data sent to PayPal + +**Solution:** +1. Look at `PAYPAL_ORDER_PAYLOAD` entry to see what was sent +2. Common issues: + - Invalid amount format (must be 2 decimals) + - Invalid currency code + - Malformed items array + - Invalid URLs (return_url, cancel_url must be absolute URLs) + +--- + +#### Issue: Database connection failed + +**Log entry example:** +``` +[2025-10-29 21:30:00] [cap_12345] DB_CONNECTION_FAILED +error => Access denied for user +``` + +**Cause:** Can't connect to database + +**Solution:** +1. Check database credentials in `includes/config.inc.php` +2. Verify database server is running +3. Check database permissions + +--- + +#### Issue: Invoice update failed + +**Log entry example:** +``` +[2025-10-29 21:30:00] [cap_12345] UPDATE_INVOICES_FAILED +error => Table 'ogp_billing_invoices' doesn't exist +``` + +**Cause:** Database schema issue + +**Solution:** +1. Verify table exists and has correct name +2. Check `$table_prefix` variable in config +3. Run database migrations if needed + +## Log Entry Structure + +Each log entry includes: + +``` +[TIMESTAMP] [REQUEST_ID] LOG_LABEL +key => value +key => value +-------------------------------------------------------------------------------- +``` + +- **TIMESTAMP**: When the event occurred (Y-m-d H:i:s format) +- **REQUEST_ID**: Unique identifier for tracking the request +- **LOG_LABEL**: What happened (e.g., OAUTH_SUCCESS, CREATE_ORDER_FAILED) +- **Data**: Relevant data for the event (arrays/objects pretty-printed) + +## Request Flow with Logging + +### Creating an Order + +1. User clicks "Pay with PayPal" in cart.php +2. JavaScript calls `api/create_order.php` +3. Logs generated: + - `REQUEST_START` - Initial request info + - `RAW_INPUT` - What was received + - `PARSED_INPUT` - Decoded data + - `OAUTH_REQUEST_START` - Starting OAuth + - `OAUTH_RESPONSE` - OAuth result + - `OAUTH_SUCCESS` or `OAUTH_*_ERROR` + - `CREATE_ORDER_REQUEST_START` - Sending to PayPal + - `CREATE_ORDER_RESPONSE` - PayPal's response + - `CREATE_ORDER_SUCCESS` or `CREATE_ORDER_*_ERROR` + +### Capturing Payment + +1. User approves payment on PayPal +2. PayPal redirects back to site +3. JavaScript calls `api/capture_order.php` +4. Logs generated: + - `REQUEST_START` - Initial request + - `RAW_INPUT` - Order ID received + - `PARSED_INPUT` - Decoded data + - `OAUTH_*` - Authentication steps + - `CAPTURE_REQUEST_START` - Starting capture + - `CAPTURE_RESPONSE` - PayPal's response + - `CAPTURE_SUCCESS` or `CAPTURE_*_ERROR` + - `PAYMENT_DETAILS` - Extracted transaction info + - `STARTING_DB_PROCESSING` - Beginning database work + - `DB_CONNECTED` - Database ready + - `SESSION_INFO` - User session details + - `PROCESSING_INVOICES` - Starting invoice processing + - `UPDATE_INVOICES_*` - Invoice update results + - `PROCESSING_INVOICE` - For each invoice + - `NEW_ORDER_DETECTED` or `RENEWAL_DETECTED` + - `ORDER_CREATE_*` or `ORDER_EXTENDED_*` + - `PROCESSING_COMPLETE` - Done + +## Monitoring Tips + +### Watch logs in real-time + +```bash +# Watch create order logs +tail -f /modules/billing/logs/paypal_create_order.log + +# Watch capture logs +tail -f /modules/billing/logs/paypal_capture.log + +# Watch all logs +tail -f /modules/billing/logs/*.log +``` + +### Filter for errors only + +```bash +grep -i error /modules/billing/logs/paypal_create_order.log +grep -i failed /modules/billing/logs/paypal_capture.log +``` + +### Find specific request by ID + +```bash +grep "req_abc123" /modules/billing/logs/paypal_create_order.log +grep "cap_xyz789" /modules/billing/logs/paypal_capture.log +``` + +### Count successful vs failed requests + +```bash +grep -c "CREATE_ORDER_SUCCESS" /modules/billing/logs/paypal_create_order.log +grep -c "CREATE_ORDER.*ERROR" /modules/billing/logs/paypal_create_order.log +``` + +## Log Rotation + +Logs will grow over time. Consider implementing log rotation: + +```bash +# Archive old logs +cd /modules/billing/logs +gzip paypal_create_order.log +mv paypal_create_order.log.gz paypal_create_order.$(date +%Y%m%d).log.gz +touch paypal_create_order.log +``` + +Or use logrotate: + +``` +/path/to/modules/billing/logs/*.log { + daily + rotate 7 + compress + delaycompress + notifempty + create 0644 www-data www-data +} +``` + +## Error Messages to Users + +When errors occur, users now see messages with request IDs: + +- "Failed to create order: API error 500 (Ref: req_abc123)" +- "Payment capture failed: oauth_fail (Ref: cap_xyz789)" + +Use these reference IDs to search the logs for the full details. + +## Getting Help + +When reporting issues, include: + +1. The exact error message shown to user (including Ref ID) +2. Relevant log entries (search by Ref ID) +3. What the user was trying to do +4. Whether it's consistent or intermittent +5. Browser console output (F12 → Console tab) + +## Additional Resources + +- PayPal API Documentation: https://developer.paypal.com/api/rest/ +- PayPal Sandbox Testing: https://developer.paypal.com/developer/accounts/ +- PayPal Error Codes: https://developer.paypal.com/api/rest/reference/orders/v2/errors/ + +## Changelog + +### 2025-10-29 +- Added comprehensive logging to create_order.php +- Enhanced logging in capture_order.php +- Added client-side error logging +- Created debugging guide diff --git a/modules/billing/QUICK_DEBUG_REFERENCE.md b/modules/billing/QUICK_DEBUG_REFERENCE.md new file mode 100644 index 00000000..5822eb26 --- /dev/null +++ b/modules/billing/QUICK_DEBUG_REFERENCE.md @@ -0,0 +1,186 @@ +# PayPal Payment Flow - Quick Debug Reference + +## Quick Commands + +### View recent errors: +```bash +cd /home/runner/work/GSP/GSP/modules/billing/logs + +# Last 50 lines of create order log +tail -50 paypal_create_order.log + +# Last 50 lines of capture log +tail -50 paypal_capture.log + +# Last 50 lines of client errors +tail -50 client_errors.log +``` + +### Watch logs live: +```bash +# In terminal, run: +tail -f /home/runner/work/GSP/GSP/modules/billing/logs/paypal_*.log +``` + +### Search for specific error: +```bash +# Find all OAuth errors +grep "OAUTH.*ERROR" paypal_create_order.log paypal_capture.log + +# Find database errors +grep "DB.*FAILED" paypal_capture.log + +# Find a specific request by ID +grep "req_12345" paypal_create_order.log +``` + +## Common Error Patterns + +### ❌ "JSON error" or "unable to handle this request" + +**What to check:** +1. Browser console (F12 → Console tab) for JavaScript errors +2. `client_errors.log` for client-side issues +3. `paypal_create_order.log` for `JSON_DECODE_ERROR` + +**Quick fix:** +- Check if cart items are valid +- Verify amount calculations are correct +- Look for PHP errors that might corrupt JSON output + +--- + +### ❌ HTTP ERROR 500 + +**What to check:** +1. `paypal_create_order.log` for `CREATE_ORDER_HTTP_ERROR` +2. `paypal_capture.log` for `CAPTURE_HTTP_ERROR` +3. Look for `OAUTH.*ERROR` entries + +**Quick fix:** +- Verify PayPal credentials are correct +- Check PayPal API status: https://www.paypal-status.com/ +- Verify sandbox vs live mode settings match credentials + +--- + +### ❌ Payment seems successful but no order created + +**What to check:** +1. `paypal_capture.log` for `DB_CONNECTION_FAILED` +2. Look for `UPDATE_INVOICES_FAILED` +3. Check `ORDER_CREATE_FAILED` + +**Quick fix:** +- Verify database connection settings +- Check if `ogp_billing_invoices` table exists +- Verify `ogp_billing_orders` table exists +- Check table permissions + +--- + +### ❌ Intermittent failures (works sometimes, fails sometimes) + +**What to check:** +1. Compare successful vs failed requests in logs +2. Look for timeout errors (`CURL.*ERROR`) +3. Check for database connection pool exhaustion + +**Quick fix:** +- Check server load/resources +- Verify network connectivity to PayPal API +- Check for rate limiting + +## Log File Locations + +``` +/home/runner/work/GSP/GSP/modules/billing/logs/ +├── paypal_create_order.log # Order creation (when clicking "Pay") +├── paypal_capture.log # Payment capture (after PayPal approval) +└── client_errors.log # JavaScript/browser errors +``` + +## Request ID Format + +- Create order: `req_XXXXXXXXXXXXX` +- Capture order: `cap_XXXXXXXXXXXXX` + +When user sees an error with `(Ref: req_abc123)`, search logs for that ID. + +## Important Log Labels + +### Create Order Flow: +- `REQUEST_START` → `RAW_INPUT` → `PARSED_INPUT` +- `OAUTH_REQUEST_START` → `OAUTH_SUCCESS` +- `CREATE_ORDER_REQUEST_START` → `CREATE_ORDER_SUCCESS` + +### Capture Order Flow: +- `REQUEST_START` → `PARSED_INPUT` +- `OAUTH_SUCCESS` → `CAPTURE_SUCCESS` +- `DB_CONNECTED` → `PROCESSING_INVOICES` +- `ORDER_CREATED_SUCCESS` or `ORDER_EXTENDED_SUCCESS` + +### Error Labels: +- `*_ERROR` - Something went wrong +- `*_FAILED` - Operation failed +- `INVALID_*` - Invalid input/data + +## Browser Console Debugging + +1. Open cart page +2. Press F12 to open DevTools +3. Go to Console tab +4. Click "Pay with PayPal" +5. Watch for: + - Red error messages + - `PayPal Error:` logs + - Network errors (check Network tab) + +## Testing Checklist + +When testing payments: + +- [ ] Check browser console for errors +- [ ] Note the Ref ID if error occurs +- [ ] Check `paypal_create_order.log` for the request +- [ ] Check `paypal_capture.log` if got past order creation +- [ ] Verify database tables exist and have data +- [ ] Check PayPal sandbox account activity + +## Need More Help? + +See full guide: `PAYPAL_DEBUGGING_GUIDE.md` + +## Key Configuration Files + +- PayPal credentials: `api/create_order.php` and `api/capture_order.php` + - Lines 5-6: `$client_id` and `$client_secret` + - Line 4: `$sandbox` (true/false) + +- Database config: `includes/config.inc.php` + - `$db_host`, `$db_user`, `$db_pass`, `$db_name` + - `$table_prefix` + +## Status Checklist for Issues + +When user reports error: + +1. **Get details:** + - [ ] What error message did they see? + - [ ] What was the Ref ID (if shown)? + - [ ] Can they reproduce it? + +2. **Check logs:** + - [ ] Find the request by Ref ID + - [ ] Look for ERROR or FAILED labels + - [ ] Check surrounding context (before/after) + +3. **Verify config:** + - [ ] PayPal credentials valid? + - [ ] Database connection working? + - [ ] Correct sandbox/live mode? + +4. **Test:** + - [ ] Try creating test order + - [ ] Watch logs in real-time + - [ ] Check database for created records