payment app
This commit is contained in:
		
					parent
					
						
							
								b14b3d2803
							
						
					
				
			
			
				commit
				
					
						6223f4a1ef
					
				
			
		
					 15 changed files with 379 additions and 101 deletions
				
			
		|  | @ -412,3 +412,15 @@ META_USE_SITES = True | ||||||
| 
 | 
 | ||||||
| PARLER_LANGUAGES = {1: ({'code': 'en-us'}, {'code': 'de'},)} | PARLER_LANGUAGES = {1: ({'code': 'en-us'}, {'code': 'de'},)} | ||||||
| AUTH_USER_MODEL = 'membership.CustomUser' | AUTH_USER_MODEL = 'membership.CustomUser' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # PAYMENT | ||||||
|  | 
 | ||||||
|  | STRIPE_API_PUBLIC_KEY = 'pk_test_uvWyHNJgVL2IB8kjfgJkGjg4'  # used in frontend to call from user browser | ||||||
|  | STRIPE_API_PRIVATE_KEY = 'sk_test_uIPMdgXoRGydrcD7fkwcn7dj'  # used in backend payment | ||||||
|  | STRIPE_DESCRIPTION_ON_PAYMENT = "Payment for ungleich GmbH services" | ||||||
|  | 
 | ||||||
|  | # EMAIL MESSAGES | ||||||
|  | REGISTRATION_MESSAGE = {'subject': "Validation mail", | ||||||
|  |                         'message': 'Please validate Your account under this link http://localhost:8000/en-us/validate/{}', | ||||||
|  |                         'from': 'test@test.com'} | ||||||
|  |  | ||||||
|  | @ -1,14 +1,50 @@ | ||||||
| __author__ = 'tomislav' | __author__ = 'tomislav' | ||||||
| from django import forms | from django import forms | ||||||
|  | from django.utils.translation import ugettext_lazy as _ | ||||||
|  | import six | ||||||
|  | 
 | ||||||
|  | from .models import CreditCards | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class LoginForm(forms.Form): | class LoginForm(forms.Form): | ||||||
|     email = forms.EmailField(label="Email address", max_length=50, |     email = forms.EmailField(label="Email address", max_length=50, | ||||||
|                             widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter email'})) |                              widget=forms.TextInput( | ||||||
|  |                                  attrs={'class': 'form-control', 'placeholder': 'Enter email'})) | ||||||
|     password = forms.CharField(label='Password', max_length=50, |     password = forms.CharField(label='Password', max_length=50, | ||||||
|                                widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Password','type':'password'})) |                                widget=forms.TextInput( | ||||||
|  |                                    attrs={'class': 'form-control', 'placeholder': 'Password', | ||||||
|  |                                           'type': 'password'})) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class RegisterForm(LoginForm): | class RegisterForm(LoginForm): | ||||||
|     name = forms.CharField(label='Name', max_length=50, |     name = forms.CharField(label='Name', max_length=50, | ||||||
|                            widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder':'Enter name'})) |                            widget=forms.TextInput( | ||||||
|  |                                attrs={'class': 'form-control', 'placeholder': 'Enter name'})) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class PaymentForm(forms.ModelForm): | ||||||
|  |     class Meta: | ||||||
|  |         model = CreditCards | ||||||
|  |         fields = ('name', 'card_number', 'expiry_date', 'ccv', 'user_id') | ||||||
|  |         labels = {'name': _('Name'), 'card_number': _('Card number'), 'expiry_date': _('Expiry date'), | ||||||
|  |                   'ccv': _('CCV')} | ||||||
|  |         exclude = ('user_id','payment_type') | ||||||
|  |         widgets = { | ||||||
|  |             'name': forms.TextInput( | ||||||
|  |                 attrs={'class': 'form-control', "placeholder": "Enter name on card", | ||||||
|  |                        'placeholder': 'Enter name on card'}), | ||||||
|  |             'card_number': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Card Number','data-stripe':'number'}), | ||||||
|  |             'expiry_date': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'MM/YYYY'}), | ||||||
|  |             'ccv': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'CCV','data-stripe':'cvc'})} | ||||||
|  | 
 | ||||||
|  |     def clean(self): | ||||||
|  |         data = self.cleaned_data | ||||||
|  | 
 | ||||||
|  |         # if CreditCards.objects.filter(card_number=data.get("card_number")): | ||||||
|  |         #     raise forms.ValidationError({'card_number': _('Credit card is used before.')}) | ||||||
|  |         return self.cleaned_data | ||||||
|  | 
 | ||||||
|  |     def save(self, user_id): | ||||||
|  |         self.instance.user_id = user_id | ||||||
|  |         self.instance.user_id_id = user_id.id | ||||||
|  |         super(PaymentForm, self).save() | ||||||
|  |  | ||||||
							
								
								
									
										42
									
								
								membership/migrations/0001_initial.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								membership/migrations/0001_initial.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | from __future__ import unicode_literals | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | from django.conf import settings | ||||||
|  | import django.core.validators | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.CreateModel( | ||||||
|  |             name='CustomUser', | ||||||
|  |             fields=[ | ||||||
|  |                 ('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID', primary_key=True)), | ||||||
|  |                 ('password', models.CharField(verbose_name='password', max_length=128)), | ||||||
|  |                 ('last_login', models.DateTimeField(null=True, verbose_name='last login', blank=True)), | ||||||
|  |                 ('name', models.CharField(max_length=50)), | ||||||
|  |                 ('email', models.EmailField(unique=True, max_length=254)), | ||||||
|  |                 ('validated', models.IntegerField(default=0, choices=[(0, 'Not validated'), (1, 'Validated')])), | ||||||
|  |                 ('validation_slug', models.CharField(unique=True, max_length=50, db_index=True)), | ||||||
|  |             ], | ||||||
|  |             options={ | ||||||
|  |                 'abstract': False, | ||||||
|  |             }, | ||||||
|  |         ), | ||||||
|  |         migrations.CreateModel( | ||||||
|  |             name='CreditCards', | ||||||
|  |             fields=[ | ||||||
|  |                 ('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID', primary_key=True)), | ||||||
|  |                 ('name', models.CharField(max_length=50)), | ||||||
|  |                 ('card_number', models.CharField(max_length=50)), | ||||||
|  |                 ('expiry_date', models.CharField(validators=[django.core.validators.RegexValidator('\\d{2}\\/\\d{4}', 'Use this pattern(MM/YYYY).')], max_length=50)), | ||||||
|  |                 ('ccv', models.CharField(validators=[django.core.validators.RegexValidator('\\d{3,4}', 'Wrong CCV number.')], max_length=4)), | ||||||
|  |                 ('payment_type', models.CharField(max_length=5, default='N')), | ||||||
|  |                 ('user_id', models.ForeignKey(to=settings.AUTH_USER_MODEL)), | ||||||
|  |             ], | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
							
								
								
									
										0
									
								
								membership/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								membership/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -1,7 +1,9 @@ | ||||||
| from django.db import models | from django.db import models | ||||||
|  | from django.utils.translation import ugettext_lazy as _ | ||||||
| from django.contrib.auth.models import User, AbstractBaseUser, BaseUserManager | from django.contrib.auth.models import User, AbstractBaseUser, BaseUserManager | ||||||
| from django.contrib.auth.hashers import make_password | from django.contrib.auth.hashers import make_password | ||||||
| from django.core.mail import send_mail | from django.core.mail import send_mail | ||||||
|  | from django.core.validators import RegexValidator | ||||||
| 
 | 
 | ||||||
| REGISTRATION_MESSAGE = {'subject': "Validation mail", | REGISTRATION_MESSAGE = {'subject': "Validation mail", | ||||||
|                         'message': 'Please validate Your account under this link http://localhost:8000/en-us/validate/{}', |                         'message': 'Please validate Your account under this link http://localhost:8000/en-us/validate/{}', | ||||||
|  | @ -110,7 +112,12 @@ class CustomUser(AbstractBaseUser): | ||||||
|         # Simplest possible answer: All admins are staff |         # Simplest possible answer: All admins are staff | ||||||
|         return self.is_admin |         return self.is_admin | ||||||
| 
 | 
 | ||||||
| # class CreditCards(models.Model): | 
 | ||||||
| #     id = models.IntegerField(primary_key=True) | class CreditCards(models.Model): | ||||||
| #     user_id = models.ForeignKey(User, on_delete=models.CASCADE) |     name = models.CharField(max_length=50) | ||||||
| #     number = models.CharField(max_length=400) |     user_id = models.ForeignKey(CustomUser, on_delete=models.CASCADE) | ||||||
|  |     card_number = models.CharField(max_length=50) | ||||||
|  |     expiry_date = models.CharField(max_length=50, validators=[RegexValidator(r'\d{2}\/\d{4}', _( | ||||||
|  |         'Use this pattern(MM/YYYY).'))]) | ||||||
|  |     ccv = models.CharField(max_length=4,validators=[RegexValidator(r'\d{3,4}',_('Wrong CCV number.'))]) | ||||||
|  |     payment_type = models.CharField(max_length=5,default='N') | ||||||
|  |  | ||||||
							
								
								
									
										46
									
								
								membership/payment.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								membership/payment.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | ||||||
|  | __author__ = 'tomislav' | ||||||
|  | from django.conf import settings | ||||||
|  | from .models import CreditCards | ||||||
|  | import stripe | ||||||
|  | stripe.api_key = settings.STRIPE_API_PRIVATE_KEY | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class StripePayment(object): | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def make_payment(cls,user,amount,token,time): | ||||||
|  |         try: | ||||||
|  |             # Use Stripe's library to make requests... | ||||||
|  |             charge = stripe.Charge.create( | ||||||
|  |                 amount=amount, | ||||||
|  |                 currency='chf', | ||||||
|  |                 source=token, | ||||||
|  |                 description=settings.STRIPE_DESCRIPTION_ON_PAYMENT | ||||||
|  |             ) | ||||||
|  |             if charge['status'] =='succeeded': | ||||||
|  |                 obj = CreditCards.objects.filter(user_id=user.id).first() | ||||||
|  |                 obj.payment_type = time | ||||||
|  |                 obj.save() | ||||||
|  |             return charge['status'] | ||||||
|  | 
 | ||||||
|  |         except stripe.error.CardError as e: | ||||||
|  |             # Since it's a decline, stripe.error.CardError will be caught | ||||||
|  |             body = e.json_body | ||||||
|  |             err = body['error'] | ||||||
|  |             return err['message'] | ||||||
|  |         except stripe.error.RateLimitError as e: | ||||||
|  |             return "Too many requests made to the API too quickly" | ||||||
|  |         except stripe.error.InvalidRequestError as e: | ||||||
|  |             return "Invalid parameters" | ||||||
|  |         except stripe.error.AuthenticationError as e: | ||||||
|  |             # Authentication with Stripe's API failed | ||||||
|  |             # (maybe you changed API keys recently) | ||||||
|  |             pass | ||||||
|  |         except stripe.error.APIConnectionError as e: | ||||||
|  |             return "Currently its not possible to make payments." | ||||||
|  |         except stripe.error.StripeError as e: | ||||||
|  |             return "Currently its not possible to make payments." | ||||||
|  |             #maybe send email | ||||||
|  |         except Exception as e: | ||||||
|  |             return "Currently its not possible to make payments." | ||||||
|  |             #maybe send email | ||||||
|  | @ -4,7 +4,8 @@ | ||||||
|     <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> |     <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> | ||||||
|     <script type="text/javascript" src="http://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> |     <script type="text/javascript" src="http://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> | ||||||
|     <link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> |     <link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> | ||||||
|     <link href="membership.css" rel="stylesheet" type="text/css"> |     {% load static %} | ||||||
|  |     <link href="{% get_static_prefix %}membership.css" rel="stylesheet" type="text/css"> | ||||||
|   </head><body> |   </head><body> | ||||||
|     <div class="section"> |     <div class="section"> | ||||||
|       <div class="container"> |       <div class="container"> | ||||||
|  | @ -19,8 +20,15 @@ | ||||||
|                       <h2 class="text-center text-muted">Your membership is almost ready!</h2> |                       <h2 class="text-center text-muted">Your membership is almost ready!</h2> | ||||||
|                       <h5 class="text-center text-muted">If this is correct information, click CONFIRM</h5> |                       <h5 class="text-center text-muted">If this is correct information, click CONFIRM</h5> | ||||||
|                       <br> |                       <br> | ||||||
|                       <h4 class="text-center text-muted">Name: Nico Schottelius</h4> |                       <h4 class="text-center text-muted">Name: {{ name }}</h4> | ||||||
|                       <h4 class="text-center text-muted">Email: nico.schottelius@digitalglarus.ch</h4> | 
 | ||||||
|  |                         {% if email %} | ||||||
|  |                       <h4 class="text-center text-muted">Email: {{ email }}</h4> | ||||||
|  |                         {% else %} | ||||||
|  |                             <script type="text/javascript"> | ||||||
|  | 
 | ||||||
|  |                             </script> | ||||||
|  |                         {% endif %} | ||||||
|                       <h4 class="text-center text-muted">Membership requested for: |                       <h4 class="text-center text-muted">Membership requested for: | ||||||
|                         <br><br>01.01.2016-31.12.2016</h4> |                         <br><br>01.01.2016-31.12.2016</h4> | ||||||
|                       <br> |                       <br> | ||||||
|  | @ -30,12 +38,12 @@ | ||||||
|                 </div> |                 </div> | ||||||
|                 <div class="row"> |                 <div class="row"> | ||||||
|                   <div class="col-md-12 text-center"> |                   <div class="col-md-12 text-center"> | ||||||
|                     <p class="text-center text-muted">Have probelm? Contact |                     <p class="text-center text-muted">Have problem? Contact | ||||||
|                       <a href="">help@digitalglarus.ch.</a> |                       <a href="">help@digitalglarus.ch.</a> | ||||||
|                       <br> |                       <br> | ||||||
|                     </p> |                     </p> | ||||||
|                     <a class="btn btn-primary">GO BACK</a> |                     <a class="btn btn-primary" href="{% url 'reset' time=request.session.time %}">GO BACK</a> | ||||||
|                     <a class="btn btn-primary">CONFIRM</a> |                     <a class="btn btn-primary" href='.'>CONFIRM</a> | ||||||
|                   </div> |                   </div> | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
|  |  | ||||||
|  | @ -1,11 +1,53 @@ | ||||||
| <html><head> | <html> | ||||||
|  | <head> | ||||||
|     <meta charset="utf-8"> |     <meta charset="utf-8"> | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1"> |     <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|     <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> |     <script type="text/javascript" | ||||||
|     <script type="text/javascript" src="http://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> |             src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> | ||||||
|     <link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> |     <script type="text/javascript" | ||||||
|     <link href="membership.css" rel="stylesheet" type="text/css"> |             src="http://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> | ||||||
|   </head><body> |     <script type="text/javascript" src="https://js.stripe.com/v2/"></script> | ||||||
|  |     <script type="text/javascript"> | ||||||
|  |         Stripe.setPublishableKey('{{ stripe_key }}'); | ||||||
|  |         var stripeResponseHandler = function (status, response) { | ||||||
|  |             var $form = $('#payment-form'); | ||||||
|  |             if (response.error) { | ||||||
|  |                 debugger; | ||||||
|  |                 // Show the errors on the form | ||||||
|  |                 $form.find('.payment-errors').text(response.error.message); | ||||||
|  |                 $form.find('button').prop('disabled', false); | ||||||
|  |             } else { | ||||||
|  |                 // token contains id, last4, and card type | ||||||
|  |                 var token = response.id; | ||||||
|  |                 // Insert the token into the form so it gets submitted to the server | ||||||
|  |                 $form.append($('<input type="hidden" name="stripeToken" />').val(token)); | ||||||
|  |                 // and re-submit | ||||||
|  |                 $form.get(0).submit(); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |         jQuery(function ($) { | ||||||
|  |             $('#payment-form').submit(function (e) { | ||||||
|  |                 var $form = $(this); | ||||||
|  |                 m_y = $("#id_expiry_date").val().split("/") | ||||||
|  |                 // Disable the submit button to prevent repeated clicks | ||||||
|  |                 $form.find('button').prop('disabled', true); | ||||||
|  |                 Stripe.card.createToken({ | ||||||
|  |                     number: $("#id_card_number").val(), | ||||||
|  |                     cvc: $("#id_ccv").val(), | ||||||
|  |                     exp_month:m_y[0], | ||||||
|  |                     exp_year:m_y[1] | ||||||
|  |                 }, stripeResponseHandler); | ||||||
|  |                 // Prevent the form from submitting with the default action | ||||||
|  |                 return false; | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     </script> | ||||||
|  |     <link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" | ||||||
|  |           rel="stylesheet" type="text/css"> | ||||||
|  |     {% load static %} | ||||||
|  |     <link href="{% get_static_prefix %}membership.css" rel="stylesheet" type="text/css"> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
| <div class="section"> | <div class="section"> | ||||||
|     <div class="container"> |     <div class="container"> | ||||||
|         <div class="row"> |         <div class="row"> | ||||||
|  | @ -14,35 +56,29 @@ | ||||||
|                 <h3 class="text-left text-muted">Payment details</h3> |                 <h3 class="text-left text-muted">Payment details</h3> | ||||||
|                 <hr> |                 <hr> | ||||||
|                 <div class="page-header text-muted" contenteditable="true"> |                 <div class="page-header text-muted" contenteditable="true"> | ||||||
|               <h5>1 Year coworking membership  (360 CHF)</h5> |                     <h5>{{ time }} coworking membership  ({{ price }} CHF)</h5> | ||||||
|               <h5>  +2 free working days included  (0 CHF)</h5> |                     <h5>  +{{ free }} free working days included  (0 CHF)</h5> | ||||||
|  | 
 | ||||||
|                     <div class="page-header text-muted"> |                     <div class="page-header text-muted"> | ||||||
|                         <h5>Valid 01.01.2016 - 31.12.2016 </h5> |                         <h5>Valid 01.01.2016 - 31.12.2016 </h5> | ||||||
|                 <h5>Coworker Name : Nico Schottelius </h5> |                         <h5>Coworker Name : {{ name }} </h5> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                 </div> | ||||||
|                 <div class="page-header text-muted"> |                 <div class="page-header text-muted"> | ||||||
|               <h3 class="text-right">Total : 360 CHF</h3> |                     <h3 class="text-right">Total : {{ price }} CHF</h3> | ||||||
|                 </div> |                 </div> | ||||||
|             <form role="form"> |                 <form id="payment-form" role="form" method="post"> | ||||||
|  |                     <div class="payment-error"></div> | ||||||
|  |                     {% csrf_token %} | ||||||
|  |                     {% for field in  form %} | ||||||
|                         <div class="form-group"> |                         <div class="form-group"> | ||||||
|                 <label class="control-label" for="exampleInputEmail1">Name*</label> |                             <label class="control-label">{{ field.label }}*</label> | ||||||
|                 <input class="form-control" id="exampleInputEmail1" placeholder="Enter name on card" type="email"> |                             {{ field }} | ||||||
|               </div> |                             {% for error in field.errors %} | ||||||
|               <div class="form-group"> |                                 {{ error|striptags }} | ||||||
|                 <label class="control-label" for="exampleInputPassword1">Card Number*</label> |                             {% endfor %} | ||||||
|                 <input class="form-control" id="exampleInputPassword1" placeholder="Card Number" type="text"> |  | ||||||
|               </div> |  | ||||||
|             </form> |  | ||||||
|             <form role="form"> |  | ||||||
|               <div class="form-group"> |  | ||||||
|                 <label class="control-label" for="exampleInputEmail1">Expiry Date*</label> |  | ||||||
|                 <input class="form-control" id="exampleInputEmail1" placeholder="MM/YY" type="email"> |  | ||||||
|               </div> |  | ||||||
|               <div class="form-group"> |  | ||||||
|                 <label class="control-label" for="exampleInputPassword1">CCV*</label> |  | ||||||
|                 <input class="form-control" id="exampleInputPassword1" placeholder="CVV" type="password"> |  | ||||||
|                         </div> |                         </div> | ||||||
|  |                     {% endfor %} | ||||||
|                     <button type="submit" class="btn btn-block btn-primary">Submit</button> |                     <button type="submit" class="btn btn-block btn-primary">Submit</button> | ||||||
|                 </form> |                 </form> | ||||||
|                 <a class="btn btn-block btn-info">Cancel</a> |                 <a class="btn btn-block btn-info">Cancel</a> | ||||||
|  | @ -52,6 +88,7 @@ | ||||||
|         <div class="row"> |         <div class="row"> | ||||||
|             <div class="col-md-11"> |             <div class="col-md-11"> | ||||||
|                 <br> |                 <br> | ||||||
|  | 
 | ||||||
|                 <p class="text-center text-muted">Have probelm? Contact |                 <p class="text-center text-muted">Have probelm? Contact | ||||||
|                     <a href="">help@digitalglarus.ch.</a> |                     <a href="">help@digitalglarus.ch.</a> | ||||||
|                     <br> |                     <br> | ||||||
|  | @ -63,4 +100,5 @@ | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| </body></html> | </body> | ||||||
|  | </html> | ||||||
|  | @ -2,12 +2,16 @@ | ||||||
| <head> | <head> | ||||||
|     <meta charset="utf-8"> |     <meta charset="utf-8"> | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1"> |     <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|     <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> |     <script type="text/javascript" | ||||||
|     <script type="text/javascript" src="http://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> |             src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> | ||||||
|     <link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" |     <script type="text/javascript" | ||||||
|  |             src="http://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> | ||||||
|  |     <link href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" | ||||||
|  |           rel="stylesheet" | ||||||
|           type="text/css"> |           type="text/css"> | ||||||
|     {% load static %} |     {% load static %} | ||||||
|     <link href="{% get_static_prefix %}membership.css" rel="stylesheet" type="text/css"> |     <link href="{% get_static_prefix %}membership.css" rel="stylesheet" type="text/css"> | ||||||
|  | 
 | ||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
| <div class="section"> | <div class="section"> | ||||||
|  | @ -24,6 +28,8 @@ | ||||||
|                     <a href="">help@digitalglarus.ch</a> |                     <a href="">help@digitalglarus.ch</a> | ||||||
|                 </p> |                 </p> | ||||||
| 
 | 
 | ||||||
|  |                 <p>{{ msg }}</p> | ||||||
|  | 
 | ||||||
|                 <p></p> |                 <p></p> | ||||||
|             </div> |             </div> | ||||||
|             <a hrefhelp@digitalglarus.ch<="" p=""> |             <a hrefhelp@digitalglarus.ch<="" p=""> | ||||||
|  |  | ||||||
|  | @ -79,7 +79,7 @@ | ||||||
|               for coworking. It is a perfect try-out package! |               for coworking. It is a perfect try-out package! | ||||||
|               <br> |               <br> | ||||||
|             </p> |             </p> | ||||||
|             <a class="btn btn-primary">Buy Now</a> |             <a class="btn btn-primary" href="/login/buy/month/">Buy Now</a> | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|  | @ -98,7 +98,7 @@ | ||||||
|               membership. |               membership. | ||||||
|               <br> |               <br> | ||||||
|             </p> |             </p> | ||||||
|             <a class="btn btn-primary">Buy Now</a> |             <a class="btn btn-primary" href="/login/buy/year/">Buy Now</a> | ||||||
|           </div> |           </div> | ||||||
|           <div class="col-md-6"> |           <div class="col-md-6"> | ||||||
|             <img src="https://unsplash.imgix.net/photo-1413834932717-29e7d4714192?w=1024&q=50&fm=jpg&s=d9d6cbc32dd4968d0c21e331436a6af6" class="img-responsive"> |             <img src="https://unsplash.imgix.net/photo-1413834932717-29e7d4714192?w=1024&q=50&fm=jpg&s=d9d6cbc32dd4968d0c21e331436a6af6" class="img-responsive"> | ||||||
|  |  | ||||||
|  | @ -8,13 +8,27 @@ | ||||||
|           type="text/css"> |           type="text/css"> | ||||||
|     <link href="http://pingendo.github.io/pingendo-bootstrap/themes/default/bootstrap.css" rel="stylesheet" |     <link href="http://pingendo.github.io/pingendo-bootstrap/themes/default/bootstrap.css" rel="stylesheet" | ||||||
|           type="text/css"> |           type="text/css"> | ||||||
|  |     {% if request.session.next == None %} | ||||||
|  |     <script> | ||||||
|  |         type = "text/javascript" > | ||||||
|  |                 setTimeout(function () { | ||||||
|  |                     window.location.href = "/"; | ||||||
|  |                 }, 5000); | ||||||
|  |     </script> | ||||||
|  |     {% endif %} | ||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
| <div class="section"> | <div class="section"> | ||||||
|     <div class="container"> |     <div class="container"> | ||||||
|         <div class="row"> |         <div class="row"> | ||||||
|             <div class="col-md-12"> |             <div class="col-md-12"> | ||||||
|                 <h1 class="text-center text-muted">You're successfully validated!</h1> |                 <h3 class="text-center text-muted"> | ||||||
|  |                     {% if msg == 'succeeded' %} | ||||||
|  |                         Thank You for Your payment!<br> <p>redirecting...</p> | ||||||
|  |                     {% else %} | ||||||
|  |                         Your payment was not processed correctly.<br> Reason: {{ msg }} | ||||||
|  |                     {% endif %} | ||||||
|  |                 </h3> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|  | @ -1,10 +1,13 @@ | ||||||
| __author__ = 'tomislav' | __author__ = 'tomislav' | ||||||
| from django.conf.urls import url | from django.conf.urls import url | ||||||
|  | from django.contrib.auth.decorators import login_required | ||||||
| 
 | 
 | ||||||
| from . import views | from . import views | ||||||
| 
 | 
 | ||||||
| urlpatterns = ( | urlpatterns = ( | ||||||
|     url(r"^/$", views.LoginRegistrationView.as_view()), |     url(r"^/$", views.LoginRegistrationView.as_view(), name='login'), | ||||||
|     url(r"^/validate/(?P<validate_slug>.*)/$", views.validate_email), |     url(r"^/validate/(?P<validate_slug>.*)/$", views.validate_email), | ||||||
|     url(r"^/membership/$",views.MembershipView.as_view(),name='membership') |     url(r"^/membership/$", login_required(views.MembershipView.as_view()), name='membership'), | ||||||
|  |     url(r"^/buy/(?P<time>\w+)/$", login_required(views.CreditCardView.as_view()), name='payment'), | ||||||
|  |     url(r'^/buy/(?P<time>\w+)/reset',login_required(views.reset),name='reset') | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -1,27 +1,87 @@ | ||||||
| from django.shortcuts import render, redirect | from django.shortcuts import render, redirect | ||||||
| from django.views.generic import View | from django.views.generic import View | ||||||
|  | from django.contrib.auth import authenticate, login | ||||||
|  | from django.views.decorators.cache import cache_control | ||||||
|  | from django.conf import settings | ||||||
|  | from django.db.models import Q | ||||||
| 
 | 
 | ||||||
| from .models import CustomUser | from .models import CustomUser | ||||||
| from .forms import LoginForm, RegisterForm | from .forms import (LoginForm, RegisterForm, PaymentForm) | ||||||
| from django.contrib.auth import authenticate,login | from .payment import StripePayment | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def validate_email(request, validate_slug): | def validate_email(request, validate_slug): | ||||||
|     validated = User.validate_url(validate_slug) |     validated = CustomUser.validate_url(validate_slug) | ||||||
|     if validated: |     if validated: | ||||||
|         return render(request, 'templates/validated.html') |         return render(request, 'templates/validated.html') | ||||||
|     else: |     else: | ||||||
|         return render(request, 'templates/error.html') |         return render(request, 'templates/error.html') | ||||||
| 
 | 
 | ||||||
|  | def reset(request,time): | ||||||
|  |     request.session['next']=0 | ||||||
|  |     return redirect('payment',time=time) | ||||||
|  | 
 | ||||||
|  | class CreditCardView(View): | ||||||
|  |     def _get_context(self, request, time): | ||||||
|  |         request.session['time'] = time | ||||||
|  |         context = {} | ||||||
|  |         context['name'] = request.user.name | ||||||
|  |         if time == 'month': | ||||||
|  |             context['time'] = "1 month" | ||||||
|  |             context['price'] = "35" | ||||||
|  |             context['free'] = "1" | ||||||
|  |         elif time == 'year': | ||||||
|  |             context['time'] = '1 year' | ||||||
|  |             context['price'] = '360' | ||||||
|  |             context['free'] = "2" | ||||||
|  |         context['stripe_key'] = settings.STRIPE_API_PUBLIC_KEY | ||||||
|  |         context['form'] = PaymentForm() | ||||||
|  |         return context | ||||||
|  | 
 | ||||||
|  |     @cache_control(no_cache=True,must_revalidate=True) | ||||||
|  |     def get(self, request, time=None): | ||||||
|  |         context = self._get_context(request, time) | ||||||
|  |         next = request.session.get('next') | ||||||
|  |         if next == 1 or next ==0: | ||||||
|  |             template = 'templates/creditcard.html' | ||||||
|  |             request.session['next'] +=1 | ||||||
|  |         elif next == 2: | ||||||
|  |             msg = StripePayment.make_payment(request.user, request.session['amount'], | ||||||
|  |                                              request.session['token'],request.session['time']) | ||||||
|  |             template = 'templates/validated.html' | ||||||
|  |             context['msg'] = msg | ||||||
|  |             request.session['next'] = None | ||||||
|  |         return render(request, template, context) | ||||||
|  | 
 | ||||||
|  |     def post(self, request, time=None): | ||||||
|  |         form = PaymentForm(request.POST) | ||||||
|  |         stripe_token = request.POST['stripeToken'] | ||||||
|  | 
 | ||||||
|  |         if form.is_valid(): | ||||||
|  |             ret = form.save(request.user) | ||||||
|  |             amount = 35 if time == 'month' else 360 | ||||||
|  |             amount = amount * 100  # payments are in 'cents' | ||||||
|  |             request.session['token'] = stripe_token | ||||||
|  |             request.session['amount'] = amount | ||||||
|  |             request.session['next'] +=1 | ||||||
|  |             return render(request, 'templates/confirm.html', | ||||||
|  |                           context={'name': request.user.name, 'email': request.user.email}) | ||||||
|  |         else: | ||||||
|  |             context = self._get_context(request, time) | ||||||
|  |             context['form'] = form | ||||||
|  |             return render(request, 'templates/creditcard.html', context=context) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class LoginRegistrationView(View): | class LoginRegistrationView(View): | ||||||
|     def get(self, request): |     def get(self, request): | ||||||
|         login_form = LoginForm() |         login_form = LoginForm() | ||||||
|         register_form = RegisterForm() |         register_form = RegisterForm() | ||||||
|  |         request.session['next'] = None | ||||||
|         if request.user.is_authenticated(): |         if request.user.is_authenticated(): | ||||||
|             return redirect("membership") |             return redirect("membership") | ||||||
|         else: |         else: | ||||||
|             return render(request, 'templates/login.html', {'login_form': login_form, 'register_form': register_form}) |             return render(request, 'templates/login.html', | ||||||
|  |                           {'login_form': login_form, 'register_form': register_form}) | ||||||
| 
 | 
 | ||||||
|     def post(self, request): |     def post(self, request): | ||||||
|         email = request.POST.get('email') |         email = request.POST.get('email') | ||||||
|  | @ -40,8 +100,14 @@ class LoginRegistrationView(View): | ||||||
|                 login(request, user) |                 login(request, user) | ||||||
|                 return redirect('membership') |                 return redirect('membership') | ||||||
|             else: |             else: | ||||||
|                 return render(request, 'templates/login', {'msg': 'Wrong username or password'}) |                 return redirect('login') | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class MembershipView(View): | class MembershipView(View): | ||||||
|     def get(self, request): |     def get(self, request): | ||||||
|  |         #if the user has payed allready | ||||||
|  |         member_payed = request.user.creditcards_set.filter(Q(payment_type='month') | Q(payment_type='year')) | ||||||
|  |         if member_payed: | ||||||
|  |             return redirect('/') | ||||||
|  |         request.session['next'] = 0 | ||||||
|         return render(request, 'templates/membership.html') |         return render(request, 'templates/membership.html') | ||||||
|  |  | ||||||
|  | @ -89,11 +89,11 @@ pyquery==1.2.9 | ||||||
| python-memcached==1.57 | python-memcached==1.57 | ||||||
| pytz==2015.6 | pytz==2015.6 | ||||||
| pyzmq==14.7.0 | pyzmq==14.7.0 | ||||||
| requests==2.7.0 | requests==2.9.1 | ||||||
| simplejson==3.8.0 | simplejson==3.8.0 | ||||||
| six==1.10.0 | six==1.10.0 | ||||||
| sqlparse==0.1.15 | sqlparse==0.1.15 | ||||||
| stripe==1.22.3 | stripe==1.30.0 | ||||||
| tomako==0.1.0 | tomako==0.1.0 | ||||||
| TornadIO2==0.0.3 | TornadIO2==0.0.3 | ||||||
| tornado==4.2.1 | tornado==4.2.1 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue