在Django-Oscar中配置PayPal及信用卡支付的问题求助
Hey there, let’s work through your Django-Oscar payment integration headaches step by step. I’ve been in your shoes—Oscar’s payment docs can be sparse, but we can get this sorted.
First: Fixing django-oscar-paypal’s Credit Card Support
First off, django-oscar-paypal’s Express Checkout is built for PayPal account payments, not direct credit card checkout. For card payments, you need to use its Payflow Pro module, which you probably haven’t configured yet. Here’s how to set it up:
1. Add Payflow Pro Credentials to Settings
Head to your settings.py and add your PayPal Payflow account details (you’ll need to sign up for a Payflow account on PayPal’s dev platform first):
# PayPal Payflow Pro Configuration PAYPAL_PAYFLOW_USER = "your-payflow-username" PAYPAL_PAYFLOW_VENDOR = "your-payflow-merchant-id" PAYPAL_PAYFLOW_PARTNER = "PayPal" # This is a fixed value PAYPAL_PAYFLOW_PASSWORD = "your-payflow-password" PAYPAL_PAYFLOW_PRODUCTION = False # Keep False for testing, switch to True for live
2. Wire Up Payflow’s URLs
In your project’s urls.py, add the routes for Payflow’s payment views:
from oscar_paypal.payflow import views as payflow_views urlpatterns += [ # Mount Payflow Pro payment routes path("paypal/payflow/", include((payflow_views.get_urls(), "payflow"), namespace="payflow")), ]
3. Update Your Checkout Template
The "Credit Card Checkout" button you’re using is pointing to an unimplemented page. Swap its URL to point to Payflow’s payment details page:
<!-- Replace your existing credit card button link --> <a href="{% url 'payflow:payment-details' %}" class="btn btn-primary">Pay with Credit Card</a>
4. Activate the Payflow Payment Method
Log into your Oscar admin dashboard, go to Dashboard > Payment methods, and add a new payment method. Link it to the oscar_paypal.payflow.gateway.PayflowProGateway and mark it as "active". This ensures Oscar recognizes it as a valid payment option in the checkout flow.
Fixing the Empty Payment Method on the Preview Page
That empty payment method issue usually happens because the payment method isn’t properly registered or selected in the checkout flow:
- Double-check that
oscar_paypalis in bothINSTALLED_APPSandOSCAR_PAYMENT_APPSin your settings:OSCAR_PAYMENT_APPS = [ 'oscar_paypal', # Add other payment apps here ] - Make sure your
OSCAR_CHECKOUT_PIPELINEincludes thepayment_methodstep—this is where users select their payment option before reaching the preview page. - Test the checkout flow end-to-end: Ensure you actually select the Payflow credit card option before moving to the order preview. If you skip selecting a payment method, the preview page will show nothing.
Better Alternatives for Payment Integration
If django-oscar-paypal feels too clunky (and let’s be real, its docs are lacking), Stripe is a way better option—their docs are top-tier, and they support all major credit cards, Apple Pay, Google Pay, etc. Here’s a quick rundown of how to integrate it:
1. Set Up Stripe
- Install the Stripe library:
pip install stripe - Add your Stripe keys to
settings.py:STRIPE_PUBLIC_KEY = "your-stripe-public-key" STRIPE_SECRET_KEY = "your-stripe-secret-key"
2. Build a Custom Payment View
Create a view that extends Oscar’s PaymentDetailView to generate a Stripe Payment Intent (this handles the payment processing on Stripe’s end):
import stripe from django.conf import settings from oscar.apps.checkout.views import PaymentDetailView stripe.api_key = settings.STRIPE_SECRET_KEY class StripePaymentView(PaymentDetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Convert order total to cents (Stripe requires amounts in smallest currency unit) amount = int(self.order.total_incl_tax * 100) # Create a Payment Intent tied to the order intent = stripe.PaymentIntent.create( amount=amount, currency="usd", # Adjust this to your store's currency metadata={"order_id": self.order.id} ) context["stripe_client_secret"] = intent.client_secret context["stripe_public_key"] = settings.STRIPE_PUBLIC_KEY return context
3. Add Stripe Elements to Your Template
Use Stripe’s pre-built Elements to collect credit card info securely (no need to handle raw card data yourself):
<!-- Load Stripe's JS library --> <script src="https://js.stripe.com/v3/"></script> <!-- Stripe Elements container --> <div id="card-element" class="form-control"></div> <button id="pay-btn" class="btn btn-primary mt-3">Complete Payment</button> <script> const stripe = Stripe("{{ stripe_public_key }}"); const elements = stripe.elements(); const cardElement = elements.create("card"); cardElement.mount("#card-element"); document.getElementById("pay-btn").addEventListener("click", async () => { const { error, paymentIntent } = await stripe.confirmCardPayment( "{{ stripe_client_secret }}", { payment_method: { card: cardElement } } ); if (error) { // Handle payment errors (e.g., invalid card) alert(error.message); } else { // Payment succeeded—redirect to thank you page window.location.href = "{% url 'checkout:thank-you' %}"; } }); </script>
4. Verify Payment and Update Order
After the payment succeeds, you’ll want to verify the Payment Intent status via Stripe’s API and mark the Oscar order as paid. You can do this in a post-payment view or using webhooks (webhooks are more reliable for production).
Quick Tips to Avoid Headaches
- Use test cards for testing: PayPal and Stripe provide dummy card numbers (like Stripe’s
4242 4242 4242 4242) to avoid using real payment info. - Double-check your checkout pipeline: Make sure
payment_detailsandsubmit_orderare included inOSCAR_CHECKOUT_PIPELINE—these steps are critical for processing payments. - If building a custom payment gateway, implement Oscar’s
PaymentGatewayinterface to ensure payment statuses sync correctly with orders.
内容的提问来源于stack exchange,提问作者MadPhysicist

