# 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