resolve conflicts
commit
a6e685618c
|
@ -7,13 +7,7 @@
|
||||||
<link type="text/css" rel="stylesheet" href="/static/css/campaign.css" />
|
<link type="text/css" rel="stylesheet" href="/static/css/campaign.css" />
|
||||||
<link type="text/css" rel="stylesheet" href="/static/css/pledge.css" />
|
<link type="text/css" rel="stylesheet" href="/static/css/pledge.css" />
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript" src="/static/js/reconcile_pledge.js"></script>
|
||||||
var $j = jQuery.noConflict();
|
|
||||||
//give pledge box focus
|
|
||||||
$j(function() {
|
|
||||||
$j('#id_preapproval_amount').focus();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block doccontent %}
|
{% block doccontent %}
|
||||||
|
|
|
@ -57,10 +57,14 @@ try:
|
||||||
FPS_SECRET_KEY = Key.objects.get(name="FPS_SECRET_KEY").value
|
FPS_SECRET_KEY = Key.objects.get(name="FPS_SECRET_KEY").value
|
||||||
logger.info('Successful loading of FPS_*_KEYs')
|
logger.info('Successful loading of FPS_*_KEYs')
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
FPS_ACCESS_KEY = ''
|
|
||||||
FPS_SECRET_KEY = ''
|
|
||||||
logger.info('EXCEPTION: unsuccessful loading of FPS_*_KEYs: {0}'.format(e))
|
logger.info('EXCEPTION: unsuccessful loading of FPS_*_KEYs: {0}'.format(e))
|
||||||
|
|
||||||
|
def get_ipn_url():
|
||||||
|
|
||||||
|
if settings.IPN_SECURE_URL:
|
||||||
|
return settings.BASE_URL_SECURE + reverse('HandleIPN', args=["amazon"])
|
||||||
|
else:
|
||||||
|
return settings.BASE_URL + reverse('HandleIPN', args=["amazon"])
|
||||||
|
|
||||||
def ProcessIPN(request):
|
def ProcessIPN(request):
|
||||||
'''
|
'''
|
||||||
|
@ -89,6 +93,7 @@ def ProcessIPN(request):
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
logging.debug("Amazon IPN called")
|
logging.debug("Amazon IPN called")
|
||||||
|
logging.debug(request.POST)
|
||||||
|
|
||||||
uri = request.build_absolute_uri()
|
uri = request.build_absolute_uri()
|
||||||
parsed_url = urlparse.urlparse(uri)
|
parsed_url = urlparse.urlparse(uri)
|
||||||
|
@ -338,7 +343,6 @@ class AmazonRequest:
|
||||||
|
|
||||||
def success(self):
|
def success(self):
|
||||||
|
|
||||||
print "CALLING SUCCESS"
|
|
||||||
if self.errorMessage:
|
if self.errorMessage:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -483,7 +487,7 @@ class Execute(AmazonRequest):
|
||||||
self.transaction = transaction
|
self.transaction = transaction
|
||||||
|
|
||||||
# BUGBUG, handle multiple receivers! For now we just send the money to ourselves
|
# BUGBUG, handle multiple receivers! For now we just send the money to ourselves
|
||||||
|
global_params = {"OverrideIPNURL": get_ipn_url()}
|
||||||
self.raw_response = self.connection.pay(transaction.amount,
|
self.raw_response = self.connection.pay(transaction.amount,
|
||||||
transaction.pay_key,
|
transaction.pay_key,
|
||||||
recipientTokenId=None,
|
recipientTokenId=None,
|
||||||
|
@ -495,7 +499,8 @@ class Execute(AmazonRequest):
|
||||||
callerDescription=None,
|
callerDescription=None,
|
||||||
metadata=None,
|
metadata=None,
|
||||||
transactionDate=None,
|
transactionDate=None,
|
||||||
reserve=False)
|
reserve=False,
|
||||||
|
extra_params=global_params)
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUGBUG:
|
# BUGBUG:
|
||||||
|
@ -653,14 +658,15 @@ class CancelPreapproval(AmazonRequest):
|
||||||
self.connection = FPSConnection(FPS_ACCESS_KEY, FPS_SECRET_KEY, host=settings.AMAZON_FPS_HOST)
|
self.connection = FPSConnection(FPS_ACCESS_KEY, FPS_SECRET_KEY, host=settings.AMAZON_FPS_HOST)
|
||||||
self.transaction = transaction
|
self.transaction = transaction
|
||||||
|
|
||||||
params = {}
|
global_params = {"OverrideIPNURL": get_ipn_url()}
|
||||||
|
params = global_params
|
||||||
params['TokenId'] = transaction.pay_key
|
params['TokenId'] = transaction.pay_key
|
||||||
params['ReasonText'] = "Cancel Reason"
|
params['ReasonText'] = "Cancel Reason"
|
||||||
|
|
||||||
fps_response = self.connection.make_request("CancelToken", params)
|
fps_response = self.connection.make_request("CancelToken", params)
|
||||||
|
|
||||||
body = fps_response.read()
|
body = fps_response.read()
|
||||||
print body
|
|
||||||
if(fps_response.status == 200):
|
if(fps_response.status == 200):
|
||||||
|
|
||||||
rs = ResultSet()
|
rs = ResultSet()
|
||||||
|
@ -716,7 +722,8 @@ class RefundPayment(AmazonRequest):
|
||||||
# We need to reference the transaction ID here, this is stored in the preapproval_key as this
|
# We need to reference the transaction ID here, this is stored in the preapproval_key as this
|
||||||
# field is not used for amazon
|
# field is not used for amazon
|
||||||
#
|
#
|
||||||
self.raw_response = self.connection.refund(transaction.secret, transaction.preapproval_key)
|
global_params = {"OverrideIPNURL": get_ipn_url()}
|
||||||
|
self.raw_response = self.connection.refund(transaction.secret, transaction.preapproval_key, extra_params=global_params)
|
||||||
self.response = self.raw_response[0]
|
self.response = self.raw_response[0]
|
||||||
|
|
||||||
logging.debug("Amazon REFUNDPAYMENT response was:")
|
logging.debug("Amazon REFUNDPAYMENT response was:")
|
||||||
|
|
|
@ -24,7 +24,6 @@ import urllib, urlparse
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def append_element(doc, parent, name, text):
|
def append_element(doc, parent, name, text):
|
||||||
|
@ -42,15 +41,18 @@ class PaymentManager( object ):
|
||||||
def __init__( self, embedded=False):
|
def __init__( self, embedded=False):
|
||||||
self.embedded = embedded
|
self.embedded = embedded
|
||||||
|
|
||||||
def processIPN(self, request):
|
def processIPN(self, request, module):
|
||||||
|
|
||||||
# Forward to our payment processor
|
# Forward to our payment processor
|
||||||
return ProcessIPN(request)
|
mod = __import__("regluit.payment." + module, fromlist=[str(module)])
|
||||||
|
method = getattr(mod, "ProcessIPN")
|
||||||
|
return method(request)
|
||||||
|
|
||||||
def update_preapproval(self, transaction):
|
def update_preapproval(self, transaction):
|
||||||
"""Update a transaction to hold the data from a PreapprovalDetails on that transaction"""
|
"""Update a transaction to hold the data from a PreapprovalDetails on that transaction"""
|
||||||
t = transaction
|
t = transaction
|
||||||
p = PreapprovalDetails(t)
|
method = getattr(transaction.get_payment_class(), "PreapprovalDetails")
|
||||||
|
p = method(t)
|
||||||
|
|
||||||
preapproval_status = {'id':t.id, 'key':t.preapproval_key}
|
preapproval_status = {'id':t.id, 'key':t.preapproval_key}
|
||||||
|
|
||||||
|
@ -102,7 +104,8 @@ class PaymentManager( object ):
|
||||||
t = transaction
|
t = transaction
|
||||||
payment_status = {'id':t.id}
|
payment_status = {'id':t.id}
|
||||||
|
|
||||||
p = PaymentDetails(t)
|
method = getattr(transaction.get_payment_class(), "PaymentDetails")
|
||||||
|
p = method(t)
|
||||||
|
|
||||||
if p.error() or not p.success():
|
if p.error() or not p.success():
|
||||||
logger.info("Error retrieving payment details for transaction %d" % t.id)
|
logger.info("Error retrieving payment details for transaction %d" % t.id)
|
||||||
|
@ -422,7 +425,8 @@ class PaymentManager( object ):
|
||||||
transaction.date_executed = now()
|
transaction.date_executed = now()
|
||||||
transaction.save()
|
transaction.save()
|
||||||
|
|
||||||
p = Finish(transaction)
|
method = getattr(transaction.get_payment_class(), "Finish")
|
||||||
|
p = method(transaction)
|
||||||
|
|
||||||
# Create a response for this
|
# Create a response for this
|
||||||
envelope = p.envelope()
|
envelope = p.envelope()
|
||||||
|
@ -476,7 +480,8 @@ class PaymentManager( object ):
|
||||||
transaction.date_payment = now()
|
transaction.date_payment = now()
|
||||||
transaction.save()
|
transaction.save()
|
||||||
|
|
||||||
p = Execute(transaction)
|
method = getattr(transaction.get_payment_class(), "Execute")
|
||||||
|
p = method(transaction)
|
||||||
|
|
||||||
# Create a response for this
|
# Create a response for this
|
||||||
envelope = p.envelope()
|
envelope = p.envelope()
|
||||||
|
@ -515,7 +520,8 @@ class PaymentManager( object ):
|
||||||
return value: True if successful, false otherwise
|
return value: True if successful, false otherwise
|
||||||
'''
|
'''
|
||||||
|
|
||||||
p = CancelPreapproval(transaction)
|
method = getattr(transaction.get_payment_class(), "CancelPreapproval")
|
||||||
|
p = method(transaction)
|
||||||
|
|
||||||
# Create a response for this
|
# Create a response for this
|
||||||
envelope = p.envelope()
|
envelope = p.envelope()
|
||||||
|
@ -593,7 +599,8 @@ class PaymentManager( object ):
|
||||||
urllib.urlencode({'tid':t.id}))
|
urllib.urlencode({'tid':t.id}))
|
||||||
return_url = urlparse.urljoin(settings.BASE_URL, return_path)
|
return_url = urlparse.urljoin(settings.BASE_URL, return_path)
|
||||||
|
|
||||||
p = Preapproval(t, amount, expiry, return_url=return_url, cancel_url=cancel_url, paymentReason=paymentReason)
|
method = getattr(t.get_payment_class(), "Preapproval")
|
||||||
|
p = method(t, amount, expiry, return_url=return_url, cancel_url=cancel_url, paymentReason=paymentReason)
|
||||||
|
|
||||||
# Create a response for this
|
# Create a response for this
|
||||||
envelope = p.envelope()
|
envelope = p.envelope()
|
||||||
|
@ -716,7 +723,8 @@ class PaymentManager( object ):
|
||||||
logger.info("Refund Transaction failed, invalid transaction status")
|
logger.info("Refund Transaction failed, invalid transaction status")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
p = RefundPayment(transaction)
|
method = getattr(transaction.get_payment_class(), "RefundPayment")
|
||||||
|
p = method(transaction)
|
||||||
|
|
||||||
# Create a response for this
|
# Create a response for this
|
||||||
envelope = p.envelope()
|
envelope = p.envelope()
|
||||||
|
@ -791,8 +799,8 @@ class PaymentManager( object ):
|
||||||
)
|
)
|
||||||
|
|
||||||
t.create_receivers(receiver_list)
|
t.create_receivers(receiver_list)
|
||||||
|
method = getattr(t.get_payment_class(), "Pay")
|
||||||
p = Pay(t,return_url=return_url, cancel_url=cancel_url)
|
p = method(t,return_url=return_url, cancel_url=cancel_url)
|
||||||
|
|
||||||
# Create a response for this
|
# Create a response for this
|
||||||
envelope = p.envelope()
|
envelope = p.envelope()
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
|
||||||
|
# Adding field 'Transaction.host'
|
||||||
|
db.add_column('payment_transaction', 'host', self.gf('django.db.models.fields.CharField')(default='amazon', max_length=32), keep_default=False)
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
|
||||||
|
# Deleting field 'Transaction.host'
|
||||||
|
db.delete_column('payment_transaction', 'host')
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'auth.group': {
|
||||||
|
'Meta': {'object_name': 'Group'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||||
|
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||||
|
},
|
||||||
|
'auth.user': {
|
||||||
|
'Meta': {'object_name': 'User'},
|
||||||
|
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||||
|
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||||
|
},
|
||||||
|
'core.campaign': {
|
||||||
|
'Meta': {'object_name': 'Campaign'},
|
||||||
|
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||||
|
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||||
|
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'deadline': ('django.db.models.fields.DateTimeField', [], {}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
|
||||||
|
'details': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'null': 'True', 'to': "orm['core.Edition']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
|
||||||
|
'license': ('django.db.models.fields.CharField', [], {'default': "'CC BY-NC-ND'", 'max_length': '255'}),
|
||||||
|
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
|
||||||
|
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True'}),
|
||||||
|
'target': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
|
||||||
|
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
|
||||||
|
},
|
||||||
|
'core.edition': {
|
||||||
|
'Meta': {'object_name': 'Edition'},
|
||||||
|
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
|
||||||
|
'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
|
||||||
|
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.Work']"})
|
||||||
|
},
|
||||||
|
'core.premium': {
|
||||||
|
'Meta': {'object_name': 'Premium'},
|
||||||
|
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
|
||||||
|
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
|
||||||
|
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'limit': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||||
|
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
|
||||||
|
},
|
||||||
|
'core.wishes': {
|
||||||
|
'Meta': {'object_name': 'Wishes', 'db_table': "'core_wishlist_works'"},
|
||||||
|
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'source': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
|
||||||
|
'wishlist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']"}),
|
||||||
|
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wishes'", 'to': "orm['core.Work']"})
|
||||||
|
},
|
||||||
|
'core.wishlist': {
|
||||||
|
'Meta': {'object_name': 'Wishlist'},
|
||||||
|
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}),
|
||||||
|
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'through': "orm['core.Wishes']", 'to': "orm['core.Work']"})
|
||||||
|
},
|
||||||
|
'core.work': {
|
||||||
|
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
|
||||||
|
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
|
||||||
|
'num_wishes': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||||
|
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||||
|
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
|
||||||
|
},
|
||||||
|
'payment.paymentresponse': {
|
||||||
|
'Meta': {'object_name': 'PaymentResponse'},
|
||||||
|
'api': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||||
|
'correlation_id': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'info': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
|
||||||
|
'timestamp': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
|
||||||
|
'transaction': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['payment.Transaction']"})
|
||||||
|
},
|
||||||
|
'payment.receiver': {
|
||||||
|
'Meta': {'object_name': 'Receiver'},
|
||||||
|
'amount': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '14', 'decimal_places': '2'}),
|
||||||
|
'currency': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
|
||||||
|
'email': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'local_status': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}),
|
||||||
|
'primary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'reason': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||||
|
'status': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||||
|
'transaction': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['payment.Transaction']"}),
|
||||||
|
'txn_id': ('django.db.models.fields.CharField', [], {'max_length': '64'})
|
||||||
|
},
|
||||||
|
'payment.transaction': {
|
||||||
|
'Meta': {'object_name': 'Transaction'},
|
||||||
|
'amount': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '14', 'decimal_places': '2'}),
|
||||||
|
'anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'approved': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Campaign']", 'null': 'True'}),
|
||||||
|
'currency': ('django.db.models.fields.CharField', [], {'default': "'USD'", 'max_length': '10', 'null': 'True'}),
|
||||||
|
'date_authorized': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||||
|
'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'date_executed': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||||
|
'date_expired': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||||
|
'date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||||
|
'date_payment': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||||
|
'error': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True'}),
|
||||||
|
'execution': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||||
|
'host': ('django.db.models.fields.CharField', [], {'default': "'amazon'", 'max_length': '32'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'list': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']", 'null': 'True'}),
|
||||||
|
'local_status': ('django.db.models.fields.CharField', [], {'default': "'NONE'", 'max_length': '32', 'null': 'True'}),
|
||||||
|
'max_amount': ('django.db.models.fields.DecimalField', [], {'default': "'0.00'", 'max_digits': '14', 'decimal_places': '2'}),
|
||||||
|
'pay_key': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
|
||||||
|
'preapproval_key': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
|
||||||
|
'premium': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Premium']", 'null': 'True'}),
|
||||||
|
'reason': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}),
|
||||||
|
'receipt': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True'}),
|
||||||
|
'secret': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.CharField', [], {'default': "'None'", 'max_length': '32'}),
|
||||||
|
'target': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||||
|
'type': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['payment']
|
|
@ -10,6 +10,9 @@ class Transaction(models.Model):
|
||||||
# type e.g., PAYMENT_TYPE_INSTANT or PAYMENT_TYPE_AUTHORIZATION -- defined in parameters.py
|
# type e.g., PAYMENT_TYPE_INSTANT or PAYMENT_TYPE_AUTHORIZATION -- defined in parameters.py
|
||||||
type = models.IntegerField(default=PAYMENT_TYPE_NONE, null=False)
|
type = models.IntegerField(default=PAYMENT_TYPE_NONE, null=False)
|
||||||
|
|
||||||
|
# host: the payment processor. Named after the payment module that hosts the payment processing functions
|
||||||
|
host = models.CharField(default=PAYMENT_HOST_AMAZON, max_length=32, null=False)
|
||||||
|
|
||||||
# target: e.g, TARGET_TYPE_CAMPAIGN, TARGET_TYPE_LIST -- defined in parameters.py
|
# target: e.g, TARGET_TYPE_CAMPAIGN, TARGET_TYPE_LIST -- defined in parameters.py
|
||||||
target = models.IntegerField(default=TARGET_TYPE_NONE, null=False)
|
target = models.IntegerField(default=TARGET_TYPE_NONE, null=False)
|
||||||
|
|
||||||
|
@ -88,6 +91,16 @@ class Transaction(models.Model):
|
||||||
receiver = Receiver.objects.create(email=r['email'], amount=r['amount'], currency=self.currency, status="None", primary=primary, transaction=self)
|
receiver = Receiver.objects.create(email=r['email'], amount=r['amount'], currency=self.currency, status="None", primary=primary, transaction=self)
|
||||||
primary = False
|
primary = False
|
||||||
|
|
||||||
|
def get_payment_class(self):
|
||||||
|
'''
|
||||||
|
Returns the specific payment module that implements this transaction
|
||||||
|
'''
|
||||||
|
if self.host == PAYMENT_HOST_NONE:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
mod = __import__("regluit.payment." + self.host, fromlist=[str(self.host)])
|
||||||
|
return mod
|
||||||
|
|
||||||
|
|
||||||
class PaymentResponse(models.Model):
|
class PaymentResponse(models.Model):
|
||||||
# The API used
|
# The API used
|
||||||
|
|
|
@ -2,6 +2,10 @@ PAYMENT_TYPE_NONE = 0
|
||||||
PAYMENT_TYPE_INSTANT = 1
|
PAYMENT_TYPE_INSTANT = 1
|
||||||
PAYMENT_TYPE_AUTHORIZATION = 2
|
PAYMENT_TYPE_AUTHORIZATION = 2
|
||||||
|
|
||||||
|
PAYMENT_HOST_NONE = "none"
|
||||||
|
PAYMENT_HOST_PAYPAL = "paypal"
|
||||||
|
PAYMENT_HOST_AMAZON = "amazon"
|
||||||
|
|
||||||
EXECUTE_TYPE_NONE = 0
|
EXECUTE_TYPE_NONE = 0
|
||||||
EXECUTE_TYPE_CHAINED_INSTANT = 1
|
EXECUTE_TYPE_CHAINED_INSTANT = 1
|
||||||
EXECUTE_TYPE_CHAINED_DELAYED = 2
|
EXECUTE_TYPE_CHAINED_DELAYED = 2
|
||||||
|
|
|
@ -344,6 +344,7 @@ class PaypalEnvelopeRequest:
|
||||||
|
|
||||||
def success(self):
|
def success(self):
|
||||||
status = self.ack()
|
status = self.ack()
|
||||||
|
|
||||||
# print status
|
# print status
|
||||||
if status == "Success" or status == "SuccessWithWarning":
|
if status == "Success" or status == "SuccessWithWarning":
|
||||||
return True
|
return True
|
||||||
|
@ -402,7 +403,6 @@ class PaypalEnvelopeRequest:
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class Pay( PaypalEnvelopeRequest ):
|
class Pay( PaypalEnvelopeRequest ):
|
||||||
def __init__( self, transaction, return_url=None, cancel_url=None, paymentReason=""):
|
def __init__( self, transaction, return_url=None, cancel_url=None, paymentReason=""):
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ class Pay( PaypalEnvelopeRequest ):
|
||||||
'returnUrl': return_url,
|
'returnUrl': return_url,
|
||||||
'cancelUrl': cancel_url,
|
'cancelUrl': cancel_url,
|
||||||
'requestEnvelope': { 'errorLanguage': 'en_US' },
|
'requestEnvelope': { 'errorLanguage': 'en_US' },
|
||||||
'ipnNotificationUrl': settings.BASE_URL + reverse('HandleIPN'),
|
'ipnNotificationUrl': settings.BASE_URL + reverse('HandleIPN', args=["paypal"]),
|
||||||
'feesPayer': feesPayer,
|
'feesPayer': feesPayer,
|
||||||
'trackingId': transaction.secret
|
'trackingId': transaction.secret
|
||||||
}
|
}
|
||||||
|
@ -536,6 +536,14 @@ class Pay( PaypalEnvelopeRequest ):
|
||||||
return '%s/webapps/adaptivepayment/flow/pay?paykey=%s&expType=light' % ( settings.PAYPAL_PAYMENT_HOST, self.response['payKey'] )
|
return '%s/webapps/adaptivepayment/flow/pay?paykey=%s&expType=light' % ( settings.PAYPAL_PAYMENT_HOST, self.response['payKey'] )
|
||||||
|
|
||||||
|
|
||||||
|
class Execute(Pay):
|
||||||
|
'''
|
||||||
|
For payapl, execute is the same as pay. The pay funciton detects whether an execute or a co-branded operation
|
||||||
|
is called for.
|
||||||
|
'''
|
||||||
|
def __init__(self, transaction, return_url=None, cancel_url=None):
|
||||||
|
# Call our super class. In python 2.2+, we can't use super here, so just call init directly
|
||||||
|
Pay.__init__(self, transaction, return_url, cancel_url)
|
||||||
|
|
||||||
class Finish(PaypalEnvelopeRequest):
|
class Finish(PaypalEnvelopeRequest):
|
||||||
|
|
||||||
|
@ -817,7 +825,7 @@ class Preapproval( PaypalEnvelopeRequest ):
|
||||||
'returnUrl': return_url,
|
'returnUrl': return_url,
|
||||||
'cancelUrl': cancel_url,
|
'cancelUrl': cancel_url,
|
||||||
'requestEnvelope': { 'errorLanguage': 'en_US' },
|
'requestEnvelope': { 'errorLanguage': 'en_US' },
|
||||||
'ipnNotificationUrl': settings.BASE_URL + reverse('HandleIPN')
|
'ipnNotificationUrl': settings.BASE_URL + reverse('HandleIPN', args=["paypal"])
|
||||||
}
|
}
|
||||||
|
|
||||||
# Is ipnNotificationUrl being computed properly
|
# Is ipnNotificationUrl being computed properly
|
||||||
|
|
|
@ -4,8 +4,7 @@ from django.conf import settings
|
||||||
|
|
||||||
urlpatterns = patterns(
|
urlpatterns = patterns(
|
||||||
"regluit.payment.views",
|
"regluit.payment.views",
|
||||||
url(r"^paypalipn", "handleIPN", name="HandleIPN"),
|
url(r"^handleipn/(?P<module>\w+)$", "handleIPN", name="HandleIPN"),
|
||||||
url(r"^amazonipn", "handleIPN", name="HandleIPN"),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Amazon payment URLs
|
# Amazon payment URLs
|
||||||
|
|
|
@ -26,7 +26,7 @@ import logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# parameterize some test recipients
|
# parameterize some test recipients
|
||||||
TEST_RECEIVERS = ['raymond.yee@gmail.com', 'Buyer6_1325742408_per@gmail.com']
|
TEST_RECEIVERS = ['seller_1317463643_biz@gmail.com', 'buyer5_1325740224_per@gmail.com']
|
||||||
#TEST_RECEIVERS = ['seller_1317463643_biz@gmail.com', 'Buyer6_1325742408_per@gmail.com']
|
#TEST_RECEIVERS = ['seller_1317463643_biz@gmail.com', 'Buyer6_1325742408_per@gmail.com']
|
||||||
#TEST_RECEIVERS = ['glueja_1317336101_biz@gluejar.com', 'rh1_1317336251_biz@gluejar.com', 'RH2_1317336302_biz@gluejar.com']
|
#TEST_RECEIVERS = ['glueja_1317336101_biz@gluejar.com', 'rh1_1317336251_biz@gluejar.com', 'RH2_1317336302_biz@gluejar.com']
|
||||||
|
|
||||||
|
@ -294,11 +294,11 @@ def runTests(request):
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
def handleIPN(request):
|
def handleIPN(request, module):
|
||||||
# Handler for paypal IPN notifications
|
# Handler for paypal IPN notifications
|
||||||
|
|
||||||
p = PaymentManager()
|
p = PaymentManager()
|
||||||
p.processIPN(request)
|
p.processIPN(request, module)
|
||||||
|
|
||||||
logger.info(str(request.POST))
|
logger.info(str(request.POST))
|
||||||
return HttpResponse("ipn")
|
return HttpResponse("ipn")
|
||||||
|
|
|
@ -20,9 +20,9 @@ django-endless-pagination
|
||||||
django-selectable
|
django-selectable
|
||||||
pytz
|
pytz
|
||||||
django-notification
|
django-notification
|
||||||
boto
|
git+ssh://git@github.com/Gluejar/boto.git@2.3.0
|
||||||
fabric
|
fabric
|
||||||
git+git://github.com/agiliq/merchant.git#egg=django-merchant
|
#git+git://github.com/agiliq/merchant.git#egg=django-merchant
|
||||||
paramiko
|
paramiko
|
||||||
pyasn1
|
pyasn1
|
||||||
pycrypto
|
pycrypto
|
||||||
|
|
|
@ -94,6 +94,8 @@ PAYPAL_NONPROFIT_PARTNER_EMAIL = "nppart_1318957063_per@gluejar.com"
|
||||||
PAYPAL_TEST_RH_EMAIL = "rh1_1317336251_biz@gluejar.com"
|
PAYPAL_TEST_RH_EMAIL = "rh1_1317336251_biz@gluejar.com"
|
||||||
|
|
||||||
BASE_URL = 'http://0.0.0.0'
|
BASE_URL = 'http://0.0.0.0'
|
||||||
|
BASE_URL_SECURE = 'https://0.0.0.0'
|
||||||
|
IPN_SECURE_URL = True
|
||||||
|
|
||||||
# use database as queuing service in development
|
# use database as queuing service in development
|
||||||
BROKER_TRANSPORT = "djkombu.transport.DatabaseTransport"
|
BROKER_TRANSPORT = "djkombu.transport.DatabaseTransport"
|
||||||
|
|
|
@ -91,6 +91,8 @@ CELERYD_HIJACK_ROOT_LOGGER = False
|
||||||
# BASE_URL is a hard-coding of the domain name for site and used for PayPal IPN
|
# BASE_URL is a hard-coding of the domain name for site and used for PayPal IPN
|
||||||
# Next step to try https
|
# Next step to try https
|
||||||
BASE_URL = 'http://just.unglueit.com'
|
BASE_URL = 'http://just.unglueit.com'
|
||||||
|
BASE_URL_SECURE = 'https://just.unglueit.com'
|
||||||
|
IPN_SECURE_URL = False
|
||||||
|
|
||||||
# use redis for production queue
|
# use redis for production queue
|
||||||
BROKER_TRANSPORT = "redis"
|
BROKER_TRANSPORT = "redis"
|
||||||
|
|
|
@ -90,6 +90,8 @@ CELERYD_HIJACK_ROOT_LOGGER = False
|
||||||
# BASE_URL is a hard-coding of the domain name for site and used for PayPal IPN
|
# BASE_URL is a hard-coding of the domain name for site and used for PayPal IPN
|
||||||
# Next step to try https
|
# Next step to try https
|
||||||
BASE_URL = 'http://please.unglueit.com'
|
BASE_URL = 'http://please.unglueit.com'
|
||||||
|
BASE_URL_SECURE = 'https://please.unglueit.com'
|
||||||
|
IPN_SECURE_URL = False
|
||||||
|
|
||||||
# use redis for production queue
|
# use redis for production queue
|
||||||
BROKER_TRANSPORT = "redis"
|
BROKER_TRANSPORT = "redis"
|
||||||
|
|
|
@ -92,6 +92,8 @@ CELERYD_HIJACK_ROOT_LOGGER = False
|
||||||
# BASE_URL is a hard-coding of the domain name for site and used for PayPal IPN
|
# BASE_URL is a hard-coding of the domain name for site and used for PayPal IPN
|
||||||
# Next step to try https
|
# Next step to try https
|
||||||
BASE_URL = 'http://unglue.it'
|
BASE_URL = 'http://unglue.it'
|
||||||
|
BASE_URL_SECURE = 'https://unglue.it'
|
||||||
|
IPN_SECURE_URL = False
|
||||||
|
|
||||||
# use redis for production queue
|
# use redis for production queue
|
||||||
BROKER_TRANSPORT = "redis"
|
BROKER_TRANSPORT = "redis"
|
||||||
|
|
|
@ -8,7 +8,7 @@ $j(document).ready(function(){
|
||||||
$j('#js-topsection').css({"opacity": "0.15"});
|
$j('#js-topsection').css({"opacity": "0.15"});
|
||||||
$j('#main-container').css({"opacity": "0.15"});
|
$j('#main-container').css({"opacity": "0.15"});
|
||||||
$j('#js-rightcol').css({"visibility":"hidden"});
|
$j('#js-rightcol').css({"visibility":"hidden"});
|
||||||
$j('#expandable').css({"position": "absolute", "z-index": "100", "left":"50%", "margin-left": "-115px"}).fadeTo("slow", 1);;
|
$j('#expandable').css({"position": "absolute", "z-index": "100", "left":"50%", "margin-left": "-115px"}).fadeTo("slow", 1);
|
||||||
});
|
});
|
||||||
$j('#collapser').click(function(){
|
$j('#collapser').click(function(){
|
||||||
$j('#js-topsection').fadeTo("slow", 1);
|
$j('#js-topsection').fadeTo("slow", 1);
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
var $j = jQuery.noConflict();
|
||||||
|
// give pledge box focus
|
||||||
|
$j(function() {
|
||||||
|
$j('#id_preapproval_amount').focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
// if amount in pledge box is too small to qualify for premium, call attention to it
|
||||||
|
// and disable the input button with a helpful message
|
||||||
|
// when they fix it, revert to original styling and reactivate button
|
||||||
|
|
||||||
|
$j().ready(function() {
|
||||||
|
// cache these to speed things up
|
||||||
|
var inputbox = $j('#id_preapproval_amount');
|
||||||
|
var submitbutton = $j('#pledgesubmit');
|
||||||
|
|
||||||
|
var canonicalize = function(amt) {
|
||||||
|
// takes an input button from the premiums list
|
||||||
|
// finds the premium amount its associated the span class
|
||||||
|
// converts to usable integer form and returns
|
||||||
|
amt = amt.siblings('span.menu-item-price').html();
|
||||||
|
amt = amt.split('$')[1];
|
||||||
|
amt = parseInt(amt);
|
||||||
|
return amt;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mayday = function() {
|
||||||
|
// highlights pledge box and submit button in alert color
|
||||||
|
// disables submit button and overwrites with help text
|
||||||
|
inputbox.css({'border-color': '#e35351', 'background-color': '#e35351', 'color': 'white'});
|
||||||
|
submitbutton.css({'background-color': '#e35351', 'cursor': 'default', 'font-weight': 'normal', 'font-size': '15px'});
|
||||||
|
submitbutton.val("You must pledge at least $"+amount+" for that premium");
|
||||||
|
submitbutton.attr('disabled', 'disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
var allclear = function() {
|
||||||
|
// returns pledge box and submit button to conventional colors
|
||||||
|
// enables submit button and rewrites with original text
|
||||||
|
inputbox.css({'border-color': '#8dc63f', 'background-color': 'white', 'color': '#3d4e53'});
|
||||||
|
submitbutton.css({'background-color': '#8dc63f', 'cursor': 'pointer', 'font-weight': 'bold', 'font-size': '17px'});
|
||||||
|
submitbutton.val("Modify Pledge");
|
||||||
|
submitbutton.removeAttr('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
$j('#premiums_list input').on("click", function() {
|
||||||
|
// when user clicks a premium, ensure it is compatible with the pledge box amount
|
||||||
|
amount = canonicalize($j(this));
|
||||||
|
current = inputbox.val();
|
||||||
|
if (current<amount) {
|
||||||
|
mayday();
|
||||||
|
} else if (submitbutton.attr('disabled')) {
|
||||||
|
allclear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
inputbox.keyup(function() {
|
||||||
|
// when user changes the pledge box contents, ensure they are compatible
|
||||||
|
// with the selected pledge
|
||||||
|
current = $j(this).val();
|
||||||
|
amount = canonicalize($j('input[type=radio]:checked'));
|
||||||
|
current = inputbox.val();
|
||||||
|
if (current<amount) {
|
||||||
|
mayday();
|
||||||
|
} else if (submitbutton.attr('disabled')) {
|
||||||
|
allclear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue