Adding prepaymentdetails api, enhanced error checking for paymentdetails API

pull/1/head
Jason 2011-12-06 09:36:18 -05:00
parent 7dba126848
commit 0d6bc2f68a
2 changed files with 163 additions and 51 deletions

View File

@ -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, IPN_TYPE_ADJUSTMENT, Preapproval, IPN_PAY_STATUS_COMPLETED, CancelPreapproval, PaymentDetails, IPN_SENDER_STATUS_COMPLETED, IPN_TXN_STATUS_COMPLETED
from regluit.payment.paypal import Pay, IPN, IPN_TYPE_PAYMENT, IPN_TYPE_PREAPPROVAL, IPN_TYPE_ADJUSTMENT, Preapproval, IPN_PAY_STATUS_COMPLETED, CancelPreapproval, PaymentDetails, PreapprovalDetails, IPN_SENDER_STATUS_COMPLETED, IPN_TXN_STATUS_COMPLETED
import uuid
import traceback
from datetime import datetime
@ -32,8 +32,7 @@ class PaymentManager( object ):
'''
Run through all pay transactions and verify that their current status is as we think.
For now this only checks things submitted to the PAY api using the PaymentDetails. We
Should also implement PreapprovalDetails for more info
For now this only checks things submitted to the PAY api using the PaymentDetails.
'''
doc = minidom.Document()
@ -46,18 +45,19 @@ class PaymentManager( object ):
for t in transactions:
tran = doc.createElement('transaction')
tran.setAttribute("id", str(t.id))
head.appendChild(tran)
p = PaymentDetails(t)
if p.error():
logger.info("Error retrieving payment details for transaction %d" % t.id)
append_element(doc, tran, "error", "An error occurred while verifying this transaction, see server logs for details")
else:
tran = doc.createElement('transaction')
tran.setAttribute("id", str(t.id))
head.appendChild(tran)
# Check the transaction satus
# Check the transaction status
if t.status != p.status:
append_element(doc, tran, "status_ours", t.status)
append_element(doc, tran, "status_theirs", p.status)
@ -79,7 +79,45 @@ class PaymentManager( object ):
receiver.save()
except:
traceback.print_exc()
# Now look for preapprovals that have not been paid and check on their status
transactions = Transaction.objects.filter(date_authorized__gte=ref_date, date_payment=None, type=PAYMENT_TYPE_AUTHORIZATION)
for t in transactions:
p = PreapprovalDetails(t)
tran = doc.createElement('preapproval')
tran.setAttribute("key", str(t.reference))
head.appendChild(tran)
if p.error():
logger.info("Error retrieving preapproval details for transaction %d" % t.id)
append_element(doc, tran, "error", "An error occurred while verifying this transaction, see server logs for details")
else:
# Check the transaction status
if t.status != p.status:
append_element(doc, tran, "status_ours", t.status)
append_element(doc, tran, "status_theirs", p.status)
t.status = p.status
t.save()
# check the currency code
if t.currency != p.currency:
append_element(doc, tran, "currency_ours", t.currency)
append_element(doc, tran, "currency_theirs", p.currency)
t.currency = p.currency
t.save()
# Check the amount
if t.amount != D(p.amount):
append_element(doc, tran, "amount_ours", str(t.amount))
append_element(doc, tran, "amount_theirs", str(p.amount))
t.amount = p.amount
t.save()
return doc.toxml()

View File

@ -208,55 +208,73 @@ class Pay( object ):
class PaymentDetails(object):
def __init__(self, transaction=None):
self.transaction = transaction
headers = {
'X-PAYPAL-SECURITY-USERID':settings.PAYPAL_USERNAME,
'X-PAYPAL-SECURITY-PASSWORD':settings.PAYPAL_PASSWORD,
'X-PAYPAL-SECURITY-SIGNATURE':settings.PAYPAL_SIGNATURE,
'X-PAYPAL-APPLICATION-ID':settings.PAYPAL_APPID,
'X-PAYPAL-REQUEST-DATA-FORMAT':'JSON',
'X-PAYPAL-RESPONSE-DATA-FORMAT':'JSON'
}
# we can feed any of payKey, transactionId, and trackingId to identify transaction in question
# I think we've been tracking payKey. We might want to use our own trackingId (what's Transaction.secret for?)
data = {
'requestEnvelope': { 'errorLanguage': 'en_US' },
'trackingId':transaction.secret
}
self.raw_request = json.dumps(data)
self.raw_response = url_request(settings.PAYPAL_ENDPOINT, "/AdaptivePayments/PaymentDetails", data=self.raw_request, headers=headers ).content()
logger.info("paypal PaymentDetails response was: %s" % self.raw_response)
self.response = json.loads( self.raw_response )
logger.info(self.response)
self.status = self.response.get("status", None)
self.trackingId = self.response.get("trackingId", None)
self.feesPayer = self.response.get("feesPayer", None)
payment_info_list = self.response.get("paymentInfoList", None)
payment_info = payment_info_list.get("paymentInfo", None)
self.transactions = []
for payment in payment_info:
receiver = {}
receiver['status'] = payment.get("transactionStatus", None)
receiver['txn_id'] = payment.get("transactionId")
try:
self.transaction = transaction
self.errorMessage = None
self.response = None
r = payment.get("receiver", None)
if r:
receiver['email'] = r.get('email')
headers = {
'X-PAYPAL-SECURITY-USERID':settings.PAYPAL_USERNAME,
'X-PAYPAL-SECURITY-PASSWORD':settings.PAYPAL_PASSWORD,
'X-PAYPAL-SECURITY-SIGNATURE':settings.PAYPAL_SIGNATURE,
'X-PAYPAL-APPLICATION-ID':settings.PAYPAL_APPID,
'X-PAYPAL-REQUEST-DATA-FORMAT':'JSON',
'X-PAYPAL-RESPONSE-DATA-FORMAT':'JSON'
}
# we can feed any of payKey, transactionId, and trackingId to identify transaction in question
# I think we've been tracking payKey. We might want to use our own trackingId (what's Transaction.secret for?)
data = {
'requestEnvelope': { 'errorLanguage': 'en_US' },
'trackingId':transaction.secret
}
self.raw_request = json.dumps(data)
self.connection = url_request(settings.PAYPAL_ENDPOINT, "/AdaptivePayments/PaymentDetails", data=self.raw_request, headers=headers )
self.raw_response = self.connection.content()
self.code = self.connection.code()
if self.code != 200:
self.errorMessage = 'PayPal response code was %i' % self.code
return
logger.info("paypal PaymentDetails response was: %s" % self.raw_response)
self.response = json.loads( self.raw_response )
logger.info(self.response)
self.status = self.response.get("status", None)
self.trackingId = self.response.get("trackingId", None)
self.feesPayer = self.response.get("feesPayer", None)
payment_info_list = self.response.get("paymentInfoList", None)
payment_info = payment_info_list.get("paymentInfo", None)
self.transactions = []
for payment in payment_info:
receiver = {}
receiver['status'] = payment.get("transactionStatus", None)
receiver['txn_id'] = payment.get("transactionId")
self.transactions.append(receiver)
r = payment.get("receiver", None)
if r:
receiver['email'] = r.get('email')
self.transactions.append(receiver)
except:
self.errorMessage = "Error: ServerError"
traceback.print_exc()
def error(self):
if self.response.has_key('error'):
if self.response and self.response.has_key('error'):
error = self.response['error']
logger.info(error)
return error[0]['message']
elif self.errorMessage:
return self.errorMessage
else:
return None
@ -408,7 +426,63 @@ class Preapproval( object ):
class PreapprovalDetails(object):
pass
def __init__(self, transaction):
try:
self.transaction = transaction
self.response = None
self.errorMessage = None
headers = {
'X-PAYPAL-SECURITY-USERID':settings.PAYPAL_USERNAME,
'X-PAYPAL-SECURITY-PASSWORD':settings.PAYPAL_PASSWORD,
'X-PAYPAL-SECURITY-SIGNATURE':settings.PAYPAL_SIGNATURE,
'X-PAYPAL-APPLICATION-ID':settings.PAYPAL_APPID,
'X-PAYPAL-REQUEST-DATA-FORMAT':'JSON',
'X-PAYPAL-RESPONSE-DATA-FORMAT':'JSON'
}
# we can feed any of payKey, transactionId, and trackingId to identify transaction in question
# I think we've been tracking payKey. We might want to use our own trackingId (what's Transaction.secret for?)
data = {
'requestEnvelope': { 'errorLanguage': 'en_US' },
'preapprovalKey':transaction.reference
}
self.raw_request = json.dumps(data)
self.connection = url_request(settings.PAYPAL_ENDPOINT, "/AdaptivePayments/PreapprovalDetails", data=self.raw_request, headers=headers )
self.raw_response = self.connection.content()
self.code = self.connection.code()
if self.code != 200:
self.errorMessage = 'PayPal response code was %i' % self.code
return
logger.info("paypal PreapprovalDetails response was: %s" % self.raw_response)
self.response = json.loads( self.raw_response )
logger.info(self.response)
self.status = self.response.get("status", None)
self.amount = self.response.get("maxTotalAmountOfAllPayments", None)
self.currency = self.response.get("currencyCode", None)
self.approved = self.response.get("approved", None)
self.expiration = self.response.get("endingDate", None)
self.date = self.response.get("startingDate", None)
except:
self.errorMessage = "Error: ServerError"
traceback.print_exc()
def error(self):
if self.response and self.response.has_key('error'):
error = self.response['error']
logger.info(error)
return error[0]['message']
elif self.errorMessage:
return self.errorMessage
else:
return None
class IPN( object ):