From 6b1a1b17025a193cc17fbf079889402ae4ff0b81 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 14 Dec 2018 16:53:34 +0100 Subject: [PATCH 01/16] test payments working (sort of) --- rowers/forms.py | 6 +- rowers/templates/payments.html | 295 ++++++++++++++++++++++++++++ rowers/templates/promembership.html | 1 + rowers/urls.py | 2 + rowers/views.py | 85 +++++++- rowsandall_app/settings.py | 17 ++ 6 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 rowers/templates/payments.html diff --git a/rowers/forms.py b/rowers/forms.py index 05fc77a8..0994a61e 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -18,7 +18,11 @@ from django.forms import formset_factory from utils import landingpages from metrics import axes - +# Braintree form +class BrainTreeForm(forms.Form): + amount = forms.FloatField(required=True) + payment_method_nonce = forms.CharField(max_length=255) + # login form class LoginForm(forms.Form): diff --git a/rowers/templates/payments.html b/rowers/templates/payments.html new file mode 100644 index 00000000..4cc0b8f1 --- /dev/null +++ b/rowers/templates/payments.html @@ -0,0 +1,295 @@ + +{% extends "newbase.html" %} +{% block title %}Rowsandall Pro Membership{% endblock title %} +{% block main %} +{% load rowerfilters %} + +

Payments

+ + + + +{% endblock %} + +{% block sidebar %} +{% include 'menu_help.html' %} +{% endblock %} + +{% block scripts %} +{% endblock %} + diff --git a/rowers/templates/promembership.html b/rowers/templates/promembership.html index 201d3044..391d9f51 100644 --- a/rowers/templates/promembership.html +++ b/rowers/templates/promembership.html @@ -232,6 +232,7 @@ if you have any questions at this stage.

If, for any reason, you are not happy with your Pro membership, please let me know through the contact form. I will contact you as soon as possible to discuss how we can make things better.

+ diff --git a/rowers/urls.py b/rowers/urls.py index 242c07b4..ee3aa1ce 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -437,6 +437,8 @@ urlpatterns = [ url(r'^analysis/$', views.analysis_view,name='analysis'), url(r'^laboratory/$', views.laboratory_view,name='laboratory'), url(r'^promembership', TemplateView.as_view(template_name='promembership.html'),name='promembership'), + url(r'^checkouts',views.checkouts_view,name='checkouts'), + url(r'^payments',views.payments_view,name='payments'), url(r'^planrequired',views.planrequired_view), url(r'^starttrial$',views.start_trial_view), url(r'^startplantrial$',views.start_plantrial_view), diff --git a/rowers/views.py b/rowers/views.py index 8a32085c..de29e3f2 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -28,6 +28,7 @@ import isodate import re import cgi from icalendar import Calendar, Event +import braintree from django.shortcuts import render from django.template.loader import render_to_string @@ -50,7 +51,7 @@ from rowers.forms import ( RaceResultFilterForm,PowerIntervalUpdateForm,FlexAxesForm, FlexOptionsForm,DataFrameColumnsForm,OteWorkoutTypeForm, MetricsForm,DisqualificationForm,disqualificationreasons, - disqualifiers,SearchForm, + disqualifiers,SearchForm,BrainTreeForm ) from django.core.urlresolvers import reverse, reverse_lazy @@ -139,6 +140,7 @@ from rowsandall_app.settings import ( UNDERARMOUR_CLIENT_SECRET,UNDERARMOUR_CLIENT_KEY, RUNKEEPER_CLIENT_ID,RUNKEEPER_REDIRECT_URI,RUNKEEPER_CLIENT_SECRET, TP_CLIENT_ID,TP_REDIRECT_URI,TP_CLIENT_KEY,TP_CLIENT_SECRET, + BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY ) from rowers.tasks_standalone import addcomment2 @@ -1027,6 +1029,87 @@ def add_defaultfavorites(r): f.save() return 1 +# Experimental - Payments +@login_required() +def payments_view(request): + + r = getrequestrower(request) + + gateway = braintree.BraintreeGateway( + braintree.Configuration( + braintree.Environment.Sandbox, + merchant_id=BRAINTREE_MERCHANT_ID, + public_key=BRAINTREE_PUBLIC_KEY, + private_key=BRAINTREE_PRIVATE_KEY, + ) + ) + + # add code to store customer_id + + client_token = gateway.client_token.generate({ + "customer_id": r.id, + }) + + return render(request, + "payments.html", + { + 'client_token':client_token, + }) + + +@login_required() +def checkouts_view(request): + + r = getrequestrower(request) + + if request.method != 'POST': + url = reverse(payments_view) + return HttpResponseRedirect(url) + + # we're still here + gateway = braintree.BraintreeGateway( + braintree.Configuration( + braintree.Environment.Sandbox, + merchant_id=BRAINTREE_MERCHANT_ID, + public_key=BRAINTREE_PUBLIC_KEY, + private_key=BRAINTREE_PRIVATE_KEY, + ) + ) + + form = BrainTreeForm(request.POST) + if form.is_valid(): + nonce_from_the_client = form.cleaned_data['payment_method_nonce'] + amount = form.cleaned_data['amount'] + amount = str(amount) + + result = gateway.transaction.sale({ + "amount": amount, + "payment_method_nonce": nonce_from_the_client, + "options": { + "submit_for_settlement": True + } + }) + if result.is_success: + transaction = result.transaction + amount = transaction.amount + messages.info(request, + "We have successfully received your payment of {amount} Euro".format( + amount=amount + ) + ) + else: + messages.error(request,"We are sorry but there was an error with the payment") + url = reverse(payments_view) + return HttpResponseRedirect(url) + + else: + messages.error(request,"There was an error in the payment form") + url = reverse(payments_view) + return HttpResponseRedirect(url) + + url = reverse(payments_view) + return HttpResponseRedirect(url) + # User registration def rower_register_view(request): diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py index 93bfb4a4..61484bbf 100644 --- a/rowsandall_app/settings.py +++ b/rowsandall_app/settings.py @@ -421,3 +421,20 @@ try: except KeyError: workoutemailbox = 'workouts@rowsandall.com' + +# payments + +try: + BRAINTREE_MERCHANT_ID = CFG['braintree_merchant_id'] +except KeyError: + BRAINTREE_MERCHANT_ID = '' + +try: + BRAINTREE_PUBLIC_KEY = CFG['braintree_public_key'] +except KeyError: + BRAINTREE_PUBLIC_KEY = '' + +try: + BRAINTREE_PRIVATE_KEY = CFG['braintree_private_key'] +except KeyError: + BRAINTREE_PRIVATE_KEY = '' From c48175bb4a5fd52678517748f6ed915af8baa137 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 17 Dec 2018 19:36:44 +0100 Subject: [PATCH 02/16] added customer id --- rowers/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rowers/models.py b/rowers/models.py index e48f252a..3d3ee446 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -574,6 +574,9 @@ class Rower(models.Model): gdproptin = models.BooleanField(default=False) gdproptindate = models.DateTimeField(blank=True,null=True) + # customer data + customer_id = models.IntegerField(default=None,null=True,blank=True) + # Heart Rate Zone data max = models.IntegerField(default=192,verbose_name="Max Heart Rate") rest = models.IntegerField(default=48,verbose_name="Resting Heart Rate") From 63a6114e0b1b35cd3f804d7c09eb848dfe0ec241 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 17 Dec 2018 22:39:11 +0100 Subject: [PATCH 03/16] trying to get country info --- rowers/templates/payments.html | 3 ++- rowers/views.py | 35 +++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/rowers/templates/payments.html b/rowers/templates/payments.html index 4cc0b8f1..9c248bcb 100644 --- a/rowers/templates/payments.html +++ b/rowers/templates/payments.html @@ -235,7 +235,8 @@

BrainTree Experimental Corner

-
+