From bf334a38d4ba7a686347c3c8da6fd0555a869b10 Mon Sep 17 00:00:00 2001 From: Levi Date: Tue, 26 Apr 2016 01:16:03 -0500 Subject: [PATCH] Added Hosting Order model, Created Billing Address Model , Method to create a customer using Stripe API , Created Customer Stripe profile to store for further charges , Method in order to charge an amount to a customer --- digitalglarus/urls.py | 4 +- dynamicweb/settings/base.py | 4 +- dynamicweb/urls.py | 2 +- hosting/migrations/0009_auto_20160426_0444.py | 44 +++++++++++++++++++ hosting/migrations/0010_auto_20160426_0530.py | 25 +++++++++++ hosting/migrations/0011_auto_20160426_0555.py | 21 +++++++++ hosting/models.py | 30 +++++++++++-- hosting/static/hosting/js/payment.js | 18 +------- hosting/templates/hosting/payment.html | 7 +++ hosting/views.py | 39 +++++++++++++--- membership/migrations/0004_stripecustomer.py | 25 +++++++++++ membership/models.py | 27 ++++++++++++ utils/fields.py | 6 ++- utils/forms.py | 12 +++-- utils/migrations/0002_billingaddress.py | 26 +++++++++++ utils/models.py | 12 ++++- utils/stripe_utils.py | 21 ++++++++- 17 files changed, 281 insertions(+), 42 deletions(-) create mode 100644 hosting/migrations/0009_auto_20160426_0444.py create mode 100644 hosting/migrations/0010_auto_20160426_0530.py create mode 100644 hosting/migrations/0011_auto_20160426_0555.py create mode 100644 membership/migrations/0004_stripecustomer.py create mode 100644 utils/migrations/0002_billingaddress.py diff --git a/digitalglarus/urls.py b/digitalglarus/urls.py index b5329bab..4270fe2b 100644 --- a/digitalglarus/urls.py +++ b/digitalglarus/urls.py @@ -6,8 +6,8 @@ from .views import ContactView, IndexView, AboutView urlpatterns = [ # url(r'^$', IndexView.as_view(), name='home'), -# url(_(r'home/?$'), IndexView.as_view(), name='home'), -# url(_(r'about/?$'), AboutView.as_view(), name='about'), + url(_(r'home/?$'), IndexView.as_view(), name='home'), + url(_(r'about/?$'), AboutView.as_view(), name='about'), url(_(r'contact/?$'), ContactView.as_view(), name='contact'), url(_(r'supporters/?$'), views.supporters, name='supporters'), url(r'calendar_api/(?P\d+)/(?P\d+)?$',views.CalendarApi.as_view()), diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index d95d8afd..9d64dc60 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -446,8 +446,8 @@ 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_API_PUBLIC_KEY = 'pk_test_QqBZ50Am8KOxaAlOxbcm9Psl' # used in frontend to call from user browser +STRIPE_API_PRIVATE_KEY = 'sk_test_dqAmbKAij12QCGfkYZ3poGt2' # used in backend payment STRIPE_DESCRIPTION_ON_PAYMENT = "Payment for ungleich GmbH services" # EMAIL MESSAGES diff --git a/dynamicweb/urls.py b/dynamicweb/urls.py index 1d882cd0..3f313703 100644 --- a/dynamicweb/urls.py +++ b/dynamicweb/urls.py @@ -28,7 +28,7 @@ urlpatterns += i18n_patterns('', url(r'^digitalglarus/', include('digitalglarus.urls', namespace="digitalglarus"),name='digitalglarus'), url(r'^blog/',include('ungleich.urls',namespace='ungleich')), - url(r'^ungleich_page/',include('ungleich_page.urls',namespace='ungleich_page'),name='ungleich_page'), + url(r'^',include('ungleich_page.urls',namespace='ungleich_page'),name='ungleich_page'), url(r'^', include('cms.urls')), ) diff --git a/hosting/migrations/0009_auto_20160426_0444.py b/hosting/migrations/0009_auto_20160426_0444.py new file mode 100644 index 00000000..fdc51b6e --- /dev/null +++ b/hosting/migrations/0009_auto_20160426_0444.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-04-26 04:44 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('utils', '0002_billingaddress'), + ('membership', '0004_stripecustomer'), + ('hosting', '0008_virtualmachineplan'), + ] + + operations = [ + migrations.CreateModel( + name='HostingOrder', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ], + ), + migrations.RemoveField( + model_name='virtualmachineplan', + name='client', + ), + migrations.AddField( + model_name='hostingorder', + name='VMPlan', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hosting.VirtualMachinePlan'), + ), + migrations.AddField( + model_name='hostingorder', + name='billing_address', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='utils.BillingAddress'), + ), + migrations.AddField( + model_name='hostingorder', + name='customer', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='membership.StripeCustomer'), + ), + ] diff --git a/hosting/migrations/0010_auto_20160426_0530.py b/hosting/migrations/0010_auto_20160426_0530.py new file mode 100644 index 00000000..756c1446 --- /dev/null +++ b/hosting/migrations/0010_auto_20160426_0530.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-04-26 05:30 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('hosting', '0009_auto_20160426_0444'), + ] + + operations = [ + migrations.AddField( + model_name='hostingorder', + name='approved', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='hostingorder', + name='stripe_charge_id', + field=models.CharField(max_length=100, null=True), + ), + ] diff --git a/hosting/migrations/0011_auto_20160426_0555.py b/hosting/migrations/0011_auto_20160426_0555.py new file mode 100644 index 00000000..2eedbcc9 --- /dev/null +++ b/hosting/migrations/0011_auto_20160426_0555.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-04-26 05:55 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('hosting', '0010_auto_20160426_0530'), + ] + + operations = [ + migrations.AlterField( + model_name='hostingorder', + name='VMPlan', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='hosting.VirtualMachinePlan'), + ), + ] diff --git a/hosting/models.py b/hosting/models.py index 42e66e34..f3e2a178 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -3,7 +3,8 @@ import json from django.db import models from django.utils.translation import ugettext_lazy as _ from django.core import serializers -from membership.models import CustomUser +from membership.models import StripeCustomer +from utils.models import BillingAddress class RailsBetaUser(models.Model): @@ -78,13 +79,36 @@ class VirtualMachinePlan(models.Model): memory = models.IntegerField() disk_size = models.IntegerField() vm_type = models.ForeignKey(VirtualMachineType) - client = models.ManyToManyField(CustomUser) price = models.FloatField() @classmethod def create(cls, data, user): instance = cls.objects.create(**data) - instance.client.add(user) + return instance + + +class HostingOrder(models.Model): + VMPlan = models.OneToOneField(VirtualMachinePlan) + customer = models.ForeignKey(StripeCustomer) + billing_address = models.ForeignKey(BillingAddress) + created_at = models.DateTimeField(auto_now_add=True) + approved = models.BooleanField(default=False) + stripe_charge_id = models.CharField(max_length=100, null=True) + + @classmethod + def create(cls, VMPlan=None, customer=None, billing_address=None): + instance = cls.objects.create(VMPlan=VMPlan, customer=customer, + billing_address=billing_address) + return instance + + def set_approved(self): + self.approved = True + self.save() + + def set_stripe_charge(self, stripe_charge): + self.stripe_charge_id = stripe_charge.id + self.save() + diff --git a/hosting/static/hosting/js/payment.js b/hosting/static/hosting/js/payment.js index 05704cb9..dd6c64d4 100644 --- a/hosting/static/hosting/js/payment.js +++ b/hosting/static/hosting/js/payment.js @@ -35,7 +35,7 @@ $( document ).ready(function() { /* Visual feedback */ $form.find('[type=submit]').html('Validating '); - var PublishableKey = 'pk_test_6pRNASCoBOKtIshFeQd4XMUh'; // Replace with your API publishable key + var PublishableKey = window.stripeKey; Stripe.setPublishableKey(PublishableKey); Stripe.card.createToken($form, function stripeResponseHandler(status, response) { if (response.error) { @@ -52,27 +52,11 @@ $( document ).ready(function() { $form.find('.payment-errors').text(""); // response contains id and card, which contains additional card details var token = response.id; - console.log(token); // AJAX //set token on a hidden input $('#id_token').val(token); $('#billing-form').submit(); - - // $.post('/hosting/payment/', { - // token: token, - // }) - // // Assign handlers immediately after making the request, - // .done(function(data, textStatus, jqXHR) { - - // $form.find('[type=submit]').html('Payment successful ').prop('disabled', true); - // }) - // .fail(function(jqXHR, textStatus, errorThrown) { - // $form.find('[type=submit]').html('There was a problem').removeClass('success').addClass('error'); - // /* Show Stripe errors on the form */ - // $form.find('.payment-errors').text('Try refreshing the page and trying again.'); - // $form.find('.payment-errors').closest('.row').show(); - // }); } }); } diff --git a/hosting/templates/hosting/payment.html b/hosting/templates/hosting/payment.html index 68ccbb4a..1ebb1770 100644 --- a/hosting/templates/hosting/payment.html +++ b/hosting/templates/hosting/payment.html @@ -96,8 +96,15 @@ + +{% if stripe_key %} + +{%endif%} {%endblock%} + diff --git a/hosting/views.py b/hosting/views.py index 16c498f9..16556bc1 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -9,13 +9,15 @@ from django.contrib.auth import authenticate, login from django.conf import settings from membership.forms import PaymentForm -from membership.models import CustomUser +from membership.models import CustomUser, StripeCustomer +from utils.stripe_utils import StripeUtils from utils.forms import BillingAddressForm -from .models import VirtualMachineType, VirtualMachinePlan +from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder from .forms import HostingUserSignupForm, HostingUserLoginForm from .mixins import ProcessVMSelectionMixin + class DjangoHostingView(ProcessVMSelectionMixin, View): template_name = "hosting/django.html" @@ -157,21 +159,46 @@ class PaymentVMView(FormView): specifications = request.session.get('vm_specs') vm_type = specifications.get('hosting_company') vm = VirtualMachineType.objects.get(hosting_company=vm_type) + final_price = vm.calculate_price(specifications) plan_data = { 'vm_type': vm, 'cores': specifications.get('cores'), 'memory': specifications.get('memory'), 'disk_size': specifications.get('disk_size'), - 'price': vm.calculate_price(specifications) + 'price': final_price } + token = form.cleaned_data.get('token') - # Stripe payment goes here + # Get or create stripe customer + customer = StripeCustomer.get_or_create(email=self.request.user.email, + token=token) + # Create Virtual Machine Plan + plan = VirtualMachinePlan.create(plan_data, request.user) + + # Create Billing Address + billing_address = form.save() + + # Create a Hosting Order + order = HostingOrder.create(VMPlan=plan, customer=customer, + billing_address=billing_address) + + # Make stripe charge to a customer + stripe_utils = StripeUtils() + charge = stripe_utils.make_charge(amount=final_price, + customer=customer.stripe_id) + order.set_stripe_charge(charge) + + if not charge.paid: + # raise an error + pass + + # If the Stripe payment was successed, set order status approved + order.set_approved() + # order.charge = # Billing Address should be store here - VirtualMachinePlan.create(plan_data, request.user) - return HttpResponseRedirect(reverse('hosting:payment')) else: return self.form_invalid(form) diff --git a/membership/migrations/0004_stripecustomer.py b/membership/migrations/0004_stripecustomer.py new file mode 100644 index 00000000..29cc2aa6 --- /dev/null +++ b/membership/migrations/0004_stripecustomer.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-04-26 04:44 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('membership', '0003_auto_20160422_1002'), + ] + + operations = [ + migrations.CreateModel( + name='StripeCustomer', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('stripe_id', models.CharField(max_length=100, unique=True)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/membership/models.py b/membership/models.py index 1532d24f..0c23f572 100644 --- a/membership/models.py +++ b/membership/models.py @@ -8,6 +8,7 @@ from django.core.mail import send_mail from django.core.validators import RegexValidator from django.contrib.auth.models import User from django.contrib.sites.models import Site +from utils.stripe_utils import StripeUtils REGISTRATION_MESSAGE = {'subject': "Validation mail", 'message': 'Please validate Your account under this link http://localhost:8000/en-us/login/validate/{}', @@ -121,6 +122,32 @@ class CustomUser(AbstractBaseUser): return self.is_admin +class StripeCustomer(models.Model): + user = models.OneToOneField(CustomUser) + stripe_id = models.CharField(unique=True, max_length=100) + + @classmethod + def get_or_create(cls, email=None, token=None): + """ + Check if there is a registered stripe customer with that email + or create a new one + """ + try: + stripe_customer = cls.objects.get(user__email=email) + return stripe_customer + + except StripeCustomer.DoesNotExist: + user = CustomUser.objects.get(email=email) + + stripe_utils = StripeUtils() + stripe_data = stripe_utils.create_customer(token, email) + + stripe_customer = StripeCustomer.objects.\ + create(user=user, stripe_id=stripe_data.get('id')) + + return stripe_customer + + class CreditCards(models.Model): name = models.CharField(max_length=50) user_id = models.ForeignKey(CustomUser, on_delete=models.CASCADE) diff --git a/utils/fields.py b/utils/fields.py index aff70b59..43f80a51 100644 --- a/utils/fields.py +++ b/utils/fields.py @@ -1,4 +1,5 @@ from django.utils.translation import ugettext as _ +from django.db import models from django import forms # http://xml.coverpages.org/country3166.html @@ -245,10 +246,11 @@ COUNTRIES = ( ) -class CountryField(forms.ChoiceField): +class CountryField(models.CharField): def __init__(self, *args, **kwargs): kwargs.setdefault('choices', COUNTRIES) - kwargs.setdefault('initial', 'CH') + kwargs.setdefault('default', 'CH') + kwargs.setdefault('max_length', 2) super(CountryField, self).__init__(*args, **kwargs) diff --git a/utils/forms.py b/utils/forms.py index f9b2422f..0e64020a 100644 --- a/utils/forms.py +++ b/utils/forms.py @@ -1,19 +1,17 @@ from django import forms -from .models import ContactMessage +from .models import ContactMessage, BillingAddress from django.template.loader import render_to_string from django.core.mail import EmailMultiAlternatives from django.utils.translation import ugettext_lazy as _ -from utils.fields import CountryField +# from utils.fields import CountryField -class BillingAddressForm(forms.Form): - street_address = forms.CharField() - city = forms.CharField() - postal_code = forms.CharField() - country = CountryField() +class BillingAddressForm(forms.ModelForm): token = forms.CharField(widget=forms.HiddenInput()) class Meta: + model = BillingAddress + fields = ['street_address', 'city', 'postal_code', 'country'] labels = { 'street_address': _('Street Address'), 'city': _('City'), diff --git a/utils/migrations/0002_billingaddress.py b/utils/migrations/0002_billingaddress.py new file mode 100644 index 00000000..7fa22345 --- /dev/null +++ b/utils/migrations/0002_billingaddress.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-04-26 04:44 +from __future__ import unicode_literals + +from django.db import migrations, models +import utils.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('utils', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='BillingAddress', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('street_address', models.CharField(max_length=100)), + ('city', models.CharField(max_length=50)), + ('postal_code', models.CharField(max_length=50)), + ('country', utils.fields.CountryField(choices=[('AD', 'Andorra'), ('AE', 'United Arab Emirates'), ('AF', 'Afghanistan'), ('AG', 'Antigua & Barbuda'), ('AI', 'Anguilla'), ('AL', 'Albania'), ('AM', 'Armenia'), ('AN', 'Netherlands Antilles'), ('AO', 'Angola'), ('AQ', 'Antarctica'), ('AR', 'Argentina'), ('AS', 'American Samoa'), ('AT', 'Austria'), ('AU', 'Australia'), ('AW', 'Aruba'), ('AZ', 'Azerbaijan'), ('BA', 'Bosnia and Herzegovina'), ('BB', 'Barbados'), ('BD', 'Bangladesh'), ('BE', 'Belgium'), ('BF', 'Burkina Faso'), ('BG', 'Bulgaria'), ('BH', 'Bahrain'), ('BI', 'Burundi'), ('BJ', 'Benin'), ('BM', 'Bermuda'), ('BN', 'Brunei Darussalam'), ('BO', 'Bolivia'), ('BR', 'Brazil'), ('BS', 'Bahama'), ('BT', 'Bhutan'), ('BV', 'Bouvet Island'), ('BW', 'Botswana'), ('BY', 'Belarus'), ('BZ', 'Belize'), ('CA', 'Canada'), ('CC', 'Cocos (Keeling) Islands'), ('CF', 'Central African Republic'), ('CG', 'Congo'), ('CH', 'Switzerland'), ('CI', 'Ivory Coast'), ('CK', 'Cook Iislands'), ('CL', 'Chile'), ('CM', 'Cameroon'), ('CN', 'China'), ('CO', 'Colombia'), ('CR', 'Costa Rica'), ('CU', 'Cuba'), ('CV', 'Cape Verde'), ('CX', 'Christmas Island'), ('CY', 'Cyprus'), ('CZ', 'Czech Republic'), ('DE', 'Germany'), ('DJ', 'Djibouti'), ('DK', 'Denmark'), ('DM', 'Dominica'), ('DO', 'Dominican Republic'), ('DZ', 'Algeria'), ('EC', 'Ecuador'), ('EE', 'Estonia'), ('EG', 'Egypt'), ('EH', 'Western Sahara'), ('ER', 'Eritrea'), ('ES', 'Spain'), ('ET', 'Ethiopia'), ('FI', 'Finland'), ('FJ', 'Fiji'), ('FK', 'Falkland Islands (Malvinas)'), ('FM', 'Micronesia'), ('FO', 'Faroe Islands'), ('FR', 'France'), ('FX', 'France, Metropolitan'), ('GA', 'Gabon'), ('GB', 'United Kingdom (Great Britain)'), ('GD', 'Grenada'), ('GE', 'Georgia'), ('GF', 'French Guiana'), ('GH', 'Ghana'), ('GI', 'Gibraltar'), ('GL', 'Greenland'), ('GM', 'Gambia'), ('GN', 'Guinea'), ('GP', 'Guadeloupe'), ('GQ', 'Equatorial Guinea'), ('GR', 'Greece'), ('GS', 'South Georgia and the South Sandwich Islands'), ('GT', 'Guatemala'), ('GU', 'Guam'), ('GW', 'Guinea-Bissau'), ('GY', 'Guyana'), ('HK', 'Hong Kong'), ('HM', 'Heard & McDonald Islands'), ('HN', 'Honduras'), ('HR', 'Croatia'), ('HT', 'Haiti'), ('HU', 'Hungary'), ('ID', 'Indonesia'), ('IE', 'Ireland'), ('IL', 'Israel'), ('IN', 'India'), ('IO', 'British Indian Ocean Territory'), ('IQ', 'Iraq'), ('IR', 'Islamic Republic of Iran'), ('IS', 'Iceland'), ('IT', 'Italy'), ('JM', 'Jamaica'), ('JO', 'Jordan'), ('JP', 'Japan'), ('KE', 'Kenya'), ('KG', 'Kyrgyzstan'), ('KH', 'Cambodia'), ('KI', 'Kiribati'), ('KM', 'Comoros'), ('KN', 'St. Kitts and Nevis'), ('KP', "Korea, Democratic People's Republic of"), ('KR', 'Korea, Republic of'), ('KW', 'Kuwait'), ('KY', 'Cayman Islands'), ('KZ', 'Kazakhstan'), ('LA', "Lao People's Democratic Republic"), ('LB', 'Lebanon'), ('LC', 'Saint Lucia'), ('LI', 'Liechtenstein'), ('LK', 'Sri Lanka'), ('LR', 'Liberia'), ('LS', 'Lesotho'), ('LT', 'Lithuania'), ('LU', 'Luxembourg'), ('LV', 'Latvia'), ('LY', 'Libyan Arab Jamahiriya'), ('MA', 'Morocco'), ('MC', 'Monaco'), ('MD', 'Moldova, Republic of'), ('MG', 'Madagascar'), ('MH', 'Marshall Islands'), ('ML', 'Mali'), ('MN', 'Mongolia'), ('MM', 'Myanmar'), ('MO', 'Macau'), ('MP', 'Northern Mariana Islands'), ('MQ', 'Martinique'), ('MR', 'Mauritania'), ('MS', 'Monserrat'), ('MT', 'Malta'), ('MU', 'Mauritius'), ('MV', 'Maldives'), ('MW', 'Malawi'), ('MX', 'Mexico'), ('MY', 'Malaysia'), ('MZ', 'Mozambique'), ('NA', 'Namibia'), ('NC', 'New Caledonia'), ('NE', 'Niger'), ('NF', 'Norfolk Island'), ('NG', 'Nigeria'), ('NI', 'Nicaragua'), ('NL', 'Netherlands'), ('NO', 'Norway'), ('NP', 'Nepal'), ('NR', 'Nauru'), ('NU', 'Niue'), ('NZ', 'New Zealand'), ('OM', 'Oman'), ('PA', 'Panama'), ('PE', 'Peru'), ('PF', 'French Polynesia'), ('PG', 'Papua New Guinea'), ('PH', 'Philippines'), ('PK', 'Pakistan'), ('PL', 'Poland'), ('PM', 'St. Pierre & Miquelon'), ('PN', 'Pitcairn'), ('PR', 'Puerto Rico'), ('PT', 'Portugal'), ('PW', 'Palau'), ('PY', 'Paraguay'), ('QA', 'Qatar'), ('RE', 'Reunion'), ('RO', 'Romania'), ('RU', 'Russian Federation'), ('RW', 'Rwanda'), ('SA', 'Saudi Arabia'), ('SB', 'Solomon Islands'), ('SC', 'Seychelles'), ('SD', 'Sudan'), ('SE', 'Sweden'), ('SG', 'Singapore'), ('SH', 'St. Helena'), ('SI', 'Slovenia'), ('SJ', 'Svalbard & Jan Mayen Islands'), ('SK', 'Slovakia'), ('SL', 'Sierra Leone'), ('SM', 'San Marino'), ('SN', 'Senegal'), ('SO', 'Somalia'), ('SR', 'Suriname'), ('ST', 'Sao Tome & Principe'), ('SV', 'El Salvador'), ('SY', 'Syrian Arab Republic'), ('SZ', 'Swaziland'), ('TC', 'Turks & Caicos Islands'), ('TD', 'Chad'), ('TF', 'French Southern Territories'), ('TG', 'Togo'), ('TH', 'Thailand'), ('TJ', 'Tajikistan'), ('TK', 'Tokelau'), ('TM', 'Turkmenistan'), ('TN', 'Tunisia'), ('TO', 'Tonga'), ('TP', 'East Timor'), ('TR', 'Turkey'), ('TT', 'Trinidad & Tobago'), ('TV', 'Tuvalu'), ('TW', 'Taiwan, Province of China'), ('TZ', 'Tanzania, United Republic of'), ('UA', 'Ukraine'), ('UG', 'Uganda'), ('UM', 'United States Minor Outlying Islands'), ('US', 'United States of America'), ('UY', 'Uruguay'), ('UZ', 'Uzbekistan'), ('VA', 'Vatican City State (Holy See)'), ('VC', 'St. Vincent & the Grenadines'), ('VE', 'Venezuela'), ('VG', 'British Virgin Islands'), ('VI', 'United States Virgin Islands'), ('VN', 'Viet Nam'), ('VU', 'Vanuatu'), ('WF', 'Wallis & Futuna Islands'), ('WS', 'Samoa'), ('YE', 'Yemen'), ('YT', 'Mayotte'), ('YU', 'Yugoslavia'), ('ZA', 'South Africa'), ('ZM', 'Zambia'), ('ZR', 'Zaire'), ('ZW', 'Zimbabwe'), ('ZZ', 'Unknown or unspecified country')], default='CH', max_length=2)), + ], + ), + ] diff --git a/utils/models.py b/utils/models.py index 5b3ed5c0..045a7604 100644 --- a/utils/models.py +++ b/utils/models.py @@ -1,8 +1,18 @@ from django.db import models +from .fields import CountryField + # Create your models here. +class BillingAddress(models.Model): + street_address = models.CharField(max_length=100) + city = models.CharField(max_length=50) + postal_code = models.CharField(max_length=50) + country = CountryField() + + + class ContactMessage(models.Model): name = models.CharField(max_length=200) email = models.EmailField() @@ -11,4 +21,4 @@ class ContactMessage(models.Model): received_date = models.DateTimeField(auto_now_add=True) def __str__(self): - return "%s - %s - %s" % (self.name, self.email, self.received_date) \ No newline at end of file + return "%s - %s - %s" % (self.name, self.email, self.received_date) diff --git a/utils/stripe_utils.py b/utils/stripe_utils.py index a1381edf..cfe1e63a 100644 --- a/utils/stripe_utils.py +++ b/utils/stripe_utils.py @@ -12,6 +12,25 @@ class StripeUtils(object): self.stripe = stripe self.stripe.api_key = settings.STRIPE_API_PRIVATE_KEY + def create_customer(self, token, email): + stripe.api_key = settings.STRIPE_API_PRIVATE_KEY + customer = stripe.Customer.create( + source=token, + description='description for testing', + email=email + ) + return customer + + def make_charge(self, amount=None, customer=None): + amount = int(amount * 100) # stripe amount unit, in cents + + charge = self.stripe.Charge.create( + amount=amount, # in cents + currency=self.CURRENCY, + customer=customer + ) + return charge + def create_plan(self, amount, name, id): self.stripe.Plan.create( amount=amount, @@ -20,7 +39,7 @@ class StripeUtils(object): currency=self.CURRENCY, id=id) - def make_payment(self, user, amount, token, time): + def make_payment(self, user, amount, token): try: # Use Stripe's library to make requests... charge = self.stripe.Charge.create(