how to deal with returnurl in django-paypal for pa

2019-07-16 13:44发布

I am now developing my site using django. In integrating my site with paypal, I use pluggable application "http://github.com/johnboxall/django-paypal". Although the document is very clear for "Using PayPal Payments Pro (WPP)", but I still have some questions, especially the relationship between "returnurl" and "confirm_template".

#views.py
from paypal.pro.views import PayPalPro

def buy_my_item(request):
   item = {"amt": "10.00",             # amount to charge for item
           "inv": "inventory",         # unique tracking variable paypal
           "custom": "tracking",       # custom tracking variable for you
           "cancelurl": "http://...",  # Express checkout cancel url
           "returnurl": "http://..."}  # Express checkout return url

   kw = {"item": item,                            # what you're selling
         "payment_template": "payment.html",      # template name for payment
         "confirm_template": "confirmation.html", # template name for confirmation
         "success_url": "/success/"}              # redirect location after success

   ppp = PayPalPro(**kw)
   return ppp(request)

When clicking the "continue" button on paypal site, it redirects me back to "returnurl". Here, is my problem, I don't know how to deal with this returnurl. In my opinion, I should also write a function to make it render confirmation.html. Am I right? If so, how to write this function. Really grateful for any help and instructions.

2条回答
孤傲高冷的网名
2楼-- · 2019-07-16 13:49

The documentation isn't great for django-paypal. The short answer is that your returnurl should be whatever URL points to your method buy_my_item. Here's a few examples taken from something I have working IRL. Note that I use PayPal's "useraction=commit" option to reduce the number of steps in their Express Checkout.

In your urls.py:

url(r'^pay-now/', views.pay_now, name='pay_now'),
url(r'^purchase-thanks/$', views.purchase_thanks, name='pay_success'),
url(r'^purchase-cancelled/$', views.purchase_thanks, name='pay_cancel'),

In your views.py:

""" User payment method endpoint for rendering and processing forms. """
@csrf_exempt
def pay_now( request ):
    # Override django-paypal library endpoints to include 'useraction=commit'
    # which changed PayPal's review page to be a 'pay now' page.
    # This is ugly but I didn't want to subclass.
    from paypal.pro import views as pro_views
    pro_views.EXPRESS_ENDPOINT = "https://www.paypal.com/webscr?cmd=_express-checkout&useraction=commit&%s"
    pro_views.SANDBOX_EXPRESS_ENDPOINT = "https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&useraction=commit&%s"

    # ...because we use 'useraction=commit', there's no need to show the confirm page.
    # So let's change the request to show the confirmation form into a request to
    # approve it. It just so happens that the arguments are the same -- the difference
    # is between the GET and the POST.
    # <input type="hidden" name="token" value="EC-485941126E653491T" id="id_token"/>
    # <input type="hidden" name="PayerID" value="78W69D3FEVWJBC" id="id_PayerID"/>
    if request.method == 'GET' and 'token' in request.GET and 'PayerID' in request.GET:
        request.method = 'POST'
        request.POST = request.GET # Crudely convert GET to POST

    item = {
        'amt':           99.99, # Amount to charge for item
        'currencycode':  'usd',
        #'inv':           1, # Unique tracking variable paypal - must be a number.
        #'desc':          'Your product name', # Deprecated by PayPal, don't bother
                                               # (you'll get the name twice in your statement otherwise)
        'custom':        'custom1', # Custom tracking variable for you. Realistically you have to pass
                                    # this if you're specifying basket contents to PayPal as django-paypal
                                    # won't be given `item_name` in the IPN, only `item_name1` etc.
                                    # which it cannot interpret.
        'cancelurl':     'http://%s%s' % DYNAMIC_URL, reverse('pay_cancel')), # Express checkout cancel url
        'returnurl':     'http://%s%s' % (DYNAMIC_URL, reverse('pay_now')), # Express checkout return url
        'allownote':     0, # Disable "special instructions for seller"
        'l_name0':       'Your product name',
        #'l_number0':    1234,
        #'l_desc0':      'longer description',
        'l_amt0':        99.99,
        'l_qty0':        1,
        'itemamt':       99.99,
        #'taxamt':       0.00,
        #'shippingamt':  0.00,
        #'handlingamt':  0.00,
        #'shipdiscamt':  0.00,
        #'insuranceamt': 0.00,
    }

    kw = {
        'item': item,
        'payment_template': 'cms/register.html', # Template name for payment
        'confirm_template': 'cms/paypal-confirmation.html', # Template name for confirmation
        'success_url':      reverse('pay_success'), # Ultimate return URL
    }

    ppp = PayPalPro(**kw)
    return ppp(request)

You may have a bunch of other questions, like "how can I tell the difference between an EC and a WPP payment when I get to the payment confirmation page?", but I'll save that until it's asked! django-paypal isn't bad, but it can be pretty frustrating making it work, particularly when you want to pass additional values to your templates, and the documentation (even on the forks I've seen) isn't much good.

Note that this example refers to HTTP rather than HTTPS URLs. In production, using WPP, you'll almost certainly want to be using HTTPS. Also, the main distribution of the product is out of date, and you'll need to patch the IPN endpoint with @csrf_exempt to make it work.

查看更多
贪生不怕死
3楼-- · 2019-07-16 13:49

Hi guys i'm with the same problem, according to this http://uswaretech.com/blog/2008/11/using-paypal-with-django/ we need to write a view that handle response from paypal, so i use confirm.html template but it doesn't render anything...

查看更多
登录 后发表回答