From 6b1a1b17025a193cc17fbf079889402ae4ff0b81 Mon Sep 17 00:00:00 2001
From: Sander Roosendaal Donations are welcome to keep this web site going. To help cover the hosting
+ costs, I have created several paid plans offering advanced functionality.
+ Once I process your
+ donation, I will give you access to some The following table gives an overview of the different plans. As we are
+ constantly developing new functionality, the table might be slightly outdated. Don't
+ hesitate to contact us. The Pro membership is open for a free 14 day trial
+ Payments
+
+
+
special
features on this
+ website.
+
+
+
+
+
+
+
+ BASIC
+ PRO
+ SELF-COACH
+ COACH
+
+
+ Basic rowing metrics (spm, time, distance, heart rate, power)
+ ✔
+ ✔
+ ✔
+ ✔
+
+
+ Manual Import, Export, Synchronization and download of all your data
+ ✔
+ ✔
+ ✔
+ ✔
+
+
+ Automatic Synchronization with other fitness sites
+
+ ✔
+ ✔
+ ✔
+
+
+ Heart rate and power zones
+ ✔
+ ✔
+ ✔
+ ✔
+
+
+ Ranking Pieces, Stroke Analysis
+ ✔
+ ✔
+ ✔
+ ✔
+
+
+ Advanced Analysis (Critical Power, Stats, Box Chart, Trend Flex)
+
+ ✔
+ ✔
+ ✔
+
+
+ Compare Workouts
+
+ ✔
+ ✔
+ ✔
+
+
+ Empower Stroke Profile
+
+ ✔
+ ✔
+ ✔
+
+
+ Sensor Fusion, Split Workout, In-stroke metrics
+
+ ✔
+ ✔
+ ✔
+
+
+ Create Training plans, tests and challenges for yourself. Track your performance
+ against plan.
+
+
+ ✔
+ ✔
+
+
+ Create Training plans, tests and challenges for your athletes. Track their performance
+ against plan.
+
+
+
+ ✔
+
+
+ Create and manage teams.
+
+
+
+ ✔
+
+
+
+ Manage your athlete's workouts
+
+
+
+ ✔
+
The Coach plan functionality listed is available to the coach only. Individual athletes + can purchase upgrades to "Pro" and "Self-Coach" plans. +
+ +Rowsandall.com's Training Planning functionality + is part of the paid "Self-Coach" and "Coach" plans.
+ +On the "Self-Coach" plan, you can plan your own sessions.
+ +On the "Coach" plan, you can establish teams, see workouts done by + athletes on your team, and plan individual and group sessions for your + athletes. +
+ +If you would like to find a coach who helps you plan your training + through rowsandall.com, contact me throught the contact form.
+ + {% if user.rower.rowerplan == 'basic' and user.rower.protrialexpires|date_dif == 1 %} ++ You qualify for a 14 day free trial. No credit card needed. + Try out Pro or Self-Coach membership for two weeks. Click the button below to + sign up for the trial. After your trial period expires, you will be + automatically reset to the Basic plan, unless you upgrade to Pro. +
+Yes, I want to try Pro membership for 14 days for free. No strings attached.
+Yes, I want to try Self-Coach membership for 14 days for free. No strings attached.
+ {% endif %} + +Click on the PayPal button to pay for your Pro membership. Before you pay, please register for the free Basic membership and add your user name to the form. + Your payment will be valid for one year. + You will be taken to the secure PayPal payment site. +
+You need a Paypal account for this. This is plan will automatically renew each year.
++
+ +Only a credit card needed. Will not automatically renew
+ ++
+ +After you do the payment, we will manually change your membership to + "Pro". Depending on our availability, this may take some time + (typically one working day). Don't hesitate to contact us + 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.
+ +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 = ''