Adding cancel,dispute,chargeback support, chained payments, user/list APIs, bug fixes
parent
b267e7f822
commit
ed1732b4ec
|
@ -2,7 +2,7 @@ from regluit.core.models import Campaign, Wishlist
|
|||
from regluit.payment.models import Transaction, Receiver
|
||||
from django.contrib.auth.models import User
|
||||
from regluit.payment.parameters import *
|
||||
from regluit.payment.paypal import Pay, IPN, IPN_TYPE_PAYMENT, IPN_TYPE_PREAPPROVAL, Preapproval
|
||||
from regluit.payment.paypal import Pay, IPN, IPN_TYPE_PAYMENT, IPN_TYPE_PREAPPROVAL, IPN_TYPE_ADJUSTMENT, Preapproval, IPN_PAY_STATUS_COMPLETED, CancelPreapproval, IPN_SENDER_STATUS_COMPLETED
|
||||
import uuid
|
||||
import traceback
|
||||
|
||||
|
@ -27,38 +27,119 @@ class PaymentManager( object ):
|
|||
|
||||
|
||||
if ipn.transaction_type == IPN_TYPE_PAYMENT:
|
||||
# payment IPN
|
||||
|
||||
if ipn.preapproval_key:
|
||||
key = ipn.preapproval_key
|
||||
else:
|
||||
key = ipn.key
|
||||
|
||||
key = ipn.key()
|
||||
t = Transaction.objects.get(reference=key)
|
||||
|
||||
# The status is always one of the IPN_PAY_STATUS codes defined in paypal.py
|
||||
t.status = ipn.status
|
||||
|
||||
|
||||
for item in ipn.transactions:
|
||||
|
||||
r = Receiver.objects.get(transaction=t, email=item['receiver'])
|
||||
r.status = item['status_for_sender_txn']
|
||||
r.save()
|
||||
try:
|
||||
r = Receiver.objects.get(transaction=t, email=item['receiver'])
|
||||
print item
|
||||
# one of the IPN_SENDER_STATUS codes defined in paypal.py
|
||||
r.status = item['status_for_sender_txn']
|
||||
r.txn_id = item['id_for_sender_txn']
|
||||
r.save()
|
||||
except:
|
||||
# Log an excecption if we have a receiver that is not found
|
||||
traceback.print_exc()
|
||||
|
||||
t.save()
|
||||
|
||||
elif ipn.transaction_type == IPN_TYPE_ADJUSTMENT:
|
||||
# a chargeback, reversal or refund for an existng payment
|
||||
|
||||
key = ipn.key()
|
||||
t = Transaction.objects.get(reference=key)
|
||||
|
||||
# The status is always one of the IPN_PAY_STATUS codes defined in paypal.py
|
||||
t.status = ipn.status
|
||||
|
||||
# Reason code indicates more details of the adjustment type
|
||||
t.reason = ipn.reason_code
|
||||
|
||||
|
||||
elif ipn.transaction_type == IPN_TYPE_PREAPPROVAL:
|
||||
|
||||
t = Transaction.objects.get(reference=ipn.preapproval_key)
|
||||
|
||||
key = ipn.key()
|
||||
t = Transaction.objects.get(reference=key)
|
||||
|
||||
# The status is always one of the IPN_PREAPPROVAL_STATUS codes defined in paypal.py
|
||||
t.status = ipn.status
|
||||
t.save()
|
||||
print "IPN: Preapproval transaction: " + str(t.id) + " Status: " + ipn.status
|
||||
|
||||
else:
|
||||
print "IPN: Unknown Transaction Type: " + ipn.transaction_type
|
||||
|
||||
|
||||
else:
|
||||
print "ERROR: INVALID IPN"
|
||||
print ipn.error
|
||||
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
'''
|
||||
Generic query handler for returning summary and transaction info, see query_user, query_list and query_campaign
|
||||
'''
|
||||
def run_query(self, transaction_list, summary, pledged, authorized ):
|
||||
|
||||
if pledged:
|
||||
pledged_list = transaction_list.filter(type=PAYMENT_TYPE_INSTANT,
|
||||
status="COMPLETED")
|
||||
else:
|
||||
pledged_list = []
|
||||
|
||||
if authorized:
|
||||
authorized_list = Transaction.objects.filter(type=PAYMENT_TYPE_AUTHORIZATION,
|
||||
status="ACTIVE")
|
||||
else:
|
||||
authorized_list = []
|
||||
|
||||
if summary:
|
||||
pledged_amount = 0.0
|
||||
authorized_amount = 0.0
|
||||
|
||||
for t in pledged_list:
|
||||
for r in t.receiver_set.all():
|
||||
if r.status == IPN_SENDER_STATUS_COMPLETED:
|
||||
# individual senders may not have been paid due to errors, and disputes/chargebacks only appear here
|
||||
pledged_amount += r.amount
|
||||
|
||||
for t in authorized_list:
|
||||
authorized_amount += t.amount
|
||||
|
||||
amount = pledged_amount + authorized_amount
|
||||
return amount
|
||||
|
||||
else:
|
||||
return pledged_list | authorized_list
|
||||
|
||||
|
||||
'''
|
||||
query_user
|
||||
|
||||
Returns either an amount or list of transactions for a user
|
||||
|
||||
summary: if true, return a float of the total, if false, return a list of transactions
|
||||
pledged: include amounts pledged
|
||||
authorized: include amounts pre-authorized
|
||||
|
||||
return value: either a float summary or a list of transactions
|
||||
|
||||
'''
|
||||
def query_user(self, user, summary=False, pledged=True, authorized=True):
|
||||
|
||||
transactions = Transaction.objects.filter(user=user)
|
||||
return self.run_query(transactions, summary, pledged, authorized)
|
||||
|
||||
|
||||
'''
|
||||
query_campaign
|
||||
|
@ -74,35 +155,25 @@ class PaymentManager( object ):
|
|||
'''
|
||||
def query_campaign(self, campaign, summary=False, pledged=True, authorized=True):
|
||||
|
||||
if pledged:
|
||||
pledged_list = Transaction.objects.filter(campaign=campaign,
|
||||
type=PAYMENT_TYPE_INSTANT,
|
||||
status="COMPLETED")
|
||||
else:
|
||||
pledged_list = []
|
||||
transactions = Transaction.objects.filter(campaign=campaign)
|
||||
return self.run_query(transactions, summary, pledged, authorized)
|
||||
|
||||
'''
|
||||
query_list
|
||||
|
||||
Returns either an amount or list of transactions for a list
|
||||
|
||||
summary: if true, return a float of the total, if false, return a list of transactions
|
||||
pledged: include amounts pledged
|
||||
authorized: include amounts pre-authorized
|
||||
|
||||
return value: either a float summary or a list of transactions
|
||||
|
||||
'''
|
||||
def query_campaign(self, list, summary=False, pledged=True, authorized=True):
|
||||
|
||||
if authorized:
|
||||
authorized_list = Transaction.objects.filter(campaign=campaign,
|
||||
type=PAYMENT_TYPE_AUTHORIZATION,
|
||||
status="ACTIVE")
|
||||
else:
|
||||
authorized_list = []
|
||||
|
||||
if summary:
|
||||
pledged_amount = 0.0
|
||||
authorized_amount = 0.0
|
||||
|
||||
for t in pledged_list:
|
||||
pledged_amount += t.amount
|
||||
|
||||
for t in authorized_list:
|
||||
authorized_amount += t.amount
|
||||
|
||||
amount = pledged_amount + authorized_amount
|
||||
return amount
|
||||
|
||||
else:
|
||||
return pledged_list | authorized_list
|
||||
transactions = Transaction.objects.filter(list=list)
|
||||
return self.run_query(transactions, summary, pledged, authorized)
|
||||
|
||||
'''
|
||||
execute_campaign
|
||||
|
@ -114,12 +185,14 @@ class PaymentManager( object ):
|
|||
'''
|
||||
def execute_campaign(self, campaign):
|
||||
|
||||
# only allow active transactions to go through again, if there is an error, intervention is needed
|
||||
transactions = Transaction.objects.filter(campaign=campaign, status="ACTIVE")
|
||||
|
||||
for t in transactions:
|
||||
|
||||
receiver_list = [{'email':'jakace_1309677337_biz@gmail.com', 'amount':t.amount * 0.80},
|
||||
{'email':'boogus@gmail.com', 'amount':t.amount * 0.20}]
|
||||
# BUGBUG: Fill this in with the correct info from the campaign object
|
||||
receiver_list = [{'email':'jakace_1309677337_biz@gmail.com', 'amount':t.amount},
|
||||
{'email':'seller_1317463643_biz@gmail.com', 'amount':t.amount * 0.20}]
|
||||
|
||||
self.execute_transaction(t, receiver_list)
|
||||
|
||||
|
@ -144,13 +217,17 @@ class PaymentManager( object ):
|
|||
'''
|
||||
def execute_transaction(self, transaction, receiver_list):
|
||||
|
||||
for r in receiver_list:
|
||||
receiver = Receiver.objects.create(email=r['email'], amount=r['amount'], currency=transaction.currency, status="ACTIVE", transaction=transaction)
|
||||
if len(transaction.receiver_set.all()) > 0:
|
||||
# we are re-submitting a transaction, wipe the old receiver list
|
||||
transaction.receiver_set.all().delete()
|
||||
|
||||
transaction.create_receivers(receiver_list)
|
||||
|
||||
p = Pay(transaction)
|
||||
|
||||
p = Pay(transaction, receiver_list)
|
||||
transaction.status = p.status()
|
||||
# We will update our transaction status when we receive the IPN
|
||||
|
||||
if p.status() == 'COMPLETED':
|
||||
if p.status() == IPN_PAY_STATUS_COMPLETED:
|
||||
print "Execute Success"
|
||||
return True
|
||||
|
||||
|
@ -159,6 +236,27 @@ class PaymentManager( object ):
|
|||
print "Execute Error: " + p.error()
|
||||
return False
|
||||
|
||||
'''
|
||||
cancel
|
||||
|
||||
cancels a pre-approved transaction
|
||||
|
||||
return value: True if successful, false otherwise
|
||||
'''
|
||||
def cancel(self, transaction):
|
||||
|
||||
p = CancelPreapproval(transaction)
|
||||
|
||||
if p.success():
|
||||
print "Cancel Transaction " + str(transaction.id) + " Completed"
|
||||
return True
|
||||
|
||||
else:
|
||||
print "Cancel Transaction " + str(transaction.id) + " Failed with error: " + p.error()
|
||||
transaction.error = p.error()
|
||||
return False
|
||||
|
||||
|
||||
'''
|
||||
authorize
|
||||
|
||||
|
@ -191,14 +289,12 @@ class PaymentManager( object ):
|
|||
p = Preapproval(t, amount)
|
||||
|
||||
if p.status() == 'Success':
|
||||
t.status = 'CREATED'
|
||||
t.reference = p.paykey()
|
||||
t.save()
|
||||
print "Authorize Success: " + p.next_url()
|
||||
return t, p.next_url()
|
||||
|
||||
else:
|
||||
t.status = 'ERROR'
|
||||
t.error = p.error()
|
||||
t.save()
|
||||
print "Authorize Error: " + p.error()
|
||||
|
@ -230,8 +326,9 @@ class PaymentManager( object ):
|
|||
def pledge(self, currency, target, receiver_list, campaign=None, list=None, user=None):
|
||||
|
||||
amount = 0.0
|
||||
for r in receiver_list:
|
||||
amount += r['amount']
|
||||
|
||||
# for chained payments, first amount is the total amount
|
||||
amount = receiver_list[0]['amount']
|
||||
|
||||
t = Transaction.objects.create(amount=amount,
|
||||
type=PAYMENT_TYPE_INSTANT,
|
||||
|
@ -244,11 +341,9 @@ class PaymentManager( object ):
|
|||
user=user
|
||||
)
|
||||
|
||||
for r in receiver_list:
|
||||
receiver = Receiver.objects.create(email=r['email'], amount=r['amount'], currency=currency, status="None", transaction=t)
|
||||
t.create_receivers(receiver_list)
|
||||
|
||||
p = Pay(t, receiver_list)
|
||||
t.status = p.status()
|
||||
p = Pay(t)
|
||||
|
||||
if p.status() == 'CREATED':
|
||||
t.reference = p.paykey()
|
||||
|
@ -259,7 +354,7 @@ class PaymentManager( object ):
|
|||
else:
|
||||
t.error = p.error()
|
||||
t.save()
|
||||
print "Pledge Status: " + p.status() + "Error: " + p.error()
|
||||
print "Pledge Error: " + p.error()
|
||||
return t, None
|
||||
|
||||
|
|
@ -14,10 +14,12 @@ class Transaction(models.Model):
|
|||
reference = models.CharField(max_length=128, null=True)
|
||||
receipt = models.CharField(max_length=256, null=True)
|
||||
error = models.CharField(max_length=256, null=True)
|
||||
reason = models.CharField(max_length=64, null=True)
|
||||
date_created = models.DateTimeField(auto_now_add=True)
|
||||
date_modified = models.DateTimeField(auto_now=True)
|
||||
date_payment = models.DateTimeField(null=True)
|
||||
date_authorized = models.DateTimeField(null=True)
|
||||
date_expired = models.DateTimeField(null=True)
|
||||
user = models.ForeignKey(User, null=True)
|
||||
campaign = models.ForeignKey(Campaign, null=True)
|
||||
list = models.ForeignKey(Wishlist, null=True)
|
||||
|
@ -25,12 +27,23 @@ class Transaction(models.Model):
|
|||
def __unicode__(self):
|
||||
return u"-- Transaction:\n \tstatus: %s\n \t amount: %s\n \treference: %s\n \terror: %s\n" % (self.status, str(self.amount), self.reference, self.error)
|
||||
|
||||
def create_receivers(self, receiver_list):
|
||||
|
||||
primary = True
|
||||
for r in receiver_list:
|
||||
receiver = Receiver.objects.create(email=r['email'], amount=r['amount'], currency=self.currency, status="None", primary=primary, transaction=self)
|
||||
primary = False
|
||||
|
||||
|
||||
class Receiver(models.Model):
|
||||
|
||||
email = models.CharField(max_length=64)
|
||||
amount = models.FloatField()
|
||||
currency = models.CharField(max_length=10)
|
||||
status = models.CharField(max_length=64)
|
||||
reason = models.CharField(max_length=64)
|
||||
primary = models.BooleanField()
|
||||
txn_id = models.CharField(max_length=64)
|
||||
transaction = models.ForeignKey(Transaction)
|
||||
|
||||
|
|
@ -30,14 +30,28 @@ IPN_TYPE_PAYMENT = 'Adaptive Payment PAY'
|
|||
IPN_TYPE_ADJUSTMENT = 'Adjustment'
|
||||
IPN_TYPE_PREAPPROVAL = 'Adaptive Payment PREAPPROVAL'
|
||||
|
||||
#status constants
|
||||
IPN_STATUS_CREATED = 'CREATED'
|
||||
IPN_STATUS_COMPLETED = 'COMPLETED'
|
||||
IPN_STATUS_INCOMPLETE = 'INCOMPLETE'
|
||||
IPN_STATUS_ERROR = 'ERROR'
|
||||
IPN_STATUS_REVERSALERROR = 'REVERSALERROR'
|
||||
IPN_STATUS_PROCESSING = 'PROCESSING'
|
||||
IPN_STATUS_PENDING = 'PENDING'
|
||||
#pay API status constants
|
||||
IPN_PAY_STATUS_NONE = 'NONE'
|
||||
IPN_PAY_STATUS_CREATED = 'CREATED'
|
||||
IPN_PAY_STATUS_COMPLETED = 'COMPLETED'
|
||||
IPN_PAY_STATUS_INCOMPLETE = 'INCOMPLETE'
|
||||
IPN_PAY_STATUS_ERROR = 'ERROR'
|
||||
IPN_PAY_STATUS_REVERSALERROR = 'REVERSALERROR'
|
||||
IPN_PAY_STATUS_PROCESSING = 'PROCESSING'
|
||||
IPN_PAY_STATUS_PENDING = 'PENDING'
|
||||
IPN_PAY_STATUS_ACTIVE = "ACTIVE"
|
||||
IPN_PAY_STATUS_CANCELED = "CANCELED"
|
||||
|
||||
|
||||
IPN_SENDER_STATUS_COMPLETED = 'COMPLETED'
|
||||
IPN_SENDER_STATUS_PENDING = 'PENDING'
|
||||
IPN_SENDER_STATUS_CREATED = 'CREATED'
|
||||
IPN_SENDER_STATUS_PARTIALLY_REFUNDED = 'PARTIALLY_REFUNDED'
|
||||
IPN_SENDER_STATUS_DENIED = 'DENIED'
|
||||
IPN_SENDER_STATUS_PROCESSING = 'PROCESSING'
|
||||
IPN_SENDER_STATUS_REVERSED = 'REVERSED'
|
||||
IPN_SENDER_STATUS_REFUNDED = 'REFUNDED'
|
||||
IPN_SENDER_STATUS_FAILED = 'FAILED'
|
||||
|
||||
# action_type constants
|
||||
IPN_ACTION_TYPE_PAY = 'PAY'
|
||||
|
@ -48,11 +62,13 @@ IPN_TXN_STATUS_COMPLETED = 'Completed'
|
|||
IPN_TXN_STATUS_PENDING = 'Pending'
|
||||
IPN_TXN_STATUS_REFUNDED = 'Refunded'
|
||||
|
||||
IPN_REASON_CODE_CHARGEBACK = 'Chargeback'
|
||||
IPN_REASON_CODE_SETTLEMENT = 'Settlement'
|
||||
# addaptive payment adjusted IPN reason codes
|
||||
IPN_REASON_CODE_CHARGEBACK_SETTLEMENT = 'Chargeback Settlement'
|
||||
IPN_REASON_CODE_ADMIN_REVERSAL = 'Admin reversal'
|
||||
IPN_REASON_CODE_REFUND = 'Refund'
|
||||
|
||||
class PaypalError(RuntimeError):
|
||||
pass
|
||||
|
||||
class url_request( object ):
|
||||
|
||||
|
@ -72,7 +88,7 @@ class url_request( object ):
|
|||
|
||||
|
||||
class Pay( object ):
|
||||
def __init__( self, transaction, receiver_list):
|
||||
def __init__( self, transaction):
|
||||
|
||||
headers = {
|
||||
'X-PAYPAL-SECURITY-USERID':PAYPAL_USERNAME,
|
||||
|
@ -88,6 +104,25 @@ class Pay( object ):
|
|||
print "Return URL: " + return_url
|
||||
print "Cancel URL: " + cancel_url
|
||||
|
||||
receiver_list = []
|
||||
receivers = transaction.receiver_set.all()
|
||||
|
||||
if len(receivers) == 0:
|
||||
raise Exception
|
||||
|
||||
for r in receivers:
|
||||
if len(receivers) > 1:
|
||||
if r.primary:
|
||||
primary_string = 'true'
|
||||
else:
|
||||
primary_string = 'false'
|
||||
|
||||
receiver_list.append({'email':r.email,'amount':str(r.amount), 'primary':primary_string})
|
||||
else:
|
||||
receiver_list.append({'email':r.email,'amount':str(r.amount)})
|
||||
|
||||
print receiver_list
|
||||
|
||||
data = {
|
||||
'actionType': 'PAY',
|
||||
'receiverList': { 'receiver': receiver_list },
|
||||
|
@ -120,7 +155,7 @@ class Pay( object ):
|
|||
print error
|
||||
return error[0]['message']
|
||||
else:
|
||||
return None
|
||||
return 'Paypal PAY: Unknown Error'
|
||||
|
||||
def amount( self ):
|
||||
return decimal.Decimal(self.results[ 'payment_gross' ])
|
||||
|
@ -132,6 +167,51 @@ class Pay( object ):
|
|||
return '%s?cmd=_ap-payment&paykey=%s' % ( PAYPAL_PAYMENT_HOST, self.response['payKey'] )
|
||||
|
||||
|
||||
class CancelPreapproval(object):
|
||||
|
||||
def __init__(self, transaction):
|
||||
|
||||
headers = {
|
||||
'X-PAYPAL-SECURITY-USERID':PAYPAL_USERNAME,
|
||||
'X-PAYPAL-SECURITY-PASSWORD':PAYPAL_PASSWORD,
|
||||
'X-PAYPAL-SECURITY-SIGNATURE':PAYPAL_SIGNATURE,
|
||||
'X-PAYPAL-APPLICATION-ID':PAYPAL_APPID,
|
||||
'X-PAYPAL-REQUEST-DATA-FORMAT':'JSON',
|
||||
'X-PAYPAL-RESPONSE-DATA-FORMAT':'JSON',
|
||||
}
|
||||
|
||||
data = {
|
||||
'preapprovalKey':transaction.reference,
|
||||
'requestEnvelope': { 'errorLanguage': 'en_US' }
|
||||
}
|
||||
|
||||
self.raw_request = json.dumps(data)
|
||||
self.raw_response = url_request(PAYPAL_ENDPOINT, "/AdaptivePayments/CancelPreapproval", data=self.raw_request, headers=headers ).content()
|
||||
print "paypal CANCEL PREAPPROBAL response was: %s" % self.raw_response
|
||||
self.response = json.loads( self.raw_response )
|
||||
print self.response
|
||||
|
||||
def success(self):
|
||||
if self.status() == 'Success' or self.status() == "SuccessWithWarning":
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def error(self):
|
||||
if self.response.has_key('error'):
|
||||
error = self.response['error']
|
||||
print error
|
||||
return error[0]['message']
|
||||
else:
|
||||
return 'Paypal Preapproval Cancel: Unknown Error'
|
||||
|
||||
def status(self):
|
||||
if self.response.has_key( 'responseEnvelope' ) and self.response['responseEnvelope'].has_key( 'ack' ):
|
||||
return self.response['responseEnvelope']['ack']
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class Preapproval( object ):
|
||||
def __init__( self, transaction, amount ):
|
||||
|
||||
|
@ -147,14 +227,19 @@ class Preapproval( object ):
|
|||
return_url = BASE_URL + COMPLETE_URL
|
||||
cancel_url = BASE_URL + CANCEL_URL
|
||||
|
||||
# set the expiration date for the preapproval
|
||||
now = datetime.datetime.utcnow()
|
||||
expiry = now + datetime.timedelta( days=PREAPPROVAL_PERIOD )
|
||||
|
||||
expiry = now + datetime.timedelta( days=PREAPPROVAL_PERIOD )
|
||||
transaction.date_authorized = now
|
||||
transaction.date_expired = expiry
|
||||
transaction.save()
|
||||
|
||||
data = {
|
||||
'endingDate': expiry.isoformat(),
|
||||
'startingDate': now.isoformat(),
|
||||
'maxTotalAmountOfAllPayments': '%.2f' % transaction.amount,
|
||||
'maxNumberOfPayments':1,
|
||||
'maxAmountPerPayment': '%.2f' % transaction.amount,
|
||||
'currencyCode': transaction.currency,
|
||||
'returnUrl': return_url,
|
||||
'cancelUrl': cancel_url,
|
||||
|
@ -183,7 +268,7 @@ class Preapproval( object ):
|
|||
print error
|
||||
return error[0]['message']
|
||||
else:
|
||||
return None
|
||||
return 'Paypal Preapproval: Unknown Error'
|
||||
|
||||
def status( self ):
|
||||
if self.response.has_key( 'responseEnvelope' ) and self.response['responseEnvelope'].has_key( 'ack' ):
|
||||
|
@ -216,19 +301,15 @@ class IPN( object ):
|
|||
if raw_response != 'VERIFIED':
|
||||
self.error = 'PayPal response was "%s"' % raw_response
|
||||
return
|
||||
|
||||
# check payment status
|
||||
if request.POST['status'] != 'COMPLETED' and request.POST['status'] != 'ACTIVE':
|
||||
self.error = 'PayPal status was "%s"' % request.POST['status']
|
||||
return
|
||||
|
||||
# Process the details
|
||||
self.status = request.POST.get('status', None)
|
||||
self.sender_email = request.POST.get('sender_email', None)
|
||||
self.action_type = request.POST.get('action_type', None)
|
||||
self.key = request.POST.get('pay_key', None)
|
||||
self.pay_key = request.POST.get('pay_key', None)
|
||||
self.preapproval_key = request.POST.get('preapproval_key', None)
|
||||
self.transaction_type = request.POST.get('transaction_type', None)
|
||||
self.reason_code = request.POST.get('reason_code', None)
|
||||
|
||||
self.process_transactions(request)
|
||||
|
||||
|
@ -236,9 +317,21 @@ class IPN( object ):
|
|||
self.error = "Error: ServerError"
|
||||
traceback.print_exc()
|
||||
|
||||
def key(self):
|
||||
# We only keep one reference, either a prapproval key, or a pay key, for the transaction. This avoids the
|
||||
# race condition that may result if the IPN for an executed pre-approval(with both a pay key and preapproval key) is received
|
||||
# before we have time to store the pay key
|
||||
if self.preapproval_key:
|
||||
return self.preapproval_key
|
||||
elif self.pay_key:
|
||||
return self.pay_key
|
||||
else:
|
||||
return None
|
||||
|
||||
def success( self ):
|
||||
return self.error == None
|
||||
|
||||
|
||||
|
||||
@classmethod
|
||||
def slicedict(cls, d, s):
|
||||
return dict((str(k.replace(s, '', 1)), v) for k,v in d.iteritems() if k.startswith(s))
|
||||
|
|
|
@ -5,6 +5,7 @@ urlpatterns = patterns(
|
|||
url(r"^testpledge", "testPledge"),
|
||||
url(r"^testauthorize", "testAuthorize"),
|
||||
url(r"^testexecute", "testExecute"),
|
||||
url(r"^testcancel", "testCancel"),
|
||||
url(r"^querycampaign", "queryCampaign"),
|
||||
url(r"^paypalipn", "paypalIPN")
|
||||
)
|
||||
|
|
|
@ -57,7 +57,7 @@ def testExecute(request):
|
|||
|
||||
# Note, set this to 1-5 different receivers with absolute amounts for each
|
||||
receiver_list = [{'email':'jakace_1309677337_biz@gmail.com', 'amount':t.amount * 0.80},
|
||||
{'email':'boogus@gmail.com', 'amount':t.amount * 0.20}]
|
||||
{'email':'seller_1317463643_biz@gmail.com', 'amount':t.amount * 0.20}]
|
||||
|
||||
p.execute_transaction(t, receiver_list)
|
||||
output += str(t)
|
||||
|
@ -88,7 +88,7 @@ def testAuthorize(request):
|
|||
|
||||
# Note, set this to 1-5 different receivers with absolute amounts for each
|
||||
receiver_list = [{'email':'jakace_1309677337_biz@gmail.com', 'amount':20.00},
|
||||
{'email':'boogus@gmail.com', 'amount':10.00}]
|
||||
{'email':'seller_1317463643_biz@gmail.com', 'amount':10.00}]
|
||||
|
||||
if campaign_id:
|
||||
campaign = Campaign.objects.get(id=int(campaign_id))
|
||||
|
@ -106,6 +106,25 @@ def testAuthorize(request):
|
|||
print "testAuthorize: Error " + str(t.reference)
|
||||
return HttpResponse(response)
|
||||
|
||||
'''
|
||||
http://BASE/testcancel?transaction=2
|
||||
|
||||
Example that cancels a preapproved transaction
|
||||
'''
|
||||
def testCancel(request):
|
||||
|
||||
if "transaction" not in request.GET.keys():
|
||||
return HttpResponse("No Transaction in Request")
|
||||
|
||||
t = Transaction.objects.get(id=int(request.GET['transaction']))
|
||||
p = PaymentManager()
|
||||
if p.cancel(t):
|
||||
return HttpResponse("Success")
|
||||
else:
|
||||
message = "Error: " + t.error
|
||||
return HttpResponse(message)
|
||||
|
||||
|
||||
'''
|
||||
http://BASE/testpledge?campaign=2
|
||||
|
||||
|
@ -123,7 +142,7 @@ def testPledge(request):
|
|||
|
||||
# Note, set this to 1-5 different receivers with absolute amounts for each
|
||||
receiver_list = [{'email':'jakace_1309677337_biz@gmail.com', 'amount':20.00},
|
||||
{'email':'boogus@gmail.com', 'amount':10.00}]
|
||||
{'email':'seller_1317463643_biz@gmail.com', 'amount':10.00}]
|
||||
|
||||
if campaign_id:
|
||||
campaign = Campaign.objects.get(id=int(campaign_id))
|
||||
|
|
Loading…
Reference in New Issue