From 4b2a69154e25c870ffefdd20c009d9b20667a4fb Mon Sep 17 00:00:00 2001 From: Re-Krass <38668040+Re-Krass@users.noreply.github.com> Date: Thu, 21 Jun 2018 00:23:11 +0200 Subject: [PATCH] add basic payment settings --- Pipfile | 1 + Pipfile.lock | 112 +++++++++++++++++- .../api/migrations/0005_auto_20180621_0005.py | 58 +++++++++ ydl_api/api/models.py | 23 +++- ydl_api/api/serializers.py | 66 ++++++----- ydl_api/api/templates/api/payment.html | 7 ++ ydl_api/api/urls.py | 2 + ydl_api/api/views.py | 18 ++- 8 files changed, 252 insertions(+), 35 deletions(-) create mode 100644 ydl_api/api/migrations/0005_auto_20180621_0005.py create mode 100644 ydl_api/api/templates/api/payment.html diff --git a/Pipfile b/Pipfile index 7d57bf3..6f75e95 100644 --- a/Pipfile +++ b/Pipfile @@ -16,6 +16,7 @@ django-cors-headers = "*" gunicorn = "*" django-rest-swagger = "*" "django-sendgrid-v5" = "*" +django-payments = "*" [dev-packages] pylint = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 7d8036b..786241d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3974ee19ad1bdb6ff139ba0f8528b97bfef858ffb9ca4f70b8f1be018cde4d4f" + "sha256": "ba31f7144a765a6d62917fa15b689e827305192222d7771613af0b3ed8a41417" }, "pipfile-spec": 6, "requires": { @@ -16,6 +16,20 @@ ] }, "default": { + "asn1crypto": { + "hashes": [ + "sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87", + "sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49" + ], + "version": "==0.24.0" + }, + "braintree": { + "hashes": [ + "sha256:2cc26b961b2d066ee3031893278bf2c6b4e01d5f8b36b807c816c570ddd329f0", + "sha256:e94a2739b4e80c39aca17ef380e8b2af8ced87d8b65f7788eae2de769a33ab90" + ], + "version": "==3.46.0" + }, "certifi": { "hashes": [ "sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7", @@ -23,6 +37,39 @@ ], "version": "==2018.4.16" }, + "cffi": { + "hashes": [ + "sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743", + "sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef", + "sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50", + "sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f", + "sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93", + "sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257", + "sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3", + "sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc", + "sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04", + "sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6", + "sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359", + "sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596", + "sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b", + "sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd", + "sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95", + "sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e", + "sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6", + "sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca", + "sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31", + "sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1", + "sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085", + "sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801", + "sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4", + "sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184", + "sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917", + "sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f", + "sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb" + ], + "markers": "platform_python_implementation != 'pypy'", + "version": "==1.11.5" + }, "chardet": { "hashes": [ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", @@ -44,6 +91,28 @@ ], "version": "==0.0.4" }, + "cryptography": { + "hashes": [ + "sha256:3f3b65d5a16e6b52fba63dc860b62ca9832f51f1a2ae5083c78b6840275f12dd", + "sha256:551a3abfe0c8c6833df4192a63371aa2ff43afd8f570ed345d31f251d78e7e04", + "sha256:5cb990056b7cadcca26813311187ad751ea644712022a3976443691168781b6f", + "sha256:60bda7f12ecb828358be53095fc9c6edda7de8f1ef571f96c00b2363643fa3cd", + "sha256:6fef51ec447fe9f8351894024e94736862900d3a9aa2961528e602eb65c92bdb", + "sha256:77d0ad229d47a6e0272d00f6bf8ac06ce14715a9fd02c9a97f5a2869aab3ccb2", + "sha256:808fe471b1a6b777f026f7dc7bd9a4959da4bfab64972f2bbe91e22527c1c037", + "sha256:9b62fb4d18529c84b961efd9187fecbb48e89aa1a0f9f4161c61b7fc42a101bd", + "sha256:9e5bed45ec6b4f828866ac6a6bedf08388ffcfa68abe9e94b34bb40977aba531", + "sha256:9fc295bf69130a342e7a19a39d7bbeb15c0bcaabc7382ec33ef3b2b7d18d2f63", + "sha256:abd070b5849ed64e6d349199bef955ee0ad99aefbad792f0c587f8effa681a5e", + "sha256:ba6a774749b6e510cffc2fb98535f717e0e5fd91c7c99a61d223293df79ab351", + "sha256:c332118647f084c983c6a3e1dba0f3bcb051f69d12baccac68db8d62d177eb8a", + "sha256:d6f46e862ee36df81e6342c2177ba84e70f722d9dc9c6c394f9f1f434c4a5563", + "sha256:db6013746f73bf8edd9c3d1d3f94db635b9422f503db3fc5ef105233d4c011ab", + "sha256:f57008eaff597c69cf692c3518f6d4800f0309253bb138b526a37fe9ef0c7471", + "sha256:f6c821ac253c19f2ad4c8691633ae1d1a17f120d5b01ea1d256d7b602bc59887" + ], + "version": "==2.2.2" + }, "django": { "hashes": [ "sha256:3eb25c99df1523446ec2dc1b00e25eb2ecbdf42c9d8b0b8b32a204a8db9011f8", @@ -75,6 +144,13 @@ "index": "pypi", "version": "==1.2.0" }, + "django-payments": { + "hashes": [ + "sha256:e7811a574d249a6a74d589c8546a7dbbe4c4dc9f2378bd4a7dd42db73a69e7fd" + ], + "index": "pypi", + "version": "==0.12.3" + }, "django-rest-swagger": { "hashes": [ "sha256:48f6aded9937e90ae7cbe9e6c932b9744b8af80cc4e010088b3278c700e0685b", @@ -228,6 +304,12 @@ "index": "pypi", "version": "==5.1.0" }, + "pycparser": { + "hashes": [ + "sha256:99a8ca03e29851d96616ad0404b4aad7d9ee16f25c9f9708a11faf2810f7b226" + ], + "version": "==2.18" + }, "pyjwt": { "hashes": [ "sha256:30b1380ff43b55441283cc2b2676b755cca45693ae3097325dea01f3d110628c", @@ -288,6 +370,27 @@ ], "version": "==3.15.0" }, + "six": { + "hashes": [ + "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", + "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb" + ], + "version": "==1.11.0" + }, + "stripe": { + "hashes": [ + "sha256:9d0443d772d176faba8c8e8a2ddc3a507861dd7d882b4a88cf6062b20fa5f224", + "sha256:ebfde12d1575aa46ea6a0ade55d1e8caee5e343e3fb235ac07d8c59614ec4be0" + ], + "version": "==1.82.2" + }, + "suds-jurko": { + "hashes": [ + "sha256:1cb7252cb13018fc32887c3a834ed7c6648a5b5c4c159be5806da2e1785399e8", + "sha256:29edb72fd21e3044093d86f33c66cf847c5aaab26d64cb90e69e528ef014e57f" + ], + "version": "==0.6" + }, "uritemplate": { "hashes": [ "sha256:01c69f4fe8ed503b2951bef85d996a9d22434d2431584b5b107b2981ff416fbd", @@ -302,6 +405,13 @@ "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" ], "version": "==1.23" + }, + "xmltodict": { + "hashes": [ + "sha256:8f8d7d40aa28d83f4109a7e8aa86e67a4df202d9538be40c0cb1d70da527b0df", + "sha256:add07d92089ff611badec526912747cf87afd4f9447af6661aca074eeaf32615" + ], + "version": "==0.11.0" } }, "develop": { diff --git a/ydl_api/api/migrations/0005_auto_20180621_0005.py b/ydl_api/api/migrations/0005_auto_20180621_0005.py new file mode 100644 index 0000000..ff5e0c5 --- /dev/null +++ b/ydl_api/api/migrations/0005_auto_20180621_0005.py @@ -0,0 +1,58 @@ +# Generated by Django 2.0.6 on 2018-06-20 22:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0004_auto_20180620_1443'), + ] + + operations = [ + migrations.CreateModel( + name='Payment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('variant', models.CharField(max_length=255)), + ('status', models.CharField(choices=[('waiting', 'Waiting for confirmation'), ('preauth', 'Pre-authorized'), ('confirmed', 'Confirmed'), ('rejected', 'Rejected'), ('refunded', 'Refunded'), ('error', 'Error'), ('input', 'Input')], default='waiting', max_length=10)), + ('fraud_status', models.CharField(choices=[('unknown', 'Unknown'), ('accept', 'Passed'), ('reject', 'Rejected'), ('review', 'Review')], default='unknown', max_length=10, verbose_name='fraud check')), + ('fraud_message', models.TextField(blank=True, default='')), + ('created', models.DateTimeField(auto_now_add=True)), + ('modified', models.DateTimeField(auto_now=True)), + ('transaction_id', models.CharField(blank=True, max_length=255)), + ('currency', models.CharField(max_length=10)), + ('total', models.DecimalField(decimal_places=2, default='0.0', max_digits=9)), + ('delivery', models.DecimalField(decimal_places=2, default='0.0', max_digits=9)), + ('tax', models.DecimalField(decimal_places=2, default='0.0', max_digits=9)), + ('description', models.TextField(blank=True, default='')), + ('billing_first_name', models.CharField(blank=True, max_length=256)), + ('billing_last_name', models.CharField(blank=True, max_length=256)), + ('billing_address_1', models.CharField(blank=True, max_length=256)), + ('billing_address_2', models.CharField(blank=True, max_length=256)), + ('billing_city', models.CharField(blank=True, max_length=256)), + ('billing_postcode', models.CharField(blank=True, max_length=256)), + ('billing_country_code', models.CharField(blank=True, max_length=2)), + ('billing_country_area', models.CharField(blank=True, max_length=256)), + ('billing_email', models.EmailField(blank=True, max_length=254)), + ('customer_ip_address', models.GenericIPAddressField(blank=True, null=True)), + ('extra_data', models.TextField(blank=True, default='')), + ('message', models.TextField(blank=True, default='')), + ('token', models.CharField(blank=True, default='', max_length=36)), + ('captured_amount', models.DecimalField(decimal_places=2, default='0.0', max_digits=9)), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='user', + name='credit', + field=models.DecimalField(decimal_places=2, default=0, max_digits=19), + ), + migrations.AlterField( + model_name='calendarentry', + name='date', + field=models.DateTimeField(), + ), + ] diff --git a/ydl_api/api/models.py b/ydl_api/api/models.py index 098de89..12a5894 100644 --- a/ydl_api/api/models.py +++ b/ydl_api/api/models.py @@ -1,6 +1,10 @@ from django.db import models from django.contrib.auth.models import AbstractUser from django.core.validators import MinValueValidator +from decimal import Decimal + +from payments import PurchasedItem +from payments.models import BasePayment class Language(models.Model): name = models.CharField(max_length=100) @@ -17,6 +21,7 @@ def upload_to(self, filename): isEmailActivated = models.BooleanField(default=False) profile_picture = models.ImageField(upload_to = upload_to, blank=True) languages = models.ForeignKey(Language, on_delete=models.CASCADE, blank=True, null=True) + credit = models.DecimalField(max_digits=19, decimal_places=2, default=0) def save(self, *args, **kwargs): super().save(*args, **kwargs) @@ -33,6 +38,7 @@ def __str__(self): class Student(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True) courses = models.ManyToManyField('Course', blank = True) + # paid_courses = models.ManyToManyField('Course', blank = True) def __str__(self): return str(self.user) @@ -41,7 +47,6 @@ class Meta: verbose_name = ('student') verbose_name_plural = ('students') - class Teacher(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True) @@ -67,7 +72,6 @@ class Meta: class Course(models.Model): name = models.CharField(max_length=100) description = models.CharField(max_length=512) - # students = models.ManyToManyField(Student) teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE) deadline = models.DateTimeField() student_count = models.IntegerField(validators=[MinValueValidator(0)], default=0) @@ -82,6 +86,8 @@ class Meta: verbose_name = ('course') verbose_name_plural = ('courses') +#class PaidCourse(models.Model): + class Announcement(models.Model): title = models.CharField(max_length=100) @@ -140,3 +146,16 @@ class Meta: def __str__(self): return self.matter + +class Payment(BasePayment): + + def get_failure_url(self): + return 'https://ydlearning.com/failure/' + + def get_success_url(self): + return 'https://ydlearning.com/success/' + + def get_purchased_items(self): + # you'll probably want to retrieve these from an associated order + yield PurchasedItem(name='The Hound of the Baskervilles', sku='BSKV', + quantity=9, price=Decimal(10), currency='USD') \ No newline at end of file diff --git a/ydl_api/api/serializers.py b/ydl_api/api/serializers.py index 5a0cc8a..d787bbc 100644 --- a/ydl_api/api/serializers.py +++ b/ydl_api/api/serializers.py @@ -12,7 +12,7 @@ from django.contrib.sites.shortcuts import get_current_site from django.utils.encoding import force_bytes, force_text from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode -from django.template.loader import render_to_string +from django.template.loader import render_to_string from django.core.mail import EmailMessage from rest_framework_jwt.settings import api_settings from django.conf import settings @@ -23,10 +23,11 @@ # Email Stuff E from django.utils import timezone - + jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER + class UserSerializer(serializers.ModelSerializer): # password = serializers.CharField(write_only=True) token = serializers.SerializerMethodField() @@ -52,18 +53,17 @@ def create(self, validated_data): html_template = get_template('api/verification_email.html') context = { - 'user':user.username, - 'link':'https://api.ydlearning.com/activate/{}/{}'.format(uid, token), - 'expires_in':str(settings.JWT_AUTH['JWT_EXPIRATION_DELTA']), + 'user': user.username, + 'link': 'https://api.ydlearning.com/activate/{}/{}'.format(uid, token), + 'expires_in': str(settings.JWT_AUTH['JWT_EXPIRATION_DELTA']), 'expires_time': ' hours', # change plural! - #'logo_img_link':"https://lh3.googleusercontent.com/PL8M-2OhoDITza8WOCdveAax9yQuXzaDakaJHcivO1ZjJg5D1u0eb9gzgx8VSLlfVT4vitIV2GIPkc8OfGJrR6rpko1U8JuV4CAZ2p-gvc4NhVUthlbaEz9HcKwY98UFiwN79pzu=s742-no", - 'email_sendto':user.email, + # 'logo_img_link':"", + 'email_sendto': user.email, 'ydl_context': "Context Text", - 'ydl_email':"admin@ydlearning.com", - 'ydl_url':"https://www.ydlearning.com", + 'ydl_email': "admin@ydlearning.com", + 'ydl_url': "https://www.ydlearning.com", 'ydl_url_github': "https://github.com/YoungAndDigitalLearning", 'ydl_url_impr': "https://www.ydlearning.com/sites/impressum.html", - #'ydl_url_prpol': "https://www.ydlearning.com/privacypolicy", } html = html_template.render(context) @@ -72,15 +72,15 @@ def create(self, validated_data): '[Y&D Learning] Please verify your email address.', '', # Content - # + # # Email send from - #'admin@ydlearning.com', + # 'admin@ydlearning.com', 'no-reply@ydlearning.com', # Email send to [user.email], # fail silently fail_silently=False, - html_message = html, + html_message=html, ) return user @@ -97,9 +97,10 @@ class Meta: class CourseSerializer(serializers.ModelSerializer): class Meta: model = Course - fields = "__all__" + fields = "__all__" + +# Nur für Get auf den User -# Nur für Get auf den User class LongUserSerializer(serializers.ModelSerializer): courses = serializers.SerializerMethodField() @@ -116,14 +117,14 @@ def update(self, instance, validated_data): context = { 'user': validated_data.get('username', instance.username), - 'link':'https://api.ydlearning.com/activate/{}/{}'.format(uid, token), - 'expires_in':str(settings.JWT_AUTH['JWT_EXPIRATION_DELTA']), + 'link': 'https://api.ydlearning.com/activate/{}/{}'.format(uid, token), + 'expires_in': str(settings.JWT_AUTH['JWT_EXPIRATION_DELTA']), 'expires_time': ' hours', # change plural! - #'logo_img_link':"https://lh3.googleusercontent.com/PL8M-2OhoDITza8WOCdveAax9yQuXzaDakaJHcivO1ZjJg5D1u0eb9gzgx8VSLlfVT4vitIV2GIPkc8OfGJrR6rpko1U8JuV4CAZ2p-gvc4NhVUthlbaEz9HcKwY98UFiwN79pzu=s742-no", + # 'logo_img_link':"", 'email_sendto': validated_data.get('email', instance.email), 'ydl_context': "Context Text", - 'ydl_email':"admin@ydlearning.com", - 'ydl_url':"https://www.ydlearning.com", + 'ydl_email': "admin@ydlearning.com", + 'ydl_url': "https://www.ydlearning.com", 'ydl_url_github': "https://github.com/YoungAndDigitalLearning", 'ydl_url_impr': "https://www.ydlearning.com/sites/impressum.html", } @@ -133,27 +134,29 @@ def update(self, instance, validated_data): '[Y&D Learning] Please verify your email address.', '', # Content - # + # # Email send from - #'admin@ydlearning.com', + # 'admin@ydlearning.com', 'no-reply@ydlearning.com', # Email send to [validated_data.get('email', instance.email)], # fail silently fail_silently=False, - html_message = html, + html_message=html, ) def get_courses(self, obj): if obj.is_teacher: return TeacherSerializer(obj.teacher).data["course_set"] - elif obj.is_student: - return StudentSerializer(obj.student ).data["courses"] + elif obj.is_student: + return StudentSerializer(obj.student).data["courses"] class Meta: model = User - fields = ["id", "username", "first_name", "last_name", "email", "last_login", "date_joined", "isEmailActivated", "courses", "is_teacher"] + fields = ["id", "username", "first_name", "last_name", "last_login", "date_joined", + "isEmailActivated", "courses", "is_teacher"] # "email", Debug (Dont show emails on website) + class StudentSerializer(serializers.ModelSerializer): @@ -171,7 +174,7 @@ class ResourceSerializer(serializers.ModelSerializer): content = serializers.SerializerMethodField() size = serializers.SerializerMethodField() - # only return content if effective date is now or already passed + # only return content if effective date is now or already passed def get_content(self, obj): if obj.effective_from >= timezone.now(): return self.context["request"].build_absolute_uri(obj.content.url) @@ -180,16 +183,17 @@ def get_content(self, obj): def get_size(self, obj): return obj.content.size - + html_template = get_template('api/verification_email.html') class Meta: model = Resource - fields = ["name", "uploaded", "effective_from", "uploader", "expires", "size", "content"] + fields = ["name", "uploaded", "effective_from", + "uploader", "expires", "size", "content"] class AnnouncementSerializer(serializers.ModelSerializer): - author = LongUserSerializer(many = False, read_only = True) + author = LongUserSerializer(many=False, read_only=True) class Meta: model = Announcement - fields = "__all__" \ No newline at end of file + fields = "__all__" diff --git a/ydl_api/api/templates/api/payment.html b/ydl_api/api/templates/api/payment.html new file mode 100644 index 0000000..3bf67ef --- /dev/null +++ b/ydl_api/api/templates/api/payment.html @@ -0,0 +1,7 @@ + +
+ {{ form.as_p }} +

+ +

+
\ No newline at end of file diff --git a/ydl_api/api/urls.py b/ydl_api/api/urls.py index 002439a..0973dad 100644 --- a/ydl_api/api/urls.py +++ b/ydl_api/api/urls.py @@ -2,6 +2,7 @@ from django.urls import path, include from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token, verify_jwt_token from rest_framework_swagger.views import get_swagger_view +from django.conf.urls import include, url from .views import CourseAPIView, ListCreateUserViewSet, activate, StudentListApiView, DetailUserAPIView, DetailCourseAPIView, \ ListCreateResourceAPIView, ListCreateAnnouncementAPIView, LimitListAnnouncementAPIView, render_email @@ -35,6 +36,7 @@ path('activate///', activate), path('resources/', ListCreateResourceAPIView.as_view()), path('announcements/', ListCreateAnnouncementAPIView.as_view()), # use ...announcements/?limit=... for limited An + path('payments/', include('payments.urls')), ] diff --git a/ydl_api/api/views.py b/ydl_api/api/views.py index 1c425e9..4c6d66e 100644 --- a/ydl_api/api/views.py +++ b/ydl_api/api/views.py @@ -21,6 +21,11 @@ from django.core.exceptions import ObjectDoesNotExist # Email Stuff E +# Payment +from django.shortcuts import get_object_or_404, redirect +from django.template.response import TemplateResponse +from payments import get_payment_model, RedirectNeeded + jwt_decode_handler = api_settings.JWT_DECODE_HANDLER def render_email(request): @@ -167,7 +172,6 @@ def get_queryset(self): permissions.AllowAny # Or users can't register ] - class LimitListAnnouncementAPIView(ListAPIView): model = Announcement serializer_class = AnnouncementSerializer @@ -175,3 +179,15 @@ class LimitListAnnouncementAPIView(ListAPIView): def get_queryset(self): print("Quarks", self.kwargs["limit"]) return Announcement.objects.all()[:self.kwargs["limit"]] + + + + +def payment_details(request, payment_id): + payment = get_object_or_404(get_payment_model(), id=payment_id) + try: + form = payment.get_form(data=request.POST or None) + except RedirectNeeded as redirect_to: + return redirect(str(redirect_to)) + return TemplateResponse(request, 'payment.html', + {'form': form, 'payment': payment}) \ No newline at end of file