From af5492c797c0b7d81b75d2f1211be674efca1c43 Mon Sep 17 00:00:00 2001 From: Sergey G Date: Mon, 15 Jan 2018 23:13:44 +0500 Subject: [PATCH] LIL-74 Added `paymentwall` --- apps/payment/__init__.py | 0 apps/payment/admin.py | 3 + apps/payment/apps.py | 6 ++ apps/payment/migrations/0001_initial.py | 25 ++++++++ apps/payment/migrations/__init__.py | 0 apps/payment/models.py | 15 +++++ apps/payment/tests.py | 3 + apps/payment/views.py | 76 +++++++++++++++++++++++++ project/settings.py | 1 + requirements.txt | 3 +- 10 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 apps/payment/__init__.py create mode 100644 apps/payment/admin.py create mode 100644 apps/payment/apps.py create mode 100644 apps/payment/migrations/0001_initial.py create mode 100644 apps/payment/migrations/__init__.py create mode 100644 apps/payment/models.py create mode 100644 apps/payment/tests.py create mode 100644 apps/payment/views.py diff --git a/apps/payment/__init__.py b/apps/payment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/payment/admin.py b/apps/payment/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/apps/payment/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps/payment/apps.py b/apps/payment/apps.py new file mode 100644 index 00000000..5c370a84 --- /dev/null +++ b/apps/payment/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class PaymentConfig(AppConfig): + name = 'apps.payment' + label = 'lilcity_payment' diff --git a/apps/payment/migrations/0001_initial.py b/apps/payment/migrations/0001_initial.py new file mode 100644 index 00000000..ad79ff6d --- /dev/null +++ b/apps/payment/migrations/0001_initial.py @@ -0,0 +1,25 @@ +# Generated by Django 2.0.1 on 2018-01-15 18:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Purchase', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('transaction_id', models.PositiveIntegerField()), + ('status', models.CharField(max_length=50)), + ('product_id', models.PositiveIntegerField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + ), + ] diff --git a/apps/payment/migrations/__init__.py b/apps/payment/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/payment/models.py b/apps/payment/models.py new file mode 100644 index 00000000..1eaa1c6f --- /dev/null +++ b/apps/payment/models.py @@ -0,0 +1,15 @@ +from django.db import models + + +class Purchase(models.Model): + COMPLETE = 'COMPLETE' + CHARGEBACK = 'CHARGEBACK' + REFUNDED = 'REFUNDED' + ERROR = 'ERROR' + PENDING = 'PENDING' + + transaction_id = models.PositiveIntegerField() + status = models.CharField(max_length=50) + product_id = models.PositiveIntegerField() + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) diff --git a/apps/payment/tests.py b/apps/payment/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/apps/payment/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/payment/views.py b/apps/payment/views.py new file mode 100644 index 00000000..b1c64c7e --- /dev/null +++ b/apps/payment/views.py @@ -0,0 +1,76 @@ +from django.utils.decorators import method_decorator +from django.views.generic import View +from django.views.decorators.csrf import csrf_exempt +from django.http import HttpResponse + +from paymentwall.pingback import Pingback + +from .models import Purchase + + +@method_decorator(csrf_exempt, name='dispatch') +class PaymentwallCallbackView(View): + + CHARGEBACK = '1' + CREDIT_CARD_FRAUD = '2' + ORDER_FRAUD = '3' + BAD_DATA = '4' + FAKE_PROXY_USER = '5' + REJECTED_BY_ADVERTISER = '6' + DUPLICATED_CONVERSIONS = '7' + GOODWILL_CREDIT_TAKEN_BACK = '8' + CANCELLED_ORDER = '9' + PARTIALLY_REVERSED = '10' + + def get_request_ip(self): + x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR') + if x_forwarded_for: + ip = x_forwarded_for.split(',')[0] + else: + ip = self.request.META.get('REMOTE_ADDR') + return ip + + def get(self, request, *args, **kwargs): + pingback = Pingback(request.GET.copy(), self.get_request_ip()) + + if pingback.validate(): + cart_id = pingback.get_product().get_id() + + # try: + # cart = CartModel.objects.get(pk=cart_id) + # except CartModel.DoesNotExist: + # log.error('Paymentwall pingback: Cant find cart, Paymentwall sent this data: {}'.format(request.GET.copy())) + # return HttpResponse(status=403) + + try: + purchase = Purchase.objects.get(transaction_id=pingback.get_reference_id()) + except Purchase.DoesNotExist: + # purchase = cart.create_purchase(transaction_id=pingback.get_reference_id()) + pass + + if pingback.is_deliverable(): + purchase.status = Purchase.COMPLETE + + elif pingback.is_cancelable(): + reason = pingback.get_parameter('reason') + + if reason == self.CHARGEBACK or reason == self.CREDIT_CARD_FRAUD or reason == self.ORDER_FRAUD or reason == self.PARTIALLY_REVERSED: + purchase.status = Purchase.CHARGEBACK + elif reason == self.CANCELLED_ORDER: + purchase.status = Purchase.REFUNDED + else: + purchase.status = Purchase.ERROR + + elif pingback.is_under_review(): + purchase.status = Purchase.PENDING + + else: + # log.error('Paymentwall pingback: Unknown pingback type, Paymentwall sent this data: {}'.format(request.GET.copy())) + pass + + # purchase.save() + return HttpResponse('OK', status=200) + else: + # log.error('Paymentwall pingback: Cant validate pingback, error: {} Paymentwall sent this data: {}'.format(pingback.get_error_summary(), request.GET.copy())) + pass + diff --git a/project/settings.py b/project/settings.py index 821b4d8f..60a345a9 100644 --- a/project/settings.py +++ b/project/settings.py @@ -43,6 +43,7 @@ INSTALLED_APPS = [ 'apps.auth.apps', 'apps.user', 'apps.notification', + 'apps.payment', ] MIDDLEWARE = [ diff --git a/requirements.txt b/requirements.txt index 686dab1f..cf6e2289 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ Django==2.0.1 -django-anymail[mailgun]==1.2 \ No newline at end of file +django-anymail[mailgun]==1.2 +paymentwall-python==1.0.7 \ No newline at end of file