parent
b828933d64
commit
af5492c797
10 changed files with 131 additions and 1 deletions
@ -0,0 +1,3 @@ |
|||||||
|
from django.contrib import admin |
||||||
|
|
||||||
|
# Register your models here. |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
from django.apps import AppConfig |
||||||
|
|
||||||
|
|
||||||
|
class PaymentConfig(AppConfig): |
||||||
|
name = 'apps.payment' |
||||||
|
label = 'lilcity_payment' |
||||||
@ -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)), |
||||||
|
], |
||||||
|
), |
||||||
|
] |
||||||
@ -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) |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
from django.test import TestCase |
||||||
|
|
||||||
|
# Create your tests here. |
||||||
@ -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 |
||||||
|
|
||||||
@ -1,2 +1,3 @@ |
|||||||
Django==2.0.1 |
Django==2.0.1 |
||||||
django-anymail[mailgun]==1.2 |
django-anymail[mailgun]==1.2 |
||||||
|
paymentwall-python==1.0.7 |
||||||
Loading…
Reference in new issue