Panel/backup-website/PAYPAL_DEBUGGING_GUIDE.md

8.3 KiB

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:

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:

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:

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

# 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

grep -i error /modules/billing/logs/paypal_create_order.log
grep -i failed /modules/billing/logs/paypal_capture.log

Find specific request by ID

grep "req_abc123" /modules/billing/logs/paypal_create_order.log
grep "cap_xyz789" /modules/billing/logs/paypal_capture.log

Count successful vs failed requests

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:

# 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

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