Mercurial > public > sg101
comparison gpp/donations/views.py @ 36:296b610ee507
Added IPN logic to the donations module. Added a thank-you view. Need to add logging to the IPN function.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Thu, 11 Jun 2009 00:54:44 +0000 |
parents | f77a1cdd7a46 |
children | 5dbfb7fec629 |
comparison
equal
deleted
inserted
replaced
35:f77a1cdd7a46 | 36:296b610ee507 |
---|---|
1 """ | 1 """ |
2 Views for the donations application. | 2 Views for the donations application. |
3 """ | 3 """ |
4 import urllib2 | |
5 import decimal | |
6 import datetime | |
7 | |
4 from django.shortcuts import render_to_response | 8 from django.shortcuts import render_to_response |
5 from django.template import RequestContext | 9 from django.template import RequestContext |
6 from django.http import Http404 # TODO: remove | |
7 from django.conf import settings | 10 from django.conf import settings |
8 from django.contrib.sites.models import Site | 11 from django.contrib.sites.models import Site |
12 from django.http import HttpResponse | |
13 from django.http import HttpResponseServerError | |
14 from django.contrib.auth.models import User | |
9 | 15 |
10 from donations.models import Donation | 16 from donations.models import Donation |
17 | |
18 PP_DATE_FMT = '%H:%M:%S %b %d, %Y PST' | |
19 | |
20 def paypal_params(): | |
21 """ | |
22 This function returns a tuple where the 1st element is the Paypal | |
23 URL and the 2nd element is the Paypal business email. This information | |
24 depends on the setting DONATIONS_DEBUG. | |
25 """ | |
26 if settings.DONATIONS_DEBUG: | |
27 form_action = 'https://www.sandbox.paypal.com/cgi-bin/webscr' | |
28 business = settings.DONATIONS_BUSINESS_DEBUG | |
29 else: | |
30 form_action = 'https://www.paypal.com/cgi-bin/webscr' | |
31 business = settings.DONATIONS_BUSINESS | |
32 | |
33 return form_action, business | |
11 | 34 |
12 | 35 |
13 def index(request): | 36 def index(request): |
14 gross, net, donations = Donation.objects.monthly_stats() | 37 gross, net, donations = Donation.objects.monthly_stats() |
15 current_site = Site.objects.get_current() | 38 current_site = Site.objects.get_current() |
16 | 39 form_action, business = paypal_params() |
17 if settings.DEBUG: | |
18 form_action = 'https://www.sandbox.paypal.com/cgi-bin/webscr' | |
19 business = settings.DONATIONS_BUSINESS_DEBUG | |
20 else: | |
21 form_action = 'https://www.paypal.com/cgi-bin/webscr' | |
22 business = settings.DONATIONS_BUSINESS | |
23 | 40 |
24 return render_to_response('donations/index.html', { | 41 return render_to_response('donations/index.html', { |
25 'goal': settings.DONATIONS_GOAL, | 42 'goal': settings.DONATIONS_GOAL, |
26 'gross': gross, | 43 'gross': gross, |
27 'net': net, | 44 'net': net, |
37 }, | 54 }, |
38 context_instance = RequestContext(request)) | 55 context_instance = RequestContext(request)) |
39 | 56 |
40 | 57 |
41 def ipn(request): | 58 def ipn(request): |
42 raise Http404 #TODO | 59 """ |
60 This function is the IPN listener and handles the IPN POST from Paypal. | |
61 | |
62 TODO: Add logging. | |
63 """ | |
64 parameters = None | |
65 try: | |
66 if request['payment_status'] == 'Completed': | |
67 if request.POST: | |
68 parameters = request.POST.copy() | |
69 else: | |
70 parameters = request.GET.copy() | |
71 | |
72 if parameters: | |
73 parameters['cmd']='_notify-validate' | |
74 req = urllib2.Request(paypal_params()[0], parameters.urlencode()) | |
75 req.add_header("Content-type", "application/x-www-form-urlencoded") | |
76 response = urllib2.urlopen(req) | |
77 status = response.read() | |
78 if status != "VERIFIED": | |
79 parameters = None | |
80 | |
81 if parameters: | |
82 # is this a donation to the site? | |
83 try: | |
84 item_number = int(parameters['item_number']) | |
85 except ValueError: | |
86 pass | |
87 else: | |
88 if item_number == settings.DONATIONS_ITEM_NUM or \ | |
89 item_number == settings.DONATIONS_ITEM_ANON_NUM: | |
90 process_donation(item_number, parameters) | |
91 | |
92 return HttpResponse("Ok") | |
93 | |
94 except Exception, e: | |
95 # print "An exeption was caught: " + str(e) | |
96 pass | |
97 | |
98 return HttpResponseServerError("Error") | |
43 | 99 |
44 | 100 |
45 def thanks(request): | 101 def process_donation(item_number, params): |
46 raise Http404 #TODO | 102 """ |
103 Constructs a donation object from the parameters and stores | |
104 in the database. | |
105 """ | |
106 # Has this transaction been processed before? | |
107 if 'txn_id' not in params: | |
108 return | |
109 txn_id = params['txn_id'] | |
110 try: | |
111 donation = Donation.objects.get(txn_id__exact=txn_id) | |
112 except Donation.DoesNotExist: | |
113 pass | |
114 else: | |
115 return # no exception, this is a duplicate | |
116 | |
117 # Is the email address ours? | |
118 business = params.get('business') | |
119 if business != paypal_params()[1]: | |
120 return | |
121 | |
122 # is this a payment received? | |
123 txn_type = params.get('txn_type') | |
124 if txn_type != 'web_accept': | |
125 return | |
126 | |
127 # Looks like a donation, save it to the database. | |
128 # Determine which user this came from, if any. | |
129 # The username is stored in the custom field if the user was logged in when | |
130 # the donation was made. | |
131 user = None | |
132 if 'custom' in params: | |
133 try: | |
134 user = User.objects.get(username__exact=params['custom']) | |
135 except User.DoesNotExist: | |
136 pass | |
137 | |
138 is_anonymous = item_number == settings.DONATIONS_ITEM_ANON_NUM | |
139 test_ipn = params.get('test_ipn') == '1' | |
140 | |
141 first_name = params.get('first_name', '') | |
142 last_name = params.get('last_name', '') | |
143 payer_email = params.get('payer_email', '') | |
144 payer_id = params.get('payer_id', '') | |
145 memo = params.get('memo', '') | |
146 payer_status = params.get('payer_status', '') | |
147 | |
148 try: | |
149 mc_gross = decimal.Decimal(params['mc_gross']) | |
150 mc_fee = decimal.Decimal(params['mc_fee']) | |
151 except KeyError, decimal.InvalidOperation: | |
152 return | |
153 | |
154 try: | |
155 payment_date = datetime.datetime.strptime(params['payment_date'], | |
156 PP_DATE_FMT) | |
157 except KeyError, ValueError: | |
158 return | |
159 | |
160 donation = Donation( | |
161 user=user, | |
162 is_anonymous=is_anonymous, | |
163 test_ipn=test_ipn, | |
164 txn_id=txn_id, | |
165 first_name=first_name, | |
166 last_name=last_name, | |
167 payer_email=payer_email, | |
168 payer_id=payer_id, | |
169 memo=memo, | |
170 payer_status=payer_status, | |
171 mc_gross=mc_gross, | |
172 mc_fee=mc_fee, | |
173 payment_date=payment_date) | |
174 | |
175 donation.save() | |
176 |