I'll put this into a slice when the new slice site comes. But here's an
example of PayPal's Express Checkout interface which is more modern. There
are two main functions in the controller and a module.
def paypal():
session.recipient_id = ''
item = db(db.item.id==request.args(0)).select().first()
item.update_record(status='pending')
item.seller = db(item.created_by==db.auth_user.id).select().first()
purchase = db.purchase.insert(
status = 'pending',
item = item.id,
amount = item.current_price,
currency ='USD',
item_amount = item.current_price,
payment_method = 'paypal',
recipient_id = item.seller.email)
paypal = local_import('paypal', reload=True)
row = db(db.purchase.id==purchase).select().first()
res = paypal.setec(paypal_config, row)
if res['ACK'][0]=='Success':
session.recipient_id = item.seller.email
token = res['TOKEN'][0]
url =
'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token='
redirect('%s%s' % (url, token))
else:
return dict(res=res)
def paypal_return():
token = request.vars.token
recipient_id = session.recipient_id
paypal = local_import('paypal', reload=True)
payment = paypal.getec(paypal_config, token, recipient_id)
if payment['ACK'][0]=='Success':
invoice = int(payment['PAYMENTREQUEST_0_INVNUM'][0].split('-')[1])
purchase = db(db.purchase.id==invoice).select().first()
purchase.update_record(email=payment['EMAIL'][0],
name=payment['PAYMENTREQUEST_0_SHIPTONAME'][0],
first_name=payment['FIRSTNAME'][0],
last_name=payment['LASTNAME'][0],
street1=payment['PAYMENTREQUEST_0_SHIPTOSTREET'][0],
street2='',
city=payment['PAYMENTREQUEST_0_SHIPTOCITY'][0],
state=payment['PAYMENTREQUEST_0_SHIPTOSTATE'][0],
zip=payment['PAYMENTREQUEST_0_SHIPTOZIP'][0],
country=payment['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'][0],
address_status=payment['ADDRESSSTATUS'][0],
amount=payment['PAYMENTREQUEST_0_AMT'][0],
tax_amount=payment['PAYMENTREQUEST_0_TAXAMT'][0])
payerid = request.vars.PayerID
res = paypal.doec(paypal_config, token, purchase, payerid)
if res['ACK'][0]=='Success':
purchase.update_record(status='completed',
completed_on=request.now,
payment_id=res['PAYMENTINFO_0_TRANSACTIONID'][0])
item = db(db.item.id==purchase.item.id).select().first()
item.update_record(status='sold')
process_sale(item=item, purchase=purchase)
return dict(item=item)
else:
app_logging.info(payment)
session.flash = 'error'
return dict(item=False)
else:
app_logging.info(payment)
session.flash = 'error'
return dict(item=False)
import urllib
import cgi
paypal_config = {
'user': 'API USERNAME',
'pwd': 'API PASSWORD',
'signature': 'API SIGNATURE',
'version': '66.0',
'button_source': ''
}
def setec(config, purchase):
invoice = '%s-%s' % ('INVOICE', purchase.id)
values = {'USER': config['user'],
'PWD': config['pwd'],
'SIGNATURE': config['signature'],
'VERSION': config['version'],
'METHOD': 'SetExpressCheckout',
'SUBJECT': purchase.recipient_id,
'PAYMENTREQUEST_0_AMT': purchase.amount,
'PAYMENTREQUEST_0_CURRENCYCODE': purchase.currency,
'RETURNURL': 'http://127.0.0.1:8000/order/paypal_return',
'CANCELURL': 'http://127.0.0.1:8000/order/cancel/%s' %
(purchase.item),
'PAYMENTREQUEST_0_PAYMENTACTION': 'Sale',
'PAYMENTREQUEST_0_INVNUM': invoice,
'PAYMENTREQUEST_0_NOTIFYURL': 'http://mysite.com/ipn'}
return cgi.parse_qs(urllib.urlopen('https://api-3t.paypal.com/nvp',
urllib.urlencode(values)).read())
def getec(config, token, recipient_id):
values = {'USER': config['user'],
'PWD': config['pwd'],
'SIGNATURE': config['signature'],
'VERSION': config['version'],
'SUBJECT': recipient_id,
'METHOD': 'GetExpressCheckoutDetails',
'TOKEN': token}
return cgi.parse_qs(urllib.urlopen('https://api-3t.paypal.com/nvp',
urllib.urlencode(values)).read())
def doec(config, token, purchase, payerid):
values = {'USER': config['user'],
'PWD': config['pwd'],
'SIGNATURE': config['signature'],
'VERSION': config['version'],
'METHOD': 'DoExpressCheckoutPayment',
'BUTTONSOURCE': config['button_source'],
'SUBJECT': purchase.recipient_id,
'TOKEN': token,
'PAYMENTREQUEST_0_PAYMENTACTION': 'Sale',
'PAYMENTREQUEST_0_DESC': 'Order #%s' % (purchase.id),
'PAYMENTREQUEST_0_AMT': purchase.amount,
'PAYMENTREQUEST_0_CURRENCYCODE': purchase.currency,
'PAYERID': payerid}
return cgi.parse_qs(urllib.urlopen('https://api-3t.paypal.com/nvp',
urllib.urlencode(values)).read())