add: add payme api

This commit is contained in:
behruz-dev
2025-09-16 21:30:23 +05:00
parent 795eb7a5a9
commit 0252033586
7 changed files with 97 additions and 16 deletions

View File

@@ -25,6 +25,7 @@ INSTALLED_APPS = [
'rest_framework',
'rest_framework_simplejwt',
'corsheaders',
'payme',
# apps
'core.apps.accounts',
'core.apps.orders',
@@ -147,4 +148,13 @@ ALLOWED_ATMOS_IPS = []
CONSUMER_KEY = env.str('CONSUMER_KEY')
CONSUMER_SECRET = env.str('CONSUMER_SECRET')
STORE_ID = env.str('STORE_ID')
API_KEY = env.str('API_KEY')
API_KEY = env.str('API_KEY')
PAYME_ID = env.str('PAYME_ID')
PAYME_KEY = env.str('PAYME_KEY')
PAYME_ACCOUNT_FIELD = "order_number"
PAYME_AMOUNT_FIELD = "total_price"
PAYME_ACCOUNT_MODEL = "core.apps.orders.models.Order"
PAYME_ONE_TIME_PAYMENT = True
PAYME_ACCOUNT_FIELD_TYPE = "int"

View File

@@ -8,6 +8,8 @@ from rest_framework.permissions import IsAdminUser
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from core.apps.payment.views import PaymeCallBackAPIView
schema_view = get_schema_view(
openapi.Info(
@@ -34,7 +36,8 @@ urlpatterns = [
path('orders/', include('core.apps.orders.urls')),
path('payment/', include('core.apps.payment.urls')),
]
))
)),
path('payment/update/', PaymeCallBackAPIView.as_view()),
]

View File

@@ -2,7 +2,6 @@ from rest_framework import generics
from rest_framework.response import Response
from core.apps.common import models, serializers
from core.apps.payment.views import get_client_ip
class SiteConfigApiView(generics.GenericAPIView):

View File

@@ -20,4 +20,13 @@ class VisaPaymentSerializer(serializers.Serializer):
def validate_order_number(self, value):
if not Order.objects.filter(order_number=value).exists():
raise serializers.ValidationError("Order not found")
return value
return value
class PaymeSerializer(serializers.Serializer):
order_id = serializers.UUIDField()
def validate_order_id(self, value):
if not Order.objects.filter(id=value).exists():
raise serializers.ValidationError("order not found")
return value

View File

@@ -1,9 +1,10 @@
from django.urls import path
from .views import AtmosCallbackApiView, PaymentGenerateLinkApiView, VisaMastercardPaymentApiView
from .views import AtmosCallbackApiView, PaymentGenerateLinkApiView, VisaMastercardPaymentApiView, PayPaymeApiView
urlpatterns = [
path('callback/', AtmosCallbackApiView.as_view()),
path('payment/', PaymentGenerateLinkApiView.as_view()),
path('visa_mastercard/payment/', VisaMastercardPaymentApiView.as_view()),
path('payme/', PayPaymeApiView.as_view()),
]

View File

@@ -1,6 +1,9 @@
import hashlib
import uuid
from payme.views import PaymeWebHookAPIView, PaymeTransactions
from payme import Payme
from django.conf import settings
from rest_framework.generics import GenericAPIView
@@ -9,17 +12,18 @@ from rest_framework.response import Response
from rest_framework import status, permissions
from core.apps.orders.models import Order
from core.apps.payment.serializers import PaymentSerializer, VisaPaymentSerializer
from core.apps.payment.serializers import PaymentSerializer, VisaPaymentSerializer, PaymeSerializer
from core.services.payment import Atmos
payme = Payme(settings.PAYME_ID)
def get_client_ip(request):
x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
if x_forwarded_for:
ip = x_forwarded_for.split(",")[0]
else:
ip = request.META.get("REMOTE_ADDR")
return ip
# def get_client_ip(request):
# x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
# if x_forwarded_for:
# ip = x_forwarded_for.split(",")[0]
# else:
# ip = request.META.get("REMOTE_ADDR")
# return ip
class AtmosCallbackApiView(APIView):
@@ -27,7 +31,7 @@ class AtmosCallbackApiView(APIView):
permission_classes = []
def post(self, request):
client_ip = get_client_ip(request)
# client_ip = get_client_ip(request)
# if client_ip not in settings.ALLOWED_ATMOS_IPS:
# return Response({"status": 0, "message": "IP ruxsat etilmagan"}, status=403)
data = request.data
@@ -104,4 +108,58 @@ class VisaMastercardPaymentApiView(GenericAPIView):
request_id=str(uuid.uuid4()),
amount=data.get('amount'),
)
return Response({'success': True, 'link': res})
return Response({'success': True, 'link': res})
class PaymeCallBackAPIView(PaymeWebHookAPIView):
def handle_created_payment(self, params, result, *args, **kwargs):
"""
Handle the successful payment. You can override this method
"""
print(f"Transaction created for this params: {params} and cr_result: {result}")
def handle_successfully_payment(self, params, result, *args, **kwargs):
"""
Handle the successful payment. You can override this method
"""
transaction = PaymeTransactions.get_by_transaction_id(
transaction_id=params['id']
)
order = Order.objects.get(id=transaction.id)
order.is_paid = True
order.save()
print(f"Transaction successfully performed for this params: {params} and performed_result: {result}")
def handle_cancelled_payment(self, params, result, *args, **kwargs):
"""
Handle the cancelled payment. You can override this method
"""
transaction = PaymeTransactions.get_by_transaction_id(
transaction_id=params['id']
)
if transaction.state == PaymeTransactions.CANCELED:
order = Order.objects.get(id=transaction.id)
order.is_paid = False
order.save()
print(f"Transaction cancelled for this params: {params} and cancelled_result: {result}")
class PayPaymeApiView(GenericAPIView):
serializer_class = PaymeSerializer
permission_classes = [permissions.IsAuthenticated]
queryset = Order.objects.all()
def post(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
order_id = serializer.validated_data.get('order_id')
order = Order.objects.get(id=order_id)
payment_link = payme.initializer.generate_pay_link(
id=order_id,
amount=order.total_price * 100,
return_url="https://wisdom.uz",
)
return Response({'success': True, 'link': payment_link}, status=200)

View File

@@ -37,4 +37,5 @@ uritemplate==4.2.0
uvicorn==0.35.0
vine==5.1.0
wcwidth==0.2.13
requests
requests
payme-pkg