Basic paypal integration working. Still need to do thank-you page and more testing.
This commit is contained in:
parent
f2c8c9c818
commit
ae6a501117
|
@ -39,6 +39,7 @@ class Root( object ):
|
|||
settings[ u"global" ].get( u"luminotes.http_url", u"" ),
|
||||
settings[ u"global" ].get( u"luminotes.https_url", u"" ),
|
||||
settings[ u"global" ].get( u"luminotes.support_email", u"" ),
|
||||
settings[ u"global" ].get( u"luminotes.payment_email", u"" ),
|
||||
settings[ u"global" ].get( u"luminotes.rate_plans", [] ),
|
||||
)
|
||||
self.__notebooks = Notebooks( database, self.__users )
|
||||
|
|
|
@ -17,6 +17,7 @@ from view.Json import Json
|
|||
from view.Main_page import Main_page
|
||||
from view.Redeem_reset_note import Redeem_reset_note
|
||||
from view.Redeem_invite_note import Redeem_invite_note
|
||||
from view.Blank_page import Blank_page
|
||||
|
||||
|
||||
USERNAME_PATTERN = re.compile( "^[a-zA-Z0-9]+$" )
|
||||
|
@ -100,7 +101,8 @@ class Access_error( Exception ):
|
|||
|
||||
|
||||
class Payment_error( Exception ):
|
||||
def __init__( self, message ):
|
||||
def __init__( self, message, params ):
|
||||
message += "\n" + unicode( params )
|
||||
Exception.__init__( self, message )
|
||||
self.__message = message
|
||||
|
||||
|
@ -163,7 +165,7 @@ class Users( object ):
|
|||
"""
|
||||
Controller for dealing with users, corresponding to the "/users" URL.
|
||||
"""
|
||||
def __init__( self, database, http_url, https_url, support_email, rate_plans ):
|
||||
def __init__( self, database, http_url, https_url, support_email, payment_email, rate_plans ):
|
||||
"""
|
||||
Create a new Users object.
|
||||
|
||||
|
@ -175,6 +177,8 @@ class Users( object ):
|
|||
@param https_url: base URL to use for SSL http requests, or an empty string
|
||||
@type support_email: unicode
|
||||
@param support_email: email address for support requests
|
||||
@type payment_email: unicode
|
||||
@param payment_email: email address for payment
|
||||
@type rate_plans: [ { "name": unicode, "storage_quota_bytes": int } ]
|
||||
@param rate_plans: list of configured rate plans
|
||||
@rtype: Users
|
||||
|
@ -184,6 +188,7 @@ class Users( object ):
|
|||
self.__http_url = http_url
|
||||
self.__https_url = https_url
|
||||
self.__support_email = support_email
|
||||
self.__payment_email = payment_email
|
||||
self.__rate_plans = rate_plans
|
||||
|
||||
@expose( view = Json )
|
||||
|
@ -968,26 +973,97 @@ class Users( object ):
|
|||
|
||||
self.__database.commit()
|
||||
|
||||
@expose()
|
||||
@expose( view = Blank_page )
|
||||
def paypal_notify( self, **params ):
|
||||
PAYPAL_URL = u"https://www.sandbox.paypal.com/cgi-bin/webscr"
|
||||
#PAYPAL_URL = u"https://www.paypal.com/cgi-bin/webscr"
|
||||
|
||||
print params
|
||||
params[ u"cmd" ] = u"_notify-validate"
|
||||
params = urllib.urlencode( params )
|
||||
|
||||
response = urllib2.Request( PAYPAL_URL )
|
||||
response.add_header( u"Content-type", u"application/x-www-form-urlencoded" )
|
||||
response_file = urllib2.urlopen( PAYPAL_URL, params )
|
||||
result = response_file.read()
|
||||
# check that payment_status is Completed
|
||||
payment_status = params.get( u"payment_status" )
|
||||
if payment_status and payment_status != u"Completed":
|
||||
raise Payment_error( u"payment_status is not Completed", params )
|
||||
|
||||
# TODO: check that txn_id is not a duplicate
|
||||
|
||||
# check that receiver_email is mine
|
||||
if params.get( u"receiver_email" ) != self.__payment_email:
|
||||
raise Payment_error( u"incorrect receiver_email", params )
|
||||
|
||||
# verify mc_currency
|
||||
if params.get( u"mc_currency" ) != u"USD":
|
||||
raise Payment_error( u"unsupported mc_currency", params )
|
||||
|
||||
# verify item_number
|
||||
plan_index = params.get( u"item_number" )
|
||||
try:
|
||||
plan_index = int( plan_index )
|
||||
except ValueError:
|
||||
raise Payment_error( u"invalid item_number", params )
|
||||
if plan_index == 0 or plan_index >= len( self.__rate_plans ):
|
||||
raise Payment_error( u"invalid item_number", params )
|
||||
|
||||
# verify mc_gross
|
||||
rate_plan = self.__rate_plans[ plan_index ]
|
||||
fee = u"%0.2f" % rate_plan[ u"fee" ]
|
||||
mc_gross = params.get( u"mc_gross" )
|
||||
if mc_gross and mc_gross != fee:
|
||||
raise Payment_error( u"invalid mc_gross", params )
|
||||
|
||||
# verify mc_amount3
|
||||
mc_amount3 = params.get( u"mc_amount3" )
|
||||
if mc_amount3 and mc_amount3 != fee:
|
||||
raise Payment_error( u"invalid mc_amount3", params )
|
||||
|
||||
# verify item_name
|
||||
item_name = params.get( u"item_name" )
|
||||
if item_name and item_name.lower() != u"luminotes " + rate_plan[ u"name" ].lower():
|
||||
raise Payment_error( u"invalid item_name", params )
|
||||
|
||||
# verify period1 and period2 (should not be present)
|
||||
if params.get( u"period1" ) or params.get( u"period2" ):
|
||||
raise Payment_error( u"invalid period", params )
|
||||
|
||||
# verify period3
|
||||
period3 = params.get( u"period3" )
|
||||
if period3 and period3 != u"1 M": # one-month subscription
|
||||
raise Payment_error( u"invalid period3", params )
|
||||
|
||||
params[ u"cmd" ] = u"_notify-validate"
|
||||
encoded_params = urllib.urlencode( params )
|
||||
|
||||
# ask paypal to verify the request
|
||||
request = urllib2.Request( PAYPAL_URL )
|
||||
request.add_header( u"Content-type", u"application/x-www-form-urlencoded" )
|
||||
request_file = urllib2.urlopen( PAYPAL_URL, encoded_params )
|
||||
result = request_file.read()
|
||||
|
||||
if result != u"VERIFIED":
|
||||
raise Payment_error( result )
|
||||
raise Payment_error( result, params )
|
||||
|
||||
print "VERIFIED"
|
||||
# update the database based on the type of transaction
|
||||
txn_type = params.get( u"txn_type" )
|
||||
user_id = params.get( u"custom" )
|
||||
try:
|
||||
user_id = Valid_id()( user_id )
|
||||
except ValueError():
|
||||
raise Payment_error( u"invalid custom", params )
|
||||
|
||||
# TODO: update the database
|
||||
user = self.__database.load( User, user_id )
|
||||
if not user:
|
||||
raise Payment_error( u"unknown custom", params )
|
||||
|
||||
if txn_type in ( u"subscr_signup", u"subcr_modify" ):
|
||||
user.rate_plan = plan_index
|
||||
self.__database.save( user )
|
||||
elif txn_type == u"subscr_cancel":
|
||||
user.rate_plan = 0 # return the user to the free account level
|
||||
self.__database.save( user )
|
||||
elif txn_type in ( u"subscr_payment", u"subscr_failed" ):
|
||||
pass # for now, ignore payments and let paypal handle them
|
||||
else:
|
||||
raise Payment_error( "unknown txn_type", params )
|
||||
|
||||
return dict()
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
from Tags import Html
|
||||
|
||||
|
||||
class Blank_page( Html ):
|
||||
def __init__( self ):
|
||||
Html.__init__(
|
||||
self,
|
||||
)
|
Reference in New Issue