Adding prepaymentdetails api, enhanced error checking for paymentdetails API
parent
7dba126848
commit
0d6bc2f68a
|
@ -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()
|
||||
|
||||
|
|
|
@ -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 ):
|
||||
|
||||
|
|
Loading…
Reference in New Issue