diff --git a/chezbetty/templates/admin/email_endofsemester.jinja2 b/chezbetty/templates/admin/email_endofsemester.jinja2
index e4ab4c4..ddab150 100644
--- a/chezbetty/templates/admin/email_endofsemester.jinja2
+++ b/chezbetty/templates/admin/email_endofsemester.jinja2
@@ -6,8 +6,8 @@ by graduate students with limited resources. You currently owe Betty
{{ user.balance|format_currency|safe }}. We would greatly appreciate if you
could settle your debts with Betty.
-
To pay with a credit card, please visit
-your user page.
+
diff --git a/chezbetty/templates/admin/users_email.jinja2 b/chezbetty/templates/admin/users_email.jinja2
index 69c1881..63a7743 100644
--- a/chezbetty/templates/admin/users_email.jinja2
+++ b/chezbetty/templates/admin/users_email.jinja2
@@ -15,7 +15,7 @@
$ in debt to Chez Betty encouraging
them to settle up.
-{% set user = {'name': '<< name >>', 'balance': '<< balance >>'} %}
+{% set user = {'name': '<< name >>', 'balance': '<< balance >>', 'uniqname': '<< uniqname >> '} %}
{% include "email_deadbeats.jinja2" %}
@@ -29,7 +29,7 @@
$ in debt to Chez Betty encouraging
them to settle up.
-{% set user = {'name': '<< name >>', 'balance': '<< balance >>'} %}
+{% set user = {'name': '<< name >>', 'balance': '<< balance >>', 'uniqname': '<< uniqname >> '} %}
{% include "email_endofsemester.jinja2" %}
diff --git a/chezbetty/templates/base.jinja2 b/chezbetty/templates/base.jinja2
index b8c48e9..7c08834 100644
--- a/chezbetty/templates/base.jinja2
+++ b/chezbetty/templates/base.jinja2
@@ -104,9 +104,11 @@
{% endblock %}
{% set timeout = timeout|default(60*1000*5) -%}
+ {% if timeout %}
+ {% endif %}
+
+
+
+
+{{ _('For more options and transaction history, log in to your user account') }}
+
+{#
+
+#}
+
+
+{% else %} {# user.balance >= 0 #}
+
+
+ {{ _('You currently do not owe Chez Betty any money.') }}
+
+
+ {{ _('Thank you for paying your debts.') }}
+
+
+
+
+ {{ _('Log into your user account') }}
+
+
+ {{ _('Chez Betty Home') }}
+
+
+{% endif %}
+
+{% endblock %}
+
diff --git a/chezbetty/utility.py b/chezbetty/utility.py
index 6f9ec4e..6cf4f4c 100644
--- a/chezbetty/utility.py
+++ b/chezbetty/utility.py
@@ -1,7 +1,10 @@
import datetime
+from decimal import Decimal
import itertools
import qrcode
import qrcode.image.svg
+import stripe
+import traceback
from pyramid.renderers import render
from pyramid.threadlocal import get_current_registry
@@ -255,3 +258,67 @@ def timeseries_balance_total_daily(rows):
return out
+def post_stripe_payment(
+ datalayer, # Need to pass as argument to avoid circular import, ugh
+ request,
+ token,
+ amount,
+ total_cents,
+ account_making_payment,
+ account_depositing_into,
+ ):
+ # See http://stripe.com/docs/tutorials/charges
+ stripe.api_key = request.registry.settings['stripe.secret_key']
+
+ charge = (amount + 0.3) / 0.971
+ fee = charge - amount
+ if total_cents != int(round((amount + fee)*100)):
+ print("Stripe total mismatch. total_cents {} != {}".format(
+ total_cents, int(round((amount + fee)*100))))
+ request.session.flash('Unexpected error processing transaction. Card NOT charged.', 'error')
+ return False
+ amount = Decimal(amount)
+
+ if amount <= 0.0:
+ request.session.flash(
+ _('Deposit amount must be greater than $0.00. Card NOT charged.'),
+ 'error'
+ )
+ return False
+
+ try:
+ charge = stripe.Charge.create(
+ amount = total_cents,
+ currency="usd",
+ source=token,
+ description=account_making_payment.uniqname+'@umich.edu'
+ )
+
+ except stripe.CardError as e:
+ traceback.print_exc()
+ request.session.flash('Card error processing transaction. Card NOT charged.', 'error')
+ return False
+ except stripe.StripeError as e:
+ traceback.print_exc()
+ request.session.flash('Unexpected error processing transaction. Card NOT charged.', 'error')
+ request.session.flash('Please e-mail chezbetty@umich.edu so we can correct this error', 'error')
+ return False
+
+ try:
+ deposit = datalayer.cc_deposit(
+ account_making_payment,
+ account_depositing_into,
+ amount,
+ charge['id'],
+ charge['source']['last4'])
+
+ request.session.flash('Deposit added successfully.', 'success')
+
+ except Exception as e:
+ traceback.print_exc()
+ request.session.flash('A unknown error has occured.', 'error')
+ request.session.flash('Your card HAS been charged, but your account HAS NOT been credited.', 'error')
+ request.session.flash('Please e-mail chezbetty@umich.edu so we can correct this error', 'error')
+
+ return True
+
diff --git a/chezbetty/views.py b/chezbetty/views.py
index 31116b6..7bb9c80 100644
--- a/chezbetty/views.py
+++ b/chezbetty/views.py
@@ -28,6 +28,7 @@
from .utility import user_password_reset
from .utility import send_email
+from .utility import post_stripe_payment
from pyramid.security import Allow, Everyone, remember, forget
@@ -116,3 +117,40 @@ def users(request):
.filter(User.balance < -5)\
.order_by(User.balance).all()
return {'users': users}
+
+
+@view_config(route_name='paydebt', renderer='templates/paydebt.jinja2')
+def paydebt(request):
+ uniqname = request.matchdict['uniqname']
+ user = User.from_uniqname(uniqname, local_only=True)
+ return {
+ 'user': user,
+ 'stripe_pk': request.registry.settings['stripe.publishable_key'],
+ }
+
+@view_config(route_name='paydebt_submit',
+ request_method='POST',
+ renderer='json',
+ )
+def paydebt_submit(request):
+ uniqname = request.matchdict['uniqname']
+ user = User.from_uniqname(uniqname, local_only=True)
+
+ print(request.POST)
+
+ token = request.POST['stripeToken']
+ amount = float(request.POST['betty_amount'])
+ total_cents = int(request.POST['betty_total_cents'])
+
+ post_stripe_payment(
+ datalayer,
+ request,
+ token,
+ amount,
+ total_cents,
+ user,
+ user,
+ )
+
+ return {}
+
diff --git a/chezbetty/views_user.py b/chezbetty/views_user.py
index ac16afc..d6e683d 100644
--- a/chezbetty/views_user.py
+++ b/chezbetty/views_user.py
@@ -36,12 +36,13 @@
from .models.pool import Pool
from .models.pool_user import PoolUser
+from .utility import post_stripe_payment
+
from pyramid.security import Allow, Everyone, remember, forget
import chezbetty.datalayer as datalayer
from .btc import Bitcoin, BTCException
-import stripe
import uuid
import math
import pytz
@@ -132,9 +133,6 @@ def user_deposit_cc_custom(request):
request_method='POST',
permission='user')
def user_deposit_cc_submit(request):
- # See http://stripe.com/docs/tutorials/charges
- stripe.api_key = request.registry.settings['stripe.secret_key']
-
token = request.POST['stripeToken']
amount = float(request.POST['betty_amount'])
total_cents = int(request.POST['betty_total_cents'])
@@ -155,61 +153,15 @@ def user_deposit_cc_submit(request):
request.session.flash('Unexpected error processing transaction. Card NOT charged.', 'error')
return HTTPFound(location=request.route_url('user_index'))
- charge = (amount + 0.3) / 0.971
- fee = charge - amount
- if total_cents != int(round((amount + fee)*100)):
- request.session.flash('Unexpected error processing transaction. Card NOT charged.', 'error')
- return HTTPFound(location=request.route_url('user_index'))
- amount = Decimal(amount)
-
- if amount <= 0.0:
- request.session.flash(
- _('Deposit amount must be greater than $0.00. Card NOT charged.'),
- 'error'
- )
- return HTTPFound(location=request.route_url('user_index'))
-
- try:
- charge = stripe.Charge.create(
- amount = total_cents,
- currency="usd",
- source=token,
- description=request.user.uniqname+'@umich.edu'
- )
-
- except stripe.CardError as e:
- traceback.print_exc()
- request.session.flash('Card error processing transaction. Card NOT charged.', 'error')
- return HTTPFound(location=request.route_url('user_index'))
- except stripe.StripeError as e:
- traceback.print_exc()
- request.session.flash('Unexpected error processing transaction. Card NOT charged.', 'error')
- request.session.flash('Please e-mail chezbetty@umich.edu so we can correct this error', 'error')
- return HTTPFound(location=request.route_url('user_index'))
-
- try:
- if to_account == 'user':
- deposit = datalayer.cc_deposit(
- request.user,
- request.user,
- amount,
- charge['id'],
- charge['source']['last4'])
- else:
- deposit = datalayer.cc_deposit(
- request.user,
- pool,
- amount,
- charge['id'],
- charge['source']['last4'])
-
- request.session.flash('Deposit added successfully.', 'success')
-
- except Exception as e:
- traceback.print_exc()
- request.session.flash('A unknown error has occured.', 'error')
- request.session.flash('Your card HAS been charged, but your account HAS NOT been credited.', 'error')
- request.session.flash('Please e-mail chezbetty@umich.edu so we can correct this error', 'error')
+ post_stripe_payment(
+ datalayer,
+ request,
+ token,
+ amount,
+ total_cents,
+ request.user,
+ request.user if to_account == 'user' else pool,
+ )
return HTTPFound(location=request.route_url('user_index'))