test pna views
This commit is contained in:
parent
3d6f9b6972
commit
effe16e468
5 changed files with 171 additions and 26 deletions
|
|
@ -0,0 +1,51 @@
|
|||
# Generated by Django 5.1.7 on 2025-05-13 16:08
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pg', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.OAUTH2_PROVIDER_APPLICATION_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='chargerequest',
|
||||
name='pna_order_id',
|
||||
field=models.IntegerField(blank=True, db_index=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='chargerequest',
|
||||
name='pna_originator',
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='chargerequest',
|
||||
name='pna_status',
|
||||
field=models.IntegerField(blank=True, choices=[(1, 'created'), (2, 'delayed'), (3, 'pending'), (4, 'incomplete'), (5, 'success'), (6, 'failed'), (7, 'expected_failure')], db_index=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='chargerequest',
|
||||
name='pna_status_code',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='chargerequest',
|
||||
name='pna_status_message',
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='chargerequest',
|
||||
name='pna_token',
|
||||
field=models.CharField(blank=True, db_index=True, max_length=255, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='chargerequest',
|
||||
name='application',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL),
|
||||
),
|
||||
]
|
||||
|
|
@ -9,6 +9,8 @@ import uuid
|
|||
from utils.wallet_client import deposit_to_user_wallet_submit, withdraw_from_user_wallet_verify, \
|
||||
deposit_to_user_wallet_verify
|
||||
|
||||
from utils.pna import PNAClient
|
||||
|
||||
|
||||
class ChargeRequest(BaseModel):
|
||||
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT,
|
||||
|
|
@ -19,6 +21,13 @@ class ChargeRequest(BaseModel):
|
|||
callback_url = models.URLField(null=True, blank=True)
|
||||
details = models.JSONField(null=True, blank=True, default=dict)
|
||||
|
||||
pna_token = models.CharField(null=True, blank=True, max_length=255, db_index=True)
|
||||
pna_order_id = models.IntegerField(null=True, blank=True, db_index=True)
|
||||
pna_originator = models.CharField(null=True, blank=True, max_length=255)
|
||||
pna_status = models.IntegerField(choices=StateChoices.choices, null=True, blank=True, db_index=True)
|
||||
pna_status_code = models.IntegerField(null=True, blank=True)
|
||||
pna_status_message = models.CharField(null=True, blank=True, max_length=255)
|
||||
|
||||
# TODO: complete and use this
|
||||
def change_state(self, from_state, to_state, error_message=None, **data):
|
||||
if self.state == from_state:
|
||||
|
|
@ -33,6 +42,32 @@ class ChargeRequest(BaseModel):
|
|||
else:
|
||||
raise Exception(error_message)
|
||||
|
||||
def request_sale(self):
|
||||
pna_client = PNAClient()
|
||||
description = 'from addwin ipg'
|
||||
pna_callback_url = f'https://ipg.addwin.ir/page/pna_callback/{self.pk}/'
|
||||
response = pna_client.request_normal_sale(self.amount, description, pna_callback_url, order_id=1)
|
||||
|
||||
self.pna_status_code = response['Status']
|
||||
self.pna_status_message = response.get('title')
|
||||
|
||||
if response['Status'] == 0:
|
||||
self.pna_token = response['Token']
|
||||
|
||||
self.save()
|
||||
|
||||
def get_pna_redirect_url(self):
|
||||
if self.pna_token:
|
||||
return PNAClient.pg_base_url.format(token=self.pna_token)
|
||||
|
||||
|
||||
def confirm_sale(self):
|
||||
pna_client = PNAClient()
|
||||
description = 'from addwin ipg'
|
||||
response = pna_client.request_normal_sale_confirm(self.pna_token)
|
||||
if response['Status'] == 0:
|
||||
self.pna_status = StateChoices.SUCCESS.value
|
||||
|
||||
def charge_wallet_balance(self):
|
||||
if self.state in [StateChoices.CREATED]:
|
||||
to_pending = ChargeRequest.objects.filter(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
from django.urls import path, include
|
||||
from .views import ChargeRequestView, ChargeRequestCreateApiView
|
||||
from .views import ChargeRequestView, ChargeRequestCreateApiView, ChargeConfirmView
|
||||
|
||||
app_name = "pg"
|
||||
|
||||
urlpatterns = [
|
||||
path('page/charge/<pk>/', ChargeRequestView.as_view(), name='charge-request-view'),
|
||||
path('page/charge/<uuid>/', ChargeRequestView.as_view(), name='charge-request-view'),
|
||||
path('page/pna_callback/<uuid>/', ChargeConfirmView.as_view(), name='charge-confirm-view'),
|
||||
path('api/charge_create/', ChargeRequestCreateApiView.as_view(), name='charge-request-create-api-view'),
|
||||
]
|
||||
|
|
|
|||
100
apps/pg/views.py
100
apps/pg/views.py
|
|
@ -4,7 +4,7 @@ from django.http import HttpResponseRedirect
|
|||
from django.shortcuts import render
|
||||
from django.urls import reverse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.generic import UpdateView
|
||||
from django.views.generic import UpdateView, DetailView
|
||||
from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticatedOrTokenHasScope
|
||||
from rest_framework import generics
|
||||
from rest_framework.views import APIView
|
||||
|
|
@ -34,6 +34,9 @@ class ChargeRequestCreateApiView(generics.CreateAPIView):
|
|||
class ChargeRequestView(UpdateView):
|
||||
template_name = 'pg/charge-request.html'
|
||||
form_class = ChargeRequestForm
|
||||
# pk_url_kwarg = 'uuid'
|
||||
slug_field = 'uuid'
|
||||
slug_url_kwarg = 'uuid'
|
||||
|
||||
def get_queryset(self):
|
||||
return ChargeRequest.objects.all()
|
||||
|
|
@ -42,28 +45,83 @@ class ChargeRequestView(UpdateView):
|
|||
def form_valid(self, form):
|
||||
self.object = form.save()
|
||||
charge_request: ChargeRequest = self.get_object()
|
||||
try:
|
||||
charge_request.charge_wallet_balance()
|
||||
# transaction = Transaction.objects.create(
|
||||
# uuid=charge.uuid,
|
||||
# payee_id=charge.user.pk,
|
||||
# payee_type=1,
|
||||
# payer_id=payer_pk,
|
||||
# payer_type=2,
|
||||
# amount=amount,
|
||||
# details={'description': 'شارژ مجازی کیف پول'}
|
||||
# )
|
||||
# transaction.submit()
|
||||
# transaction.verify()
|
||||
# charge.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.SUCCESS.value)
|
||||
messages.success(self.request, 'شارژ انجام شد')
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
messages.error(self.request, 'خطایی رخ داده است')
|
||||
charge_request.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.EXPECTED_FAILURE.value)
|
||||
# try:
|
||||
charge_request.request_sale()
|
||||
return HttpResponseRedirect(get_pna_redirect_url)
|
||||
|
||||
return HttpResponseRedirect(self.get_success_url())
|
||||
charge_request.charge_wallet_balance()
|
||||
# transaction = Transaction.objects.create(
|
||||
# uuid=charge.uuid,
|
||||
# payee_id=charge.user.pk,
|
||||
# payee_type=1,
|
||||
# payer_id=payer_pk,
|
||||
# payer_type=2,
|
||||
# amount=amount,
|
||||
# details={'description': 'شارژ مجازی کیف پول'}
|
||||
# )
|
||||
# transaction.submit()
|
||||
# transaction.verify()
|
||||
# charge.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.SUCCESS.value)
|
||||
messages.success(self.request, 'شارژ انجام شد')
|
||||
|
||||
# except Exception as e:
|
||||
# print(e)
|
||||
# messages.error(self.request, 'خطایی رخ داده است')
|
||||
# charge_request.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.EXPECTED_FAILURE.value)
|
||||
#
|
||||
# return HttpResponseRedirect(self.get_success_url())
|
||||
|
||||
def get_success_url(self):
|
||||
return self.object.callback_url
|
||||
# return reverse('pg:charge-request-view', kwargs={'pk': self.object.pk})
|
||||
|
||||
|
||||
class ChargeConfirmView(UpdateView):
|
||||
template_name = 'pg/charge-request.html'
|
||||
form_class = ChargeRequestForm
|
||||
# pk_url_kwarg = 'uuid'
|
||||
slug_field = 'uuid'
|
||||
slug_url_kwarg = 'uuid'
|
||||
|
||||
def get_queryset(self):
|
||||
return ChargeRequest.objects.all()
|
||||
# return Charge.objects.filter(state__in=[StateChoices.CREATED.value, StateChoices.SUCCESS.value])
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
charge_request: ChargeRequest = self.get_object()
|
||||
charge_request.charge_wallet_balance()
|
||||
charge_request.confirm_sale()
|
||||
context = self.get_context_data(object=self.object)
|
||||
messages.success(self.request, 'شارژ انجام شد')
|
||||
|
||||
return self.render_to_response(context)
|
||||
|
||||
# def form_valid(self, form):
|
||||
# self.object = form.save()
|
||||
# charge_request: ChargeRequest = self.get_object()
|
||||
# try:
|
||||
#
|
||||
# # transaction = Transaction.objects.create(
|
||||
# # uuid=charge.uuid,
|
||||
# # payee_id=charge.user.pk,
|
||||
# # payee_type=1,
|
||||
# # payer_id=payer_pk,
|
||||
# # payer_type=2,
|
||||
# # amount=amount,
|
||||
# # details={'description': 'شارژ مجازی کیف پول'}
|
||||
# # )
|
||||
# # transaction.submit()
|
||||
# # transaction.verify()
|
||||
# # charge.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.SUCCESS.value)
|
||||
#
|
||||
# except Exception as e:
|
||||
# print(e)
|
||||
# messages.error(self.request, 'خطایی رخ داده است')
|
||||
# charge_request.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.EXPECTED_FAILURE.value)
|
||||
#
|
||||
# return HttpResponseRedirect(self.get_success_url())
|
||||
|
||||
def get_success_url(self):
|
||||
return self.object.callback_url
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ class PNAClient:
|
|||
|
||||
corporation_pin = settings.PNA_CORPORATION_PIN
|
||||
|
||||
def request_normal_sale(self, amount, phone_number, discription, callback_url, order_id: int):
|
||||
def request_normal_sale(self, amount, description, callback_url, order_id: int, phone_number):
|
||||
data = {
|
||||
"CorporationPin": self.corporation_pin,
|
||||
"Amount": amount,
|
||||
"OrderId": order_id,
|
||||
"CallBackUrl": callback_url,
|
||||
"AdditionalData": discription, # optional
|
||||
"Originator": phone_number, # optional
|
||||
"AdditionalData": description, # optional
|
||||
# "Originator": phone_number, # optional
|
||||
}
|
||||
|
||||
response = requests.post(self.normal_sale_request_url, json=data)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue