buy now flow complete except email confirmation
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import braintree
|
||||
from django.utils import timezone
|
||||
import datetime
|
||||
|
||||
from rowsandall_app.settings import (
|
||||
BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY
|
||||
@@ -16,8 +18,8 @@ gateway = braintree.BraintreeGateway(
|
||||
from rowers.models import Rower,PaidPlan
|
||||
from rowers.utils import ProcessorCustomerError
|
||||
|
||||
def create_customer(rower):
|
||||
if not rower.customer_id:
|
||||
def create_customer(rower,force=False):
|
||||
if not rower.customer_id or force:
|
||||
result = gateway.customer.create(
|
||||
{
|
||||
'first_name':rower.user.first_name,
|
||||
@@ -28,14 +30,25 @@ def create_customer(rower):
|
||||
raise ProcessorCustomerError
|
||||
else:
|
||||
rower.customer_id = result.customer.id
|
||||
rower.paymentprocessor = 'braintree'
|
||||
rower.save()
|
||||
return rower.customer_id
|
||||
else:
|
||||
return rower.customer_id
|
||||
|
||||
|
||||
|
||||
def get_client_token(rower):
|
||||
try:
|
||||
client_token = gateway.client_token.generate({
|
||||
"customer_id":rower.customer_id,
|
||||
})
|
||||
except ValueError:
|
||||
customer_id = create_customer(rower,force=True)
|
||||
|
||||
client_token = gateway.client_token.generate({
|
||||
"customer_id": customer_id,
|
||||
})
|
||||
|
||||
return client_token
|
||||
|
||||
@@ -51,3 +64,125 @@ def get_plans_costs():
|
||||
plan.save()
|
||||
|
||||
return plans
|
||||
|
||||
def make_payment(rower,data):
|
||||
nonce_from_the_client = data['payment_method_nonce']
|
||||
amount = 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
|
||||
|
||||
return amount
|
||||
else:
|
||||
return 0,''
|
||||
|
||||
def create_subscription(rower,data):
|
||||
planid = data['plan']
|
||||
plan = PaidPlan.objects.get(id=planid)
|
||||
nonce_from_the_client = data['payment_method_nonce']
|
||||
amount = data['amount']
|
||||
|
||||
# create or find payment method
|
||||
result = gateway.payment_method.create({
|
||||
"customer_id": rower.customer_id,
|
||||
"payment_method_nonce": nonce_from_the_client
|
||||
})
|
||||
|
||||
if result.is_success:
|
||||
payment_method_token = result.payment_method.token
|
||||
else:
|
||||
return False
|
||||
|
||||
result = gateway.subscription.create({
|
||||
"payment_method_token": payment_method_token,
|
||||
"plan_id": plan.external_id
|
||||
})
|
||||
|
||||
if result.is_success:
|
||||
rower.paidplan = plan
|
||||
rower.planexpires = timezone.now()+datetime.timedelta(days=365)
|
||||
rower.teamplanexpires = timezone.now()+datetime.timedelta(days=365)
|
||||
rower.clubsize = plan.clubsize
|
||||
rower.paymenttype = plan.paymenttype
|
||||
rower.rowerplan = plan.shortname
|
||||
rower.save()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
return False
|
||||
|
||||
def cancel_subscription(rower,id):
|
||||
themessages = []
|
||||
errormessages = []
|
||||
try:
|
||||
result = gateway.subscription.cancel(id)
|
||||
messages.append("Subscription canceled")
|
||||
except:
|
||||
errormessages.append("We could not find the subscription record in our customer database")
|
||||
return False, themessages, errormessages
|
||||
|
||||
rower.paidplan = None
|
||||
rower.teamplanexpires = timezone.now()
|
||||
rower.planexpires = timezone.now()
|
||||
rower.clubsize = 0
|
||||
rower.rowerplan = 'basic'
|
||||
rower.save()
|
||||
themessages.append("Your plan was reset to basic")
|
||||
|
||||
return True, themessages,errormessages
|
||||
|
||||
|
||||
def find_subscriptions(rower):
|
||||
try:
|
||||
result = gateway.customer.find(rower.customer_id)
|
||||
except:
|
||||
raise ProcessorCustomerError("We could not find the customer in the database")
|
||||
|
||||
active_subscriptions = []
|
||||
|
||||
cards = result.credit_cards
|
||||
for card in cards:
|
||||
for subscription in card.subscriptions:
|
||||
if subscription.status == 'Active':
|
||||
active_subscriptions.append(subscription)
|
||||
|
||||
try:
|
||||
paypal_accounts = result.paypal_accounts
|
||||
for account in accuonts:
|
||||
for subscription in account.subscriptions:
|
||||
if subscription.status == 'Active':
|
||||
active_subscriptions.append(subscription)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
result = []
|
||||
|
||||
for subscription in active_subscriptions:
|
||||
|
||||
plan = PaidPlan.objects.filter(paymentprocessor="braintree",
|
||||
external_id=subscription.plan_id)[0]
|
||||
|
||||
thedict = {
|
||||
'end_date': subscription.billing_period_end_date,
|
||||
'plan_id': subscription.plan_id,
|
||||
'price': subscription.price,
|
||||
'id': subscription.id,
|
||||
'plan': plan.name
|
||||
}
|
||||
|
||||
result.append(thedict)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ from metrics import axes
|
||||
# BillingForm form
|
||||
class BillingForm(forms.Form):
|
||||
amount = forms.FloatField(required=True)
|
||||
payment_method_nonce = forms.CharField(max_length=255)
|
||||
plan = forms.IntegerField(widget=forms.HiddenInput())
|
||||
payment_method_nonce = forms.CharField(max_length=255,required=True)
|
||||
|
||||
|
||||
# login form
|
||||
|
||||
@@ -558,7 +558,7 @@ paymentprocessors = (
|
||||
class PaidPlan(models.Model):
|
||||
shortname = models.CharField(max_length=50,choices=plans)
|
||||
name = models.CharField(max_length=200)
|
||||
external_id = models.IntegerField(blank=True,null=True,default=None)
|
||||
external_id = models.CharField(blank=True,null=True,default=None,max_length=200)
|
||||
price = models.FloatField(blank=True,null=True,default=None)
|
||||
paymentprocessor = models.CharField(
|
||||
max_length=50,choices=paymentprocessors,default='braintree')
|
||||
@@ -633,7 +633,8 @@ class Rower(models.Model):
|
||||
)
|
||||
paymentprocessor = models.CharField(max_length=50,
|
||||
choices=paymentprocessors,
|
||||
default='braintree')
|
||||
null=True,blank=True,
|
||||
default=None)
|
||||
|
||||
paidplan = models.ForeignKey(PaidPlan,null=True,default=None)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ def setrowerplans():
|
||||
print 'Could not set plan for ',r
|
||||
|
||||
def is_existing_customer(rower):
|
||||
if rower.country is not None and rower.customer_id is not None and r.country != '':
|
||||
if rower.country is not None and rower.customer_id is not None and rower.country != '':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@@ -31,6 +31,6 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% include 'menu_help.html' %}
|
||||
{% include 'menu_profile.html' %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
26
rowers/templates/payment_completed.html
Normal file
26
rowers/templates/payment_completed.html
Normal file
@@ -0,0 +1,26 @@
|
||||
{% extends "newbase.html" %}
|
||||
{% block title %}Rowsandall Paid Membership{% endblock title %}
|
||||
{% load rowerfilters %}
|
||||
{% block main %}
|
||||
|
||||
<h1>Your Payment was completed</h1>
|
||||
|
||||
<p>
|
||||
Thank you for registering to {{ user.rower.paidplan.name }}. You have paid for 12 months
|
||||
membership.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{% if user.rower.paymenttype == 'recurring' %}
|
||||
Your next payment will be automatically processed on {{ user.rower.planexpires }}
|
||||
{% else %}
|
||||
Your plan will end automatically on {{ user.rower.planexpires }}
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% include 'menu_profile.html' %}
|
||||
{% endblock %}
|
||||
|
||||
113
rowers/templates/paymentconfirm.html
Normal file
113
rowers/templates/paymentconfirm.html
Normal file
@@ -0,0 +1,113 @@
|
||||
{% extends "newbase.html" %}
|
||||
{% block title %}Rowsandall Paid Membership{% endblock title %}
|
||||
{% load rowerfilters %}
|
||||
{% block main %}
|
||||
|
||||
<h1>Confirm Your Payment</h1>
|
||||
|
||||
<h2>Order Overview</h2>
|
||||
|
||||
<ul class="main-content">
|
||||
<li class="grid_2">
|
||||
<p>
|
||||
<table class="plantable shortpadded" width="80%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Plan</th><td>{{ plan.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Payment Type</th><td>{{ plan.paymenttype }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Plan Duration</th><td>1 year starting today</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Total</th><td>€ {{ plan.price|currency }}
|
||||
{% if plan.paymenttype == 'recurring' %}
|
||||
/year
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
<p>
|
||||
<table class="plantable shortpadded" width="80%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Street Address</th><td>{{ user.rower.street_address }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>City</th><td>{{ user.rower.city }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Posstal Code</th><td>{{ user.rower.postal_code }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Country</th><td>{{ user.rower.country }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
</li>
|
||||
<li class="grid_2">
|
||||
<p>
|
||||
<a href="/rowers/billing">Change Order</a>
|
||||
</li>
|
||||
<li class="grid_4">
|
||||
<form id="payment-form" method="post" action="/rowers/checkouts"
|
||||
autocomplete="off">
|
||||
<section>
|
||||
<label for="amount">
|
||||
<div class="input-wrapper amount-wrapper">
|
||||
<input id="amount" name="amount" type="hidden" min="1" placeholder="Amount"
|
||||
value="{{ plan.price }}" readonly>
|
||||
</div>
|
||||
</label>
|
||||
<div class="bt-drop-in-wrapper">
|
||||
<div id="bt-dropin"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<input type="hidden" id="nonce" name="payment_method_nonce" />
|
||||
<input type="hidden" id="plan" name="plan" value="{{ plan.id }}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" id="submit-button"><span>Pay € {{ plan.price|currency }}</span></button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<script src="https://js.braintreegateway.com/web/dropin/1.14.1/js/dropin.min.js"></script>
|
||||
<script>
|
||||
var form = document.querySelector('#payment-form');
|
||||
var client_token = '{{ client_token }}';
|
||||
braintree.dropin.create({
|
||||
authorization: client_token,
|
||||
container: '#bt-dropin',
|
||||
paypal: {
|
||||
flow: 'checkout'
|
||||
}
|
||||
}, function (createErr, instance) {
|
||||
form.addEventListener('submit', function (event) {
|
||||
event.preventDefault();
|
||||
instance.requestPaymentMethod(function (err, payload) {
|
||||
if (err) {
|
||||
console.log('Error', err);
|
||||
return;
|
||||
}
|
||||
// Add the nonce to the form and submit
|
||||
document.querySelector('#nonce').value = payload.nonce;
|
||||
form.submit();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% include 'menu_profile.html' %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<h2>Account Information</h2>
|
||||
<p>
|
||||
{% if rower.user == user %}
|
||||
<a class="button blue small" href="/password_change/">Password Change</a>
|
||||
<a href="/password_change/">Password Change</a>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
@@ -34,29 +34,49 @@
|
||||
{{ userform.as_table }}
|
||||
{{ accountform.as_table }}
|
||||
<tr>
|
||||
<th>Plan</th><td>{{ rower.rowerplan }}</td>
|
||||
<th> </th><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Plan Expiry</th><td>{{ rower.planexpires }}</td>
|
||||
<th>Plan</th><td>{{ rower.paidplan.name }}</td>
|
||||
</tr>
|
||||
{% if rower.rowerplan != 'basic' %}
|
||||
<tr>
|
||||
<th>
|
||||
{% if rower.paymenttype != 'recurring' %}
|
||||
Plan Expiry
|
||||
{% else %}
|
||||
Next Payment Due
|
||||
{% endif %}
|
||||
</th><td>{{ rower.planexpires }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% csrf_token %}
|
||||
{% if rower.rowerplan == 'basic' and rower.user == user %}
|
||||
<a class="button blue" href="/rowers/promembership">Upgrade</a>
|
||||
{% if rower.rowerplan != 'coach' and rower.user == user %}
|
||||
<p>
|
||||
<a href="/rowers/paidplans">Upgrade</a>
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
|
||||
</p>
|
||||
{% endif %}
|
||||
<input class="button green" type="submit" value="Save">
|
||||
{% if rower.rowerplan != 'basic' and rower.user == user %}
|
||||
<p>
|
||||
<a href="/rowers/me/cancelsubscriptions">Cancel Subscription</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
<input type="submit" value="Save">
|
||||
</form>
|
||||
</li>
|
||||
{% if rower.user == user %}
|
||||
<li class="grid_2">
|
||||
<h2>GDPR - Data Protection</h2>
|
||||
<p>
|
||||
<a class="button blue small" href="/rowers/exportallworkouts">Download your data</a>
|
||||
<a href="/rowers/exportallworkouts">Download your data</a>
|
||||
</p>
|
||||
<p>
|
||||
<a class="button blue small" href="/rowers/me/deactivate">Deactivate Account</a>
|
||||
<a href="/rowers/me/deactivate">Deactivate Account</a>
|
||||
</p>
|
||||
<p>
|
||||
<a class="button red small" href="/rowers/me/delete">Delete Account</a>
|
||||
@@ -79,7 +99,7 @@
|
||||
<td>{{ grant.application }}</td>
|
||||
<td>{{ grant.scope }}</td>
|
||||
<td>
|
||||
<a class="button red small" href="/rowers/me/revokeapp/{{ grant.application.id }}">Revoke</a>
|
||||
<a href="/rowers/me/revokeapp/{{ grant.application.id }}">Revoke</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
64
rowers/templates/subscriptions_cancel.html
Normal file
64
rowers/templates/subscriptions_cancel.html
Normal file
@@ -0,0 +1,64 @@
|
||||
{% extends "newbase.html" %}
|
||||
{% block title %}Rowsandall Paid Membership{% endblock title %}
|
||||
{% load rowerfilters %}
|
||||
{% block main %}
|
||||
|
||||
<h1>Cancel Subscriptions</h1>
|
||||
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
{% if subscriptions %}
|
||||
<p>
|
||||
<table class="plantable shortpadded" width="80%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Subscription</th><th>Next Billing Date</th><th>Price</th><th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for subscription in subscriptions %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ subscription|lookup:"plan" }}
|
||||
</td>
|
||||
<td>
|
||||
{{ subscription|lookup:"end_date" }}
|
||||
</td>
|
||||
<td>
|
||||
{{ subscription|lookup:"price" }} €
|
||||
</td>
|
||||
<td>
|
||||
<a href="/rowers/me/cancelsubscription/{{ subscription|lookup:'id' }}">Stop this plan</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p>
|
||||
<p>
|
||||
By clicking on the link to stop the plan, you will downgrade to the Basic plan.
|
||||
Future payments will be stopped.
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
You don't have any subscriptions or your subscriptions cannot be automatically stopped
|
||||
from the site.
|
||||
</p>
|
||||
<p>
|
||||
If you have paid through PayPal, log in to your PayPal account and cancel the recurring payment
|
||||
there. We will manually downgrade your subscription.
|
||||
</p>
|
||||
<p>
|
||||
If you have questions, don't hesitate to contact us.
|
||||
</p>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% include 'menu_profile.html' %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -126,6 +126,15 @@ def c2userid(user):
|
||||
|
||||
return c2userid
|
||||
|
||||
@register.filter
|
||||
def currency(word):
|
||||
try:
|
||||
amount = float(word)
|
||||
except ValueError:
|
||||
return word
|
||||
|
||||
return '{amount:.2f}'.format(amount=amount)
|
||||
|
||||
@register.filter
|
||||
def rkuserid(user):
|
||||
try:
|
||||
|
||||
@@ -438,10 +438,13 @@ 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'^checkout/(?P<planid>\d+)$',views.payment_confirm_view),
|
||||
url(r'^billing',views.billing_view,name='billing'),
|
||||
url(r'^paymentcompleted',views.payment_completed_view),
|
||||
url(r'^paidplans',views.paidplans_view,name='paidplans'),
|
||||
url(r'^me/cancelsubscriptions',views.plan_stop_view),
|
||||
url(r'^me/cancelsubscription/(?P<id>[\w\ ]+.*)$',views.plan_tobasic_view),
|
||||
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),
|
||||
|
||||
201
rowers/views.py
201
rowers/views.py
@@ -84,7 +84,7 @@ from rowers.models import (
|
||||
createmicrofillers, createmesofillers,
|
||||
microcyclecheckdates,mesocyclecheckdates,macrocyclecheckdates,
|
||||
TrainingMesoCycleForm, TrainingMicroCycleForm,
|
||||
RaceLogo,RowerBillingAddressForm,
|
||||
RaceLogo,RowerBillingAddressForm,PaidPlan,
|
||||
)
|
||||
from rowers.models import (
|
||||
RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm,
|
||||
@@ -738,8 +738,27 @@ def deactivate_user(request):
|
||||
if request.method == "POST":
|
||||
user_form = DeactivateUserForm(request.POST, instance=user)
|
||||
if user_form.is_valid():
|
||||
r = Rower.objects.get(user=user)
|
||||
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
||||
try:
|
||||
subscriptions = braintreestuff.find_subscriptions(r)
|
||||
for subscription in subscriptions:
|
||||
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
||||
for message in themessages:
|
||||
messages.info(request,message)
|
||||
except ProcessorCustomerError:
|
||||
pass
|
||||
|
||||
r.paidplan = None
|
||||
r.teamplanexpires = timezone.now()
|
||||
r.planexpires = timezone.now()
|
||||
r.clubsize = 0
|
||||
r.rowerplan = 'basic'
|
||||
r.save()
|
||||
|
||||
deactivate_user = user_form.save(commit=False)
|
||||
user.is_active = False
|
||||
user.save()
|
||||
deactivate_user.save()
|
||||
# url = reverse(auth_views.logout_then_login)
|
||||
url = '/logout/?next=/login'
|
||||
@@ -790,6 +809,16 @@ def remove_user(request):
|
||||
name = user.first_name+' '+user.last_name
|
||||
email = user.email
|
||||
|
||||
r = Rower.objects.get(user=user)
|
||||
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
||||
try:
|
||||
subscriptions = braintreestuff.find_subscriptions(r)
|
||||
for subscription in subscriptions:
|
||||
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
||||
for message in themessages:
|
||||
messages.info(request,message)
|
||||
except ProcessorCustomerError:
|
||||
pass
|
||||
|
||||
if cd['delete_user']:
|
||||
user.delete()
|
||||
@@ -998,7 +1027,7 @@ def hasplannedsessions(user):
|
||||
|
||||
return result
|
||||
|
||||
from rowers.utils import isprorower
|
||||
from rowers.utils import isprorower,ProcessorCustomerError
|
||||
|
||||
# Check if a user is a Pro member
|
||||
def ispromember(user):
|
||||
@@ -1056,6 +1085,19 @@ def billing_view(request):
|
||||
|
||||
if planselectform.is_valid():
|
||||
plan = planselectform.cleaned_data['plan']
|
||||
if billingaddressform.is_valid():
|
||||
try:
|
||||
customer_id = braintreestuff.create_customer(r)
|
||||
except ProcessorCustomerError:
|
||||
messages.error(request,"Something went wrong registering you as a customer.")
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
url = reverse(payment_confirm_view,
|
||||
kwargs={
|
||||
'planid':plan.id
|
||||
})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
else:
|
||||
billingaddressform = RowerBillingAddressForm(instance=r)
|
||||
planselectform = PlanSelectForm(paymentprocessor='braintree')
|
||||
@@ -1067,48 +1109,64 @@ def billing_view(request):
|
||||
'planselectform':planselectform,
|
||||
})
|
||||
|
||||
|
||||
|
||||
# Experimental - Payments
|
||||
@login_required()
|
||||
def payments_view(request):
|
||||
def plan_stop_view(request):
|
||||
r = getrequestrower(request)
|
||||
|
||||
subscriptions = []
|
||||
|
||||
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
|
||||
try:
|
||||
subscriptions = braintreestuff.find_subscriptions(r)
|
||||
except ProcessorCustomerError:
|
||||
r.paymentprocessor = None
|
||||
r.save()
|
||||
|
||||
|
||||
|
||||
return render(request,
|
||||
'subscriptions_cancel.html',
|
||||
{'rower':r,
|
||||
'subscriptions':subscriptions
|
||||
})
|
||||
|
||||
@login_required()
|
||||
def plan_tobasic_view(request,id=0):
|
||||
r = getrequestrower(request)
|
||||
|
||||
if r.paidplan.paymentprocessor == 'braintree':
|
||||
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
|
||||
for message in themessages:
|
||||
messages.info(request,message)
|
||||
|
||||
for message in errormessages:
|
||||
messages.error(request,message)
|
||||
|
||||
url = reverse(plan_stop_view)
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
|
||||
@login_required()
|
||||
def payment_confirm_view(request,planid = 0):
|
||||
try:
|
||||
plan = PaidPlan.objects.get(id=planid)
|
||||
except PaidPlan.DoesNotExist:
|
||||
messages.error(request,"Something went wrong. Please try again.")
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
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
|
||||
if not r.customer_id:
|
||||
result = gateway.customer.create(
|
||||
{
|
||||
'first_name':r.user.first_name,
|
||||
'last_name':r.user.last_name,
|
||||
'email':r.user.email,
|
||||
})
|
||||
|
||||
if not result.is_success:
|
||||
messages.error(request,'Failed to create customer. Please try again later')
|
||||
return render(request,
|
||||
"payments.html")
|
||||
else:
|
||||
r.customer_id = result.customer.id
|
||||
r.save()
|
||||
|
||||
client_token = gateway.client_token.generate({
|
||||
"customer_id": r.customer_id,
|
||||
})
|
||||
client_token = braintreestuff.get_client_token(r)
|
||||
|
||||
return render(request,
|
||||
"payments.html",
|
||||
"paymentconfirm.html",
|
||||
{
|
||||
'plan':plan,
|
||||
'client_token':client_token,
|
||||
'rower':r,
|
||||
})
|
||||
|
||||
|
||||
@@ -1118,72 +1176,41 @@ def checkouts_view(request):
|
||||
r = getrequestrower(request)
|
||||
|
||||
if request.method != 'POST':
|
||||
url = reverse(payments_view)
|
||||
url = reverse(paidplans_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 = BillingForm(request.POST)
|
||||
if form.is_valid():
|
||||
nonce_from_the_client = form.cleaned_data['payment_method_nonce']
|
||||
amount = form.cleaned_data['amount']
|
||||
amount = str(amount)
|
||||
|
||||
#for testing
|
||||
#nonce_from_the_client = 'fake-processor-declined-visa-none'
|
||||
|
||||
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
|
||||
if transaction.payment_instrument_type == "credit_card":
|
||||
country = transaction.credit_card_details.country_of_issuance
|
||||
if country == 'Unknown':
|
||||
bin = transaction.credit_card_details.bin
|
||||
url = "https://lookup.binlist.net/"+str(bin)
|
||||
headers = {
|
||||
'Accept-Version':'3',
|
||||
}
|
||||
binresult = requests.get(url,headers=headers)
|
||||
print binresult.status_code
|
||||
if binresult.status_code == 200:
|
||||
js = binresult.json()
|
||||
country = js['country']['name']
|
||||
|
||||
print country
|
||||
amount = transaction.amount
|
||||
messages.info(request,
|
||||
"We have successfully received your payment of {amount} Euro".format(
|
||||
amount=amount
|
||||
)
|
||||
)
|
||||
data = form.cleaned_data
|
||||
success = braintreestuff.create_subscription(r,data)
|
||||
if success:
|
||||
messages.info(request,"Your payment has succeeded and your plan has been updated")
|
||||
url = reverse(payment_completed_view)
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
messages.error(request,"We are sorry but there was an error with the payment")
|
||||
url = reverse(payments_view)
|
||||
messages.error(request,"There was a problem with your payment")
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
else:
|
||||
messages.error(request,"There was an error in the payment form")
|
||||
url = reverse(payments_view)
|
||||
url = reverse(billing_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
url = reverse(payments_view)
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
@login_required()
|
||||
def payment_completed_view(request):
|
||||
r = getrequestrower(request)
|
||||
|
||||
return render(request,
|
||||
"payment_completed.html",
|
||||
{
|
||||
'rower':r
|
||||
})
|
||||
|
||||
# User registration
|
||||
def rower_register_view(request):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user