Django集成paypalrestsdk遇跨域及ppxo_unhandled_error问题求助
ppxo_unhandled_error Hey there! Let's work through those frustrating errors you're facing while integrating PayPal into your Django app. Moving from a Flask example to Django comes with a few framework-specific quirks, so let's break down how to fix both the No 'Access-Control-Allow-Origin' and ppxo_unhandled_error issues.
1. Fixing the CORS Error
The CORS error happens because your browser's same-origin policy blocks frontend requests from your Django app (e.g., localhost:8000) to your backend when using PayPal's SDK. Here's how to enable cross-origin requests properly:
Step 1: Install Django CORS Headers
First, install the package that handles CORS in Django:
pip install django-cors-headers
Step 2: Update Your settings.py
Add these configurations to your project's settings.py:
# Add to INSTALLED_APPS INSTALLED_APPS = [ # ... other apps 'corsheaders', ] # Add middleware (make sure it's BEFORE CommonMiddleware) MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... other middleware ] # Allow your frontend origin (replace with your production domain later) CORS_ALLOWED_ORIGINS = [ "http://localhost:8000", ] # For development only (disable in production!) # CORS_ALLOW_ALL_ORIGINS = True
Step 3: Restart Your Django Server
After saving changes, restart your server to apply the CORS settings.
2. Resolving the ppxo_unhandled_error
This error usually stems from misconfigured frontend PayPal button code or backend API responses that don't match what PayPal expects. Let's fix both parts:
Fix Frontend PayPal Button Code
Your template's button script needs to handle Django's CSRF protection and correctly communicate with your backend. Update your script to include these key parts:
<div id="paypal-button"></div> <script src="https://www.paypalobjects.com/api/checkout.js"></script> <script> // Helper function to get Django's CSRF token from cookies function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } // Initialize PayPal button paypal.Buttons({ createOrder: function(data, actions) { // Send request to your Django backend to create a PayPal order return fetch('/create-order/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') // Critical for Django POST requests }, body: JSON.stringify({ amount: '10.00' }) // Adjust amount as needed }).then(function(response) { return response.json(); }).then(function(orderData) { // Return the PayPal order ID to the SDK return orderData.id; }).catch(function(error) { console.error('Error creating order:', error); }); }, onApprove: function(data, actions) { // Capture the order after approval return fetch('/capture-order/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') }, body: JSON.stringify({ orderID: data.orderID }) }).then(function(response) { return response.json(); }).then(function(details) { alert('Payment successful! Thank you, ' + details.payer.name.given_name); // Add logic here to update your database or send confirmation }).catch(function(error) { console.error('Error capturing order:', error); }); } }).render('#paypal-button'); </script>
Fix Backend View Functions
Make sure your views.py functions return valid JSON responses and correctly interact with the PayPal SDK:
from django.http import JsonResponse import paypalrestsdk # Configure PayPal SDK (use your own credentials!) paypalrestsdk.configure({ "mode": "sandbox", # Switch to "live" for production "client_id": "YOUR_PAYPAL_CLIENT_ID", "client_secret": "YOUR_PAYPAL_CLIENT_SECRET" }) def create_order(request): if request.method != 'POST': return JsonResponse({'error': 'Method not allowed'}, status=405) # Get amount from frontend request amount = request.POST.get('amount', '10.00') # Create PayPal order order = paypalrestsdk.Order({ "intent": "CAPTURE", "purchase_units": [{ "amount": { "currency_code": "USD", "value": amount } }] }) if order.create(): # Return the order ID to the frontend return JsonResponse({'id': order.id}) else: # Return error details if order creation fails return JsonResponse({'error': order.error}, status=400) def capture_order(request): if request.method != 'POST': return JsonResponse({'error': 'Method not allowed'}, status=405) order_id = request.POST.get('orderID') order = paypalrestsdk.Order.find(order_id) if order.capture(): # Return capture details to frontend return JsonResponse(order.to_dict()) else: return JsonResponse({'error': order.error}, status=400)
Verify URL Routes
Ensure your urls.py maps the frontend requests to the correct views:
from django.urls import path from . import views urlpatterns = [ # ... other routes path('create-order/', views.create_order, name='create_order'), path('capture-order/', views.capture_order, name='capture_order'), ]
3. Quick Debugging Tips
- Check your browser's developer tools (F12): Look at the Network tab to see if your backend requests are returning errors (like 403 CSRF or 500 server errors).
- Confirm PayPal credentials: Double-check that your client ID/secret are correct and match the sandbox/live mode you're using.
- Test in sandbox mode first: Use PayPal's sandbox accounts to simulate payments before going live.
内容的提问来源于stack exchange,提问作者Axil

