fake gateway
This commit is contained in:
parent
a1e4fbcc52
commit
f0edf10f53
5 changed files with 108 additions and 60 deletions
|
|
@ -24,7 +24,7 @@ class BasePGModel(models.Model):
|
||||||
def make_request(self):
|
def make_request(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def confirm_request(self):
|
def confirm_request(self, request=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def reverse_request(self):
|
def reverse_request(self):
|
||||||
|
|
|
||||||
26
apps/pg/migrations/0005_fake.py
Normal file
26
apps/pg/migrations/0005_fake.py
Normal file
|
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -2,6 +2,7 @@ import urllib.parse
|
||||||
from mimetypes import guess_all_extensions
|
from mimetypes import guess_all_extensions
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib import messages
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import TextChoices
|
from django.db.models import TextChoices
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
@ -23,6 +24,7 @@ class GatewayChoise(TextChoices):
|
||||||
PNA = 'pna', _('pna')
|
PNA = 'pna', _('pna')
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: use generic relation
|
||||||
class PaymentRequest(models.Model):
|
class PaymentRequest(models.Model):
|
||||||
id = None
|
id = None
|
||||||
uuid = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4, unique=True, db_index=True)
|
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)
|
updated_at = models.DateTimeField(auto_now=True, db_index=True)
|
||||||
|
|
||||||
def get_gateway_tools(self):
|
def get_gateway_tools(self):
|
||||||
if self.gateway == 'pna':
|
if self.gateway == GatewayChoise.PNA:
|
||||||
return self.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):
|
elif 'pna' in data:
|
||||||
self.gateway = gateway
|
self.gateway = GatewayChoise.PNA
|
||||||
if gateway == 'pna':
|
|
||||||
pna = PNA.objects.create(payment_request=self)
|
pna = PNA.objects.create(payment_request=self)
|
||||||
pna.payment_request = self
|
pna.payment_request = self
|
||||||
|
|
||||||
if gateway == 'fake':
|
else:
|
||||||
pass
|
raise Exception('Unknown gateway')
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: complete and use this
|
# TODO: complete and use this
|
||||||
def change_state(self, from_state, to_state, error_message=None, **data):
|
def change_state(self, from_state, to_state, error_message=None, **data):
|
||||||
if self.state == from_state:
|
if self.state == from_state:
|
||||||
|
|
@ -132,7 +141,6 @@ class PaymentRequest(models.Model):
|
||||||
return bool(to_pay_success)
|
return bool(to_pay_success)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PNA(BasePGModel):
|
class PNA(BasePGModel):
|
||||||
payment_request = models.OneToOneField(PaymentRequest, on_delete=models.PROTECT, related_name='pna')
|
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_code = models.IntegerField(null=True, blank=True)
|
||||||
pna_status_message = models.CharField(null=True, blank=True, max_length=255)
|
pna_status_message = models.CharField(null=True, blank=True, max_length=255)
|
||||||
|
|
||||||
|
|
||||||
client = PNAClient()
|
client = PNAClient()
|
||||||
|
|
||||||
def make_request(self):
|
def make_request(self):
|
||||||
|
|
@ -166,20 +173,56 @@ class PNA(BasePGModel):
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def get_redirect_url(self):
|
def get_pg_page_url(self):
|
||||||
if self.pna_token:
|
if self.pna_token:
|
||||||
return self.client.pg_base_url.format(token=self.pna_token)
|
return self.client.pg_base_url.format(token=self.pna_token)
|
||||||
|
|
||||||
def confirm_request(self):
|
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
|
pna_token = self.pna_token
|
||||||
response = self.client.request_normal_sale_confirm(pna_token)
|
response = self.client.request_normal_sale_confirm(pna_token)
|
||||||
# response = {'status': 0, 'cardNumberMasked': '504172******9210', 'rrn': 511629210215, 'appToken': 4101434578524, 'token': 'NDEwMTQzNDU3ODUyNA=='}
|
# response = {'status': 0, 'cardNumberMasked': '504172******9210', 'rrn': 511629210215, 'appToken': 4101434578524, 'token': 'NDEwMTQzNDU3ODUyNA=='}
|
||||||
|
|
||||||
|
# post = <QueryDict: {'Token': ['NDEwMTI0Nzc0MDMzMA=='], 'OrderId': ['7'], 'TerminalNo': ['31127029'], 'RRN': ['511629156251'], 'status': ['0'], 'TspToken': ['00000000-0000-0000-0000-000000000000'], 'HashCardNumber': ['6008617E6BAB76997499446356F5C8B60288445650DD551FDF32007BCF2B14AF'], 'Amount': ['21,000'], 'SwAmount': [''], 'STraceNo': ['123232']}>
|
||||||
|
# post = <QueryDict: {'Token': ['NDI2MDY3ODI0MTg1OA=='], 'OrderId': ['47'], 'status': ['-138']}>
|
||||||
|
|
||||||
self.details = response
|
self.details = response
|
||||||
if response['status'] == 0:
|
if response['status'] == 0:
|
||||||
self.pna_status = StateChoices.SUCCESS.value
|
self.pna_status = StateChoices.SUCCESS.value
|
||||||
self.save()
|
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):
|
def reverse_request(self):
|
||||||
raise NotImplementedError()
|
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()
|
||||||
|
|
|
||||||
|
|
@ -48,22 +48,19 @@ class PaymentRequestView(UpdateView):
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
charge_request: PaymentRequest = self.get_object()
|
charge_request: PaymentRequest = self.get_object()
|
||||||
|
|
||||||
if 'fake' in form.data:
|
charge_request.set_gateway(form.data)
|
||||||
print('fake')
|
|
||||||
|
|
||||||
if 'pna' in form.data:
|
|
||||||
charge_request.set_gateway('pna')
|
|
||||||
|
|
||||||
tool = charge_request.get_gateway_tools()
|
tool = charge_request.get_gateway_tools()
|
||||||
|
|
||||||
|
|
||||||
# try:
|
|
||||||
tool.make_request()
|
tool.make_request()
|
||||||
redirect_url = tool.get_redirect_url()
|
|
||||||
|
redirect_url = tool.get_pg_page_url()
|
||||||
|
|
||||||
if redirect_url:
|
if redirect_url:
|
||||||
return HttpResponseRedirect(redirect_url)
|
return HttpResponseRedirect(redirect_url)
|
||||||
else:
|
else:
|
||||||
messages.error(self.request, 'can not redirect to payment gateway')
|
messages.error(self.request, 'can not redirect to payment gateway')
|
||||||
|
messages.info(self.request, 'در پردازش صفحه خطایی وجود دارد.')
|
||||||
# TODO: redirect to error page
|
# TODO: redirect to error page
|
||||||
return HttpResponseRedirect(reverse('pg:payment-confirm-view', kwargs={'uuid': charge_request.uuid}))
|
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])
|
# return Charge.objects.filter(state__in=[StateChoices.CREATED.value, StateChoices.SUCCESS.value])
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
|
||||||
print('get')
|
print('get')
|
||||||
print(args)
|
print(args)
|
||||||
print(kwargs)
|
print(kwargs)
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
context = self.get_context_data()
|
tool = self.object.get_gateway_tools()
|
||||||
messages.info(self.request, 'در پردازش صفحه خطایی وجود دارد.')
|
tool.confirm_request(request)
|
||||||
|
|
||||||
|
context = self.get_context_data()
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
|
@ -95,35 +94,15 @@ class PaymentConfirmView(UpdateView):
|
||||||
print(request.POST)
|
print(request.POST)
|
||||||
print(args)
|
print(args)
|
||||||
print(kwargs)
|
print(kwargs)
|
||||||
self.object = self.get_object()
|
|
||||||
|
|
||||||
# post = <QueryDict: {'Token': ['NDEwMTI0Nzc0MDMzMA=='], 'OrderId': ['7'], 'TerminalNo': ['31127029'], 'RRN': ['511629156251'], 'status': ['0'], 'TspToken': ['00000000-0000-0000-0000-000000000000'], 'HashCardNumber': ['6008617E6BAB76997499446356F5C8B60288445650DD551FDF32007BCF2B14AF'], 'Amount': ['21,000'], 'SwAmount': [''], 'STraceNo': ['123232']}>
|
|
||||||
|
|
||||||
if 'redirect-to-app' in request.POST:
|
if 'redirect-to-app' in request.POST:
|
||||||
response = HttpResponse(status=302)
|
response = HttpResponse(status=302)
|
||||||
response['Location'] = self.object.callback_url
|
response['Location'] = self.object.callback_url
|
||||||
return response
|
return response
|
||||||
|
|
||||||
else:
|
self.object = self.get_object()
|
||||||
# post = <QueryDict: {'Token': ['NDEwMTI0Nzc0MDMzMA=='], 'OrderId': ['7'], 'TerminalNo': ['31127029'], 'RRN': ['511629156251'], 'status': ['0'], 'TspToken': ['00000000-0000-0000-0000-000000000000'], 'HashCardNumber': ['6008617E6BAB76997499446356F5C8B60288445650DD551FDF32007BCF2B14AF'], 'Amount': ['21,000'], 'SwAmount': [''], 'STraceNo': ['123232']}>
|
tool = self.object.get_gateway_tools()
|
||||||
# post = <QueryDict: {'Token': ['NDI2MDY3ODI0MTg1OA=='], 'OrderId': ['47'], 'status': ['-138']}>
|
tool.confirm_request(request)
|
||||||
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)
|
context = self.get_context_data(object=self.object)
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@
|
||||||
<button type="submit" class="btn mx-auto center-block" name="pna">
|
<button type="submit" class="btn mx-auto center-block" name="pna">
|
||||||
<img class="img-thumbnail" width="128" height="128" src="{% static "image/pna.png" %}"/>
|
<img class="img-thumbnail" width="128" height="128" src="{% static "image/pna.png" %}"/>
|
||||||
</button>
|
</button>
|
||||||
{# <button type="submit" class="btn mx-auto center-block" name="fake">#}
|
<button type="submit" class="btn mx-auto center-block" name="fake">
|
||||||
{# <img class="img-thumbnail" width="128" height="128" src="{% static "image/fake.png" %}"/>#}
|
<img class="img-thumbnail" width="128" height="128" src="{% static "image/fake.png" %}"/>
|
||||||
{# </button>#}
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue