commit
f152bc97b1
|
@ -1008,6 +1008,15 @@ class UserProfile(models.Model):
|
|||
def pledge_count(self):
|
||||
return self.user.transaction_set.exclude(status='NONE').exclude(status='Canceled',reason=None).exclude(anonymous=True).count()
|
||||
|
||||
@property
|
||||
def account(self):
|
||||
# there should be only one active account per user
|
||||
accounts = self.user.account_set.filter(date_deactivated__isnull=True)
|
||||
if accounts.count()==0:
|
||||
return None
|
||||
else:
|
||||
return accounts[0]
|
||||
|
||||
#class CampaignSurveyResponse(models.Model):
|
||||
# # generic
|
||||
# campaign = models.ForeignKey("Campaign", related_name="surveyresponse", null=False)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<div><h2>Wrong user for donation credit</h2>
|
||||
<div>
|
||||
<p>Unglue.it would like to process your donation credit, but you are currently logged in as <code>{{request.user.username}}</code>. Your donation credit from {{nonprofit.name}} for ${{ envelope.amount }}.{{ envelope.cents }} is designated for <code>{{ envelope.username }}</code>. Do record your credit, you need to <a href='{% url auth_logout %}?next={{ request.get_full_path|urlencode }}'>log out</a>, and then <a href='{% url auth_login %}?next={{ request.get_full_path|urlencode }}'>log in</a> as <code>{{ envelope.username }}</code>. If you have any problem, don't hesitate to contact <a href="mailto:support@gluejar.com?subject={{ request.get_full_path|urlencode }}">unglue.it support</a>.
|
||||
<p>Unglue.it would like to process your donation credit, but you are currently logged in as <code>{{request.user.username}}</code>. Your donation credit from {{nonprofit.name}} for ${{ envelope.amount }}.{{ envelope.cents }} is designated for <code>{{ envelope.username }}</code>. To record your credit, you need to <a href='{% url auth_logout %}?next={{ request.get_full_path|urlencode }}'>log out</a>, and then <a href='{% url auth_login %}?next={{ request.get_full_path|urlencode }}'>log in</a> as <code>{{ envelope.username }}</code>. If you have any problem, don't hesitate to contact <a href="mailto:support@gluejar.com?subject={{ request.get_full_path|urlencode }}">unglue.it support</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -193,7 +193,20 @@ $j().ready(function() {
|
|||
{% endif %}
|
||||
<div id="authorize" {% if nonprofit.is_on %}class="off clearfix"{% else %}class="clearfix"{% endif %}>
|
||||
<h3>Pledge by Credit Card</h3>
|
||||
<p>Unglue.it uses Stripe to securely manage your Credit Card information.
|
||||
{% if request.user.profile.account %}
|
||||
<p>Unglue.it has a {{ request.user.profile.account.card_type }} credit card on file for you (we use <a href="https://stripe.com/">Stripe</a> to keep your information secure).
|
||||
The last four digits of the card are {{ request.user.profile.account.card_last4 }}.
|
||||
</p>
|
||||
<form action="#" method="POST" id="use-account-form">
|
||||
<div class="innards">
|
||||
{% csrf_token %}
|
||||
{{ form.non_field_errors }}
|
||||
{{ form.as_p }}
|
||||
<input id="use_account_submit" name="use_account" type="submit" class="submit-button" value="Complete Pledge" />
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<p>Unglue.it uses <a href="https://stripe.com/">Stripe</a> to securely manage your credit card information.
|
||||
</p>
|
||||
<div id="cc_pledge">
|
||||
<form action="" method="POST" id="payment-form">
|
||||
|
@ -252,6 +265,7 @@ $j().ready(function() {
|
|||
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
{% extends "basepledge.html" %}
|
||||
{% load humanize %}
|
||||
|
||||
{% block title %}Credit card processing Error{% endblock %}
|
||||
|
||||
{% block extra_extra_head %}
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/campaign.css" />
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/pledge.css" />
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block doccontent %}
|
||||
<div style="height:15px"></div>
|
||||
|
||||
<div class="jsmodule rounded clearfix">
|
||||
<div class="jsmod-content">
|
||||
|
||||
<div><h2>Error: Card authorization for a pledge transaction</h2>
|
||||
<div>
|
||||
<p>Unglue.it would like to process your pledge, but there's some problem with our credit card processeng. We'd appreciate it if you'd contact <a href="mailto:support@gluejar.com?subject={{ request.get_full_path|urlencode }}">unglue.it support</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{% extends "basepledge.html" %}
|
||||
{% load humanize %}
|
||||
|
||||
{% block title %}Please Log in as...{% endblock %}
|
||||
|
||||
{% block extra_extra_head %}
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/campaign.css" />
|
||||
<link type="text/css" rel="stylesheet" href="/static/css/pledge.css" />
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block doccontent %}
|
||||
<div style="height:15px"></div>
|
||||
|
||||
<div class="jsmodule rounded clearfix">
|
||||
<div class="jsmod-content">
|
||||
|
||||
<div><h2>Error: Wrong user for a pledge transaction</h2>
|
||||
<div>
|
||||
<p>Unglue.it would like to process your pledge, but you are currently logged in as <code>{{request.user.username}}</code>. To complete your pledge, you need to <a href='{% url auth_logout %}?next={{ request.get_full_path|urlencode }}'>log out</a>, and then <a href='{% url auth_login %}?next={{ request.get_full_path|urlencode }}'>log in</a> as <code>{{ transaction.user.username }}</code>. If you have any problem, don't hesitate to contact <a href="mailto:support@gluejar.com?subject={{ request.get_full_path|urlencode }}">unglue.it support</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
|
@ -734,7 +734,7 @@ class FundPledgeView(FormView):
|
|||
assert self.request.user.is_authenticated()
|
||||
if self.transaction is None:
|
||||
self.transaction = get_object_or_404(Transaction, id=self.kwargs["t_id"])
|
||||
|
||||
|
||||
if kwargs.has_key('data'):
|
||||
data = kwargs['data'].copy()
|
||||
else:
|
||||
|
@ -771,52 +771,37 @@ class FundPledgeView(FormView):
|
|||
|
||||
def form_valid(self, form):
|
||||
""" note desire to pledge; make sure there is a credit card to charge"""
|
||||
|
||||
# first pass -- we have a token -- also do more direct coupling to stripelib -- then move to
|
||||
# abstraction of payment.manager / payment.baseprocessor
|
||||
|
||||
# we should getting a stripe_token only if we had asked for CC data
|
||||
|
||||
# BUGBUG -- don't know whether transaction.host should be None -- but if it is, set to the
|
||||
# default processor
|
||||
|
||||
transaction = self.transaction
|
||||
if transaction.host is None or transaction.host == PAYMENT_HOST_NONE:
|
||||
transaction.host = settings.PAYMENT_PROCESSOR
|
||||
|
||||
stripe_token = form.cleaned_data["stripe_token"]
|
||||
preapproval_amount = form.cleaned_data["preapproval_amount"]
|
||||
|
||||
logger.info('stripe_token:{0}, preapproval_amount:{1}'.format(stripe_token, preapproval_amount))
|
||||
|
||||
if self.transaction.user.id != self.request.user.id:
|
||||
# trouble!
|
||||
return render(request, "pledge_user_error.html", {'transaction': self.transaction })
|
||||
|
||||
p = PaymentManager()
|
||||
|
||||
# if we get a stripe_token, create a new stripe account
|
||||
|
||||
try:
|
||||
(accounts, created) = p.retrieve_or_make_accounts(user=transaction.user, host=transaction.host, token=stripe_token)
|
||||
assert len(accounts) == 1 # only one active account/user at the moment
|
||||
account = accounts[0]
|
||||
logger.info('account.id: {0}'.format(account.id))
|
||||
except baseprocessor.ProcessorError as e:
|
||||
return HttpResponse("baseprocessor.ProcessorError: {0}".format(e))
|
||||
|
||||
# GOAL: deactivate any older accounts associated with user
|
||||
|
||||
# if the user has active account, use it. Otherwise...
|
||||
if not self.request.user.profile.account:
|
||||
stripe_token = form.cleaned_data["stripe_token"]
|
||||
# if we get a stripe_token, create a new stripe account for the user
|
||||
if stripe_token:
|
||||
try:
|
||||
p.make_account(user=self.request.user, host=settings.PAYMENT_PROCESSOR, token=stripe_token)
|
||||
except baseprocessor.ProcessorError as e:
|
||||
return HttpResponse("There was an error processing your credit card")
|
||||
|
||||
self.transaction.host = settings.PAYMENT_PROCESSOR
|
||||
|
||||
preapproval_amount = form.cleaned_data["preapproval_amount"]
|
||||
|
||||
# with the Account in hand, now authorize transaction
|
||||
transaction.amount = preapproval_amount
|
||||
t, url = p.authorize(transaction)
|
||||
self.transaction.max_amount = preapproval_amount
|
||||
t, url = p.authorize(self.transaction)
|
||||
logger.info("t, url: {0} {1}".format(t, url))
|
||||
|
||||
# redirecting user to pledge_complete on successful preapproval (in the case of stripe)
|
||||
# BUGBUG: Make sure we are testing properly for successful authorization properly here
|
||||
if url is not None:
|
||||
return HttpResponseRedirect(url)
|
||||
elif settings.DEBUG:
|
||||
return HttpResponse("preapproval_key: {0}".format(transaction.preapproval_key))
|
||||
else:
|
||||
raise Http404
|
||||
|
||||
return render(request, "pledge_card_error.html", {'transaction': self.transaction })
|
||||
|
||||
class NonprofitCampaign(FormView):
|
||||
template_name="nonprofit.html"
|
||||
|
|
|
@ -567,7 +567,7 @@ class PaymentManager( object ):
|
|||
urllib.urlencode({'tid':transaction.id}))
|
||||
return_url = urlparse.urljoin(settings.BASE_URL, return_path)
|
||||
|
||||
p = transaction.get_payment_class().Preapproval(transaction, transaction.amount, expiry, return_url=return_url, paymentReason=paymentReason)
|
||||
p = transaction.get_payment_class().Preapproval(transaction, transaction.max_amount, expiry, return_url=return_url, paymentReason=paymentReason)
|
||||
|
||||
# Create a response for this
|
||||
envelope = p.envelope()
|
||||
|
@ -960,16 +960,6 @@ class PaymentManager( object ):
|
|||
else:
|
||||
return Account.objects.filter(user=user, host=host, date_deactivated__isnull=True)
|
||||
|
||||
def retrieve_or_make_accounts(self, user, host, token=None, include_deactivated=False):
|
||||
accounts = self.retrieve_accounts(user=user, host=host, include_deactivated=include_deactivated)
|
||||
num_acct=len(accounts)
|
||||
if num_acct == 1:
|
||||
return (accounts, False)
|
||||
elif num_acct > 1:
|
||||
return ((accounts[num_acct-1],), False)
|
||||
else:
|
||||
account = self.make_account(user=user, host=host, token=token)
|
||||
return ((account,), True)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -448,35 +448,31 @@ class Processor(baseprocessor.Processor):
|
|||
def make_account(self, user, token=None):
|
||||
"""returns a payment.models.Account based on stripe token and user"""
|
||||
|
||||
if token == None:
|
||||
# shouldn't happen
|
||||
return None
|
||||
|
||||
sc = StripeClient()
|
||||
|
||||
# allow for the possibility that if token is None, just create a placeholder Account
|
||||
|
||||
if token is not None:
|
||||
|
||||
# create customer and charge id and then charge the customer
|
||||
try:
|
||||
customer = sc.create_customer(card=token, description=user.username,
|
||||
email=user.email)
|
||||
except stripe.StripeError as e:
|
||||
raise StripelibError(e.message, e)
|
||||
|
||||
account = Account(host = PAYMENT_HOST_STRIPE,
|
||||
account_id = customer.id,
|
||||
card_last4 = customer.active_card.last4,
|
||||
card_type = customer.active_card.type,
|
||||
card_exp_month = customer.active_card.exp_month,
|
||||
card_exp_year = customer.active_card.exp_year,
|
||||
card_fingerprint = customer.active_card.fingerprint,
|
||||
card_country = customer.active_card.country,
|
||||
user = user
|
||||
)
|
||||
|
||||
account.save()
|
||||
|
||||
else:
|
||||
account = Account(host = PAYMENT_HOST_STRIPE, user= user)
|
||||
account.save()
|
||||
# create customer and charge id and then charge the customer
|
||||
try:
|
||||
customer = sc.create_customer(card=token, description=user.username,
|
||||
email=user.email)
|
||||
except stripe.StripeError as e:
|
||||
raise StripelibError(e.message, e)
|
||||
|
||||
account = Account(host = PAYMENT_HOST_STRIPE,
|
||||
account_id = customer.id,
|
||||
card_last4 = customer.active_card.last4,
|
||||
card_type = customer.active_card.type,
|
||||
card_exp_month = customer.active_card.exp_month,
|
||||
card_exp_year = customer.active_card.exp_year,
|
||||
card_fingerprint = customer.active_card.fingerprint,
|
||||
card_country = customer.active_card.country,
|
||||
user = user
|
||||
)
|
||||
|
||||
account.save()
|
||||
|
||||
return account
|
||||
|
||||
|
@ -507,13 +503,11 @@ class Processor(baseprocessor.Processor):
|
|||
|
||||
# ASSUMPTION: a user has any given moment one and only one active payment Account
|
||||
|
||||
if transaction.user.account_set.filter(date_deactivated__isnull=True).count() > 1:
|
||||
logger.warning("user {0} has more than one active payment account".format(transaction.user))
|
||||
elif transaction.user.account_set.filter(date_deactivated__isnull=True).count() == 0:
|
||||
account = transaction.user.profile.account
|
||||
if not account:
|
||||
logger.warning("user {0} has no active payment account".format(transaction.user))
|
||||
raise StripelibError("user {0} has no active payment account".format(transaction.user))
|
||||
|
||||
account = transaction.user.account_set.filter(date_deactivated__isnull=True)[0]
|
||||
logger.info("user: {0} customer.id is {1}".format(transaction.user, account.account_id))
|
||||
|
||||
# settings to apply to transaction for TRANSACTION_STATUS_ACTIVE
|
||||
|
|
Loading…
Reference in New Issue