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())