Panel/Website/PAYPAL_DEBUGGING_GUIDE.md

316 lines
8.3 KiB
Markdown

# 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