Using Paypal with Django

By : Shabda Raaj

Paypal has a comprehensive API to use their services programatically. The ExpressCheckout API allows you to get the user's details and then process the payments on your servers. They include a SOAP and NVP API. With NVP you do a GET to the Paypal servers with Url encoded values, get responses in plain text and work with them.

The basic flow for ExpressCheckout is something like this,

  1. You make a SetExpressCheckout request to Paypal, passing your credentials and and the amount you want to charge etc.
  2. Paypal returns an response with ACK of SUCCESS and token which you need to pass to subsequent requests.
  3. You transfer the user to Paypal site, passing the token returned in step 2.
  4. User logs in, and authorises transfer. Paypal redirects back to the SUCCESS_URL specified in step 1, passing the token and PayerID.
  5. You make a GetExpressCheckoutDetails request to Paypal, apssing token, payer id and other details.
  6. Paypal returns the user's and transactions details.
  7. You ask user to confirm details.
  8. You make a DoExpressCheckoutPayment request to Paypal. At this point the money is transferred from user's account to your account.

Now you can do the requests to Paypal very simply by sending requests, (it is just Url encoded name-value pair), but here is a Django snippet to make this wonderfully easy.

Before you can make requests to Paypal, servers you need to get API credentials. While developing your app, you of course, do not want to use actual Paypal money. Paypal makes available a sandbox where you can use virtual money before you go live.

  1. Go to developer.paypal.com and request a new sandbox API credentials.
  2. (Optionally)Read https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_api_reference to understand how does the Paypal NVP api works.
  3. We would two pages. [a] View 1: Where we do SetExpressCheckout and show a link to Paypal. [b] View 2: Where we do GetExpressCheckoutDetails, get the user's details, get a confirm from user. On a confirmation from user we post to the same page and do a DoExpressCheckoutPayment.

[Totally untested code ahead. I am copying and simplifying from one of our applications.]

#view 1

def veiw1(request):
        ...........
    pp = paypal.PayPal()
    token = pp.SetExpressCheckout(...)
    paypal_url = pp.PAYPAL_URL + token
    payload = {'paypal_url':paypal_url}
    return render_to_response('template1.html', payload, RequestContext(request))

In the template send user to {{ paypal_url }} when they want to pay.

#View 2
#View 2 would be called after Paypal redirects after user authorises the transfer.

def view2(request):
    token = request.GET.get('token', '')
    pp = paypal.PayPal()
    if request.method == 'GET':
        paypal_details = pp.GetExpressCheckoutDetails(token, return_all = True)
        payload = {}
        if 'Success' in paypal_details['ACK']:
            payload['ack'] = True
            token = paypal_details['TOKEN'][0]
            first_name = paypal_details['FIRSTNAME'][0]
            .....
        return render_to_response('template2.html', payload, RequestContext(request))
    if request.method == POST:
        payment_details  = pp.DoExpressCheckoutPayment(token = token)
        if 'Success' in payment_details['ACK']:
            pass
            #We have been paid. DO things like, enable subsciprion, ship goods etc.
            return HttpResponseRedirect(payment_done_url)

Here in template2.html, we show the user/transaction details, and a on user's confirmation do a post to the same url. This should help you get started with integrating Paypal with Django.

Resources.

  1. Paypal developer forums
  2. Paypal developer documentation

Need to build a Paypal enabled webapp? We can help


Related Posts


Can we help you build amazing apps? Contact us today.

Topics : tips paypal

Comments

Yashh

Awesome. something I wanted to play with... cool!!

commmenttor
Josh

I'm a little confused about the order in which you're doing things in your example. It seem to me that your view1 is like a checkout page where they see the details of the purchase and then have a link by which they can choose to pay with PayPal (and possibly other links to pay with other methods). The click that link, are taken to the PayPal site where they log in and confirm the transaction, then are taken back to your site at view2 where they confirm the transaction again? I guess I'm just not getting the flow here. Why isn't their having logged into PayPal and confirmed there enough to actually process the payment as soon as they're returned to your site?

commmenttor
Lakshman 13th Nov., 2008

Josh: This is so you can do the checkout on your own site. You get the details of user who authorised the transaction, and then do the checkout on _your_ site, not on paypal's.

commmenttor
omtv

Quite a useful script, thanks a lot!

commmenttor
Peter

I don't see the purpose of having the user confirm twice (the second time on your site). Why not just issue the DoExpressCheckoutPayment() after they have hit your "success" view? I mean without a valid token the transaction will not be processed anyways.

Seems like the extra step isn't really needed.

I personally still use IPN for my payment processing app but I have been looking into this method lately. Simply because sometimes IPN has a delay in the confirmation and my customers end up waiting a minute or two before they can download their purchase. PITA.

commmenttor
ZooKeeper 12th Jan., 2009

Thank you so much!

Is there going to be an updated version of this snippet?

commmenttor
SpongieFan 26th May, 2009

So where's an example for a directpayment? Not everyone is using expresscheckout ya know...
Thanks!

commmenttor
Dhruv

I didnt get this part

'Go to developer.paypal.com and request a new sandbox API credentials. '

I went there , made account, created API credentials and under then under test accounts I see some information. What I dont know is how to use that information in the code. What information to be used and where in the code?

Help please.

Thanks,
Dhruv

commmenttor
Adobe Business Catalyst

Very useful for my ecommerce site im developing! Thank!

commmenttor
Arno Smi

I keep getting a error 500 sent from paypals ipn any ideas why?

commmenttor
shabda

@arno

What step?

commmenttor
seo

seo(搜索引擎優化)是我們主要業務,為大型企業網絡提供SEO搜尋引擎最佳化解決方案;數千家中大型企業網站營銷策劃經驗,提供企業SEO培訓,整站優化方案制定,整站優化實施,百度網站收錄恢復,網站重構壹條龍服務

commmenttor
dariush 13th April, 2010

thank you this helpful information.

I somehow get the following error message when during "request.method == 'POST'":

"The view ecomstore.checkout.views.process_paypal didn't return an HttpResponse object."

My view code:
BEGIN
def process_paypal(request, template_name='checkout/order_confirm.html'):
""" Paypal API GetExpressCheckoutDetails """
token = request.GET.get('token', '')
transaction_id = request.GET.get('transaction_id', '')
amount_with_ship_price = request.GET.get('amt', '')
pp = paypal.PayPal()
if request.method == 'GET':
paypal_details = pp.GetExpressCheckoutDetails(token, return_all = True)
payload = {}
if 'Success' in paypal_details['ACK']:
payload['ack'] = True
if paypal_details['TOKEN'][0] == token: # Make sure TOKEN matches the value in SetExpressCheckout response
token = paypal_details['TOKEN'][0]
email_adress = paypal_details['EMAIL'][0]
...
else:
error_message = u'TOKEN from GetExpressCheckoutDetails does not match the SetExpressCheckout response TOKEN'
form = CheckoutForm()
page_title = 'Order Confirm'
return render_to_response(template_name, locals(), context_instance=RequestContext(request))
if request.method == 'POST':
payment_details = pp.DoExpressCheckoutPayment(token = token, payer_id = transaction_id, amt = amount_with_ship_price)
if 'Success' in payment_details['ACK']:
request.session['order_number'] = order_number
receipt_url = urlresolvers.reverse('checkout_receipt')
return HttpResponseRedirect(receipt_url)
END

I don't know if there is anything wrong with the indentation.

Thank you for your help.

commmenttor
dariush 13th April, 2010

thank you this helpful information.

I somehow get the following error message when during "request.method == 'POST'":

"The view ecomstore.checkout.views.process_paypal didn't return an HttpResponse object."

My view code:

def process_paypal(request, template_name='checkout/order_confirm.html'):
""" Paypal API GetExpressCheckoutDetails """
token = request.GET.get('token', '')
transaction_id = request.GET.get('transaction_id', '')
amount_with_ship_price = request.GET.get('amt', '')
pp = paypal.PayPal()
if request.method == 'GET':
paypal_details = pp.GetExpressCheckoutDetails(token, return_all = True)
payload = {}
if 'Success' in paypal_details['ACK']:
payload['ack'] = True
if paypal_details['TOKEN'][0] == token: # Make sure TOKEN matches the value in SetExpressCheckout response
token = paypal_details['TOKEN'][0]
email_adress = paypal_details['EMAIL'][0]
...
else:
error_message = u'TOKEN from GetExpressCheckoutDetails does not match the SetExpressCheckout response TOKEN'
form = CheckoutForm()
page_title = 'Order Confirm'
return render_to_response(template_name, locals(), context_instance=RequestContext(request))
if request.method == 'POST':
payment_details = pp.DoExpressCheckoutPayment(token = token, payer_id = transaction_id, amt = amount_with_ship_price)
if 'Success' in payment_details['ACK']:
request.session['order_number'] = order_number
receipt_url = urlresolvers.reverse('checkout_receipt')
return HttpResponseRedirect(receipt_url)

I don't know if there is anything wrong with the indentation.

Thank you for your help.

commmenttor
dariush 13th April, 2010

sorry I don't know how to paste my sample code properly:

http://dpaste.com/183479/

commmenttor
ritikaa

Yes, you are very much right, you cannot open a PayPal account for Charity, if your charity is registered in India, same thing happened with me also, I applied a Charity account for my client and after completing all the formalities they just denied for the account.
I have a suggestion for you, apply for a normal account with some other website and then use it for your Charity website, I have list of websites who are doing the same thing.
You can also try some other Payment Gateways like CCavenue, but in case you are using Vbulletin script, I don’t think so that it may help you. The first suggestion may work for you.

commmenttor
buy discount air jordan original og 1 (i) black red we predict unlimited values

Break the habit of Complaining And Begin your own special babyliss Marketing and advertising As a substitute .
buy discount air jordan original og 1 (i) black red we predict unlimited values http://www.terrysmall.com/css/authentic-air-jordan-shoes/air-jordan-1-retro-blue-white-grey-p-9277.html

commmenttor
cool reductions prada 2014 fashion sunglasses 1423985 up to 50% off

The most important babyliss Organisation Talk - The Ones Who loves nothing benefits?!
cool reductions prada 2014 fashion sunglasses 1423985 up to 50% off http://www.birdofparadiseanguilla.com/blog/prada-madras-bag/prada-2014-fashion-sunglasses-1423985-p-7697.html

commmenttor
Post a comment Name :

Email :

Your site url:

Comment :

© Agiliq, 2009-2012