9
9
import socket
10
10
import urllib
11
11
import urllib2
12
+ import logging
13
+ from pprint import pformat
12
14
13
15
from paypal .settings import PayPalConfig
14
16
from paypal .response import PayPalResponse
15
17
from paypal .exceptions import PayPalError , PayPalAPIResponseError
18
+
19
+ logger = logging .getLogger ('paypal.interface' )
16
20
17
21
class PayPalInterface (object ):
18
22
"""
@@ -68,11 +72,13 @@ def _call(self, method, **kwargs):
68
72
69
73
``kwargs`` will be a hash of
70
74
"""
75
+ # Beware, this is a global setting.
71
76
socket .setdefaulttimeout (self .config .HTTP_TIMEOUT )
72
-
77
+
78
+ # This dict holds the key/value pairs to pass to the PayPal API.
73
79
url_values = {
74
80
'METHOD' : method ,
75
- 'VERSION' : self .config .API_VERSION
81
+ 'VERSION' : self .config .API_VERSION ,
76
82
}
77
83
78
84
headers = {}
@@ -88,30 +94,27 @@ def _call(self, method, **kwargs):
88
94
url_values ['SUBJECT' ] = self .config .SUBJECT
89
95
# headers['X-PAYPAL-REQUEST-DATA-FORMAT'] = 'NV'
90
96
# headers['X-PAYPAL-RESPONSE-DATA-FORMAT'] = 'NV'
91
- # print(headers)
92
97
98
+ # All values passed to PayPal API must be uppercase.
93
99
for key , value in kwargs .iteritems ():
94
100
url_values [key .upper ()] = value
95
101
96
- # When in DEBUG level 2 or greater, print out the NVP pairs.
97
- if self .config .DEBUG_LEVEL >= 2 :
98
- k = url_values .keys ()
99
- k .sort ()
100
- for i in k :
101
- print " %-20s : %s" % (i , url_values [i ])
102
+ # This shows all of the key/val pairs we're sending to PayPal.
103
+ if logger .isEnabledFor (logging .DEBUG ):
104
+ logger .debug ('PayPal NVP Query Key/Vals:\n %s' % pformat (url_values ))
102
105
103
106
url = self ._encode_utf8 (** url_values )
104
-
105
107
data = urllib .urlencode (url )
106
108
req = urllib2 .Request (self .config .API_ENDPOINT , data , headers )
107
109
response = PayPalResponse (urllib2 .urlopen (req ).read (), self .config )
108
110
109
- if self .config .DEBUG_LEVEL >= 1 :
110
- print " %-20s : %s" % ("ENDPOINT" , self .config .API_ENDPOINT )
111
+ logger .debug ('PayPal NVP API Endpoint: %s' % self .config .API_ENDPOINT )
111
112
112
113
if not response .success :
113
- if self .config .DEBUG_LEVEL >= 1 :
114
- print response
114
+ logger .error ('A PayPal API error was encountered.' )
115
+ logger .error ('PayPal NVP Query Key/Vals:\n %s' % pformat (url_values ))
116
+ logger .error ('PayPal NVP Query Response' )
117
+ logger .error (response )
115
118
raise PayPalAPIResponseError (response )
116
119
117
120
return response
@@ -284,51 +287,52 @@ def get_transaction_details(self, transactionid):
284
287
del args ['self' ]
285
288
return self ._call ('GetTransactionDetails' , ** args )
286
289
287
- def set_express_checkout (self , token = '' , ** kwargs ):
288
- """Shortcut for the SetExpressCheckout method.
289
- JV did not like the original method. found it limiting.
290
+ def set_express_checkout (self , ** kwargs ):
291
+ """Start an Express checkout.
292
+
293
+ You'll want to use this in conjunction with
294
+ :meth:`generate_express_checkout_redirect_url` to create a payment,
295
+ then figure out where to redirect the user to for them to
296
+ authorize the payment on PayPal's website.
297
+
298
+ Required Keys
299
+ -------------
300
+
301
+ * PAYMENTREQUEST_0_AMT
302
+ * PAYMENTREQUEST_0_PAYMENTACTION
303
+ * RETURNURL
304
+ * CANCELURL
290
305
"""
291
- kwargs .update (locals ())
292
- del kwargs ['self' ]
293
- self ._check_required (('amt' ,), ** kwargs )
294
306
return self ._call ('SetExpressCheckout' , ** kwargs )
295
307
296
- def do_express_checkout_payment (self , token , ** kwargs ):
297
- """Shortcut for the DoExpressCheckoutPayment method.
298
-
299
- Required
300
- *TOKEN
301
- PAYMENTACTION
302
- PAYERID
303
- AMT
304
-
305
- Optional
306
- RETURNFMFDETAILS
307
- GIFTMESSAGE
308
- GIFTRECEIPTENABLE
309
- GIFTWRAPNAME
310
- GIFTWRAPAMOUNT
311
- BUYERMARKETINGEMAIL
312
- SURVEYQUESTION
313
- SURVEYCHOICESELECTED
314
- CURRENCYCODE
315
- ITEMAMT
316
- SHIPPINGAMT
317
- INSURANCEAMT
318
- HANDLINGAMT
319
- TAXAMT
308
+ def do_express_checkout_payment (self , ** kwargs ):
309
+ """Finishes an Express checkout.
320
310
321
- Optional + USEFUL
322
- INVNUM - invoice number
311
+ :param str token: The token that was returned earlier by
312
+ :meth:`set_express_checkout`. This identifies the transaction.
313
+
314
+ Required
315
+ --------
316
+ * TOKEN
317
+ * PAYMENTACTION
318
+ * PAYERID
319
+ * AMT
323
320
324
321
"""
325
- kwargs .update (locals ())
326
- del kwargs ['self' ]
327
- self ._check_required (('paymentaction' , 'payerid' ), ** kwargs )
328
322
return self ._call ('DoExpressCheckoutPayment' , ** kwargs )
329
323
330
324
def generate_express_checkout_redirect_url (self , token ):
331
- """Submit token, get redirect url for client."""
325
+ """Returns the URL to redirect the user to for the Express checkout.
326
+
327
+ Express Checkouts must be verified by the customer by redirecting them
328
+ to the PayPal website. Use the token returned in the response from
329
+ :meth:`set_express_checkout` with this function to figure out where
330
+ to redirect the user to.
331
+
332
+ :param str token: The unique token identifying this transaction.
333
+ :rtype: str
334
+ :returns: The URL to redirect the user to for approval.
335
+ """
332
336
url_vars = (self .config .PAYPAL_URL_BASE , token )
333
337
return "%s?cmd=_express-checkout&token=%s" % url_vars
334
338
0 commit comments