diff --git a/apps/core/models.py b/apps/core/models.py index aee706a..4afbf6f 100644 --- a/apps/core/models.py +++ b/apps/core/models.py @@ -24,7 +24,7 @@ class BasePGModel(models.Model): def make_request(self): pass - def confirm_request(self): + def confirm_request(self, request=None): pass def reverse_request(self): diff --git a/apps/pg/migrations/0005_fake.py b/apps/pg/migrations/0005_fake.py new file mode 100644 index 0000000..6fe31df --- /dev/null +++ b/apps/pg/migrations/0005_fake.py @@ -0,0 +1,26 @@ +# Generated by Django 5.1.4 on 2025-05-31 10:03 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pg', '0004_paymentrequest_phone_number_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='Fake', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True, db_index=True)), + ('updated_at', models.DateTimeField(auto_now=True, db_index=True)), + ('payment_request', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='pg.paymentrequest')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/apps/pg/models.py b/apps/pg/models.py index b8b1af2..46d89ab 100644 --- a/apps/pg/models.py +++ b/apps/pg/models.py @@ -2,6 +2,7 @@ import urllib.parse from mimetypes import guess_all_extensions from django.conf import settings +from django.contrib import messages from django.db import models from django.db.models import TextChoices from django.urls import reverse @@ -20,9 +21,10 @@ from django.utils.translation import gettext_lazy as _ class GatewayChoise(TextChoices): FAKE = "fake", _("fake") - PNA = 'pna' , _('pna') + PNA = 'pna', _('pna') +# TODO: use generic relation class PaymentRequest(models.Model): id = None uuid = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4, unique=True, db_index=True) @@ -42,23 +44,30 @@ class PaymentRequest(models.Model): updated_at = models.DateTimeField(auto_now=True, db_index=True) def get_gateway_tools(self): - if self.gateway == 'pna': - return self.pna + if self.gateway == GatewayChoise.PNA: + return PNA.objects.get(payment_request=self) + + if self.gateway == GatewayChoise.FAKE: + return Fake.objects.get(payment_request=self) + + def set_gateway(self, data): + + if 'fake' in data: + self.gateway = GatewayChoise.FAKE + fake = Fake.objects.create(payment_request=self) + fake.payment_request = self - def set_gateway(self, gateway): - self.gateway = gateway - if gateway == 'pna': + elif 'pna' in data: + self.gateway = GatewayChoise.PNA pna = PNA.objects.create(payment_request=self) pna.payment_request = self - if gateway == 'fake': - pass + else: + raise Exception('Unknown gateway') self.save() - - # TODO: complete and use this def change_state(self, from_state, to_state, error_message=None, **data): if self.state == from_state: @@ -132,7 +141,6 @@ class PaymentRequest(models.Model): return bool(to_pay_success) - class PNA(BasePGModel): payment_request = models.OneToOneField(PaymentRequest, on_delete=models.PROTECT, related_name='pna') @@ -145,7 +153,6 @@ class PNA(BasePGModel): pna_status_code = models.IntegerField(null=True, blank=True) pna_status_message = models.CharField(null=True, blank=True, max_length=255) - client = PNAClient() def make_request(self): @@ -166,20 +173,56 @@ class PNA(BasePGModel): self.save() - def get_redirect_url(self): + def get_pg_page_url(self): if self.pna_token: return self.client.pg_base_url.format(token=self.pna_token) - def confirm_request(self): - pna_token = self.pna_token - response = self.client.request_normal_sale_confirm(pna_token) - # response = {'status': 0, 'cardNumberMasked': '504172******9210', 'rrn': 511629210215, 'appToken': 4101434578524, 'token': 'NDEwMTQzNDU3ODUyNA=='} - self.details = response - if response['status'] == 0: - self.pna_status = StateChoices.SUCCESS.value - self.save() + def confirm_request(self, request=None): + print(dict(request.POST)) + post_dict = dict(request.POST) + if post_dict.get('status') in [0, '0', [0], ['0']]: + try: + + pna_token = self.pna_token + response = self.client.request_normal_sale_confirm(pna_token) + # response = {'status': 0, 'cardNumberMasked': '504172******9210', 'rrn': 511629210215, 'appToken': 4101434578524, 'token': 'NDEwMTQzNDU3ODUyNA=='} + + # post = + # post = + + self.details = response + if response['status'] == 0: + self.pna_status = StateChoices.SUCCESS.value + self.save() + + self.payment_request.charge_wallet_balance() + + messages.success(request, 'شارژ انجام شد') + + except Exception as e: + print(e) + messages.error(request, str(e)) + else: + print(request.POST) + messages.error(request, "نتیجه تراکنش از سمت درگاه دریافت نشد.") def reverse_request(self): raise NotImplementedError() +class Fake(BasePGModel): + payment_request = models.OneToOneField(PaymentRequest, on_delete=models.PROTECT, related_name='+') + + def make_request(self): + pass + + def get_pg_page_url(self): + return reverse('pg:payment-confirm-view', kwargs={'uuid': self.payment_request.uuid}) + + def confirm_request(self, request=None): + self.payment_request.charge_wallet_balance() + messages.success(request, 'شارژ انجام شد') + self.save() + + def reverse_request(self): + raise NotImplementedError() diff --git a/apps/pg/views.py b/apps/pg/views.py index 0092f54..71c61c2 100644 --- a/apps/pg/views.py +++ b/apps/pg/views.py @@ -48,22 +48,19 @@ class PaymentRequestView(UpdateView): self.object = form.save() charge_request: PaymentRequest = self.get_object() - if 'fake' in form.data: - print('fake') - - if 'pna' in form.data: - charge_request.set_gateway('pna') + charge_request.set_gateway(form.data) tool = charge_request.get_gateway_tools() - - # try: tool.make_request() - redirect_url = tool.get_redirect_url() + + redirect_url = tool.get_pg_page_url() + if redirect_url: return HttpResponseRedirect(redirect_url) else: messages.error(self.request, 'can not redirect to payment gateway') + messages.info(self.request, 'در پردازش صفحه خطایی وجود دارد.') # TODO: redirect to error page return HttpResponseRedirect(reverse('pg:payment-confirm-view', kwargs={'uuid': charge_request.uuid})) @@ -81,13 +78,15 @@ class PaymentConfirmView(UpdateView): # return Charge.objects.filter(state__in=[StateChoices.CREATED.value, StateChoices.SUCCESS.value]) def get(self, request, *args, **kwargs): + print('get') print(args) print(kwargs) self.object = self.get_object() - context = self.get_context_data() - messages.info(self.request, 'در پردازش صفحه خطایی وجود دارد.') + tool = self.object.get_gateway_tools() + tool.confirm_request(request) + context = self.get_context_data() return self.render_to_response(context) def post(self, request, *args, **kwargs): @@ -95,37 +94,17 @@ class PaymentConfirmView(UpdateView): print(request.POST) print(args) print(kwargs) - self.object = self.get_object() - - # post = if 'redirect-to-app' in request.POST: response = HttpResponse(status=302) response['Location'] = self.object.callback_url return response - else: - # post = - # post = - print(dict(request.POST)) - post_dict = dict(request.POST) - if post_dict.get('status') in [0, '0', [0], ['0']]: - try: - payment_request: PaymentRequest = self.get_object() - tool = payment_request.get_gateway_tools() - tool.confirm_request() - payment_request.charge_wallet_balance() - messages.success(self.request, 'شارژ انجام شد') - - except Exception as e: - print(e) - messages.error(self.request, str(e)) - else: - print(request.POST) - messages.error(self.request, "نتیجه تراکنش از سمت درگاه دریافت نشد.") - - context = self.get_context_data(object=self.object) - return self.render_to_response(context) + self.object = self.get_object() + tool = self.object.get_gateway_tools() + tool.confirm_request(request) + context = self.get_context_data(object=self.object) + return self.render_to_response(context) # def form_valid(self, form): diff --git a/templates/pg/payment-request.html b/templates/pg/payment-request.html index dc71e4e..3948d4a 100644 --- a/templates/pg/payment-request.html +++ b/templates/pg/payment-request.html @@ -26,9 +26,9 @@ -{# #} +