add: add payment api

This commit is contained in:
behruz-dev
2025-08-28 14:50:00 +05:00
parent 2263de00a1
commit 2a2e2c9920
6 changed files with 58 additions and 23 deletions

View File

@@ -144,5 +144,6 @@ CSRF_TRUSTED_ORIGINS = [
] ]
ALLOWED_ATMOS_IPS = [] ALLOWED_ATMOS_IPS = []
CONSUMER_KEY = '' CONSUMER_KEY = env.str('CONSUMER_KEY')
CONSUMER_SECRET = '' CONSUMER_SECRET = env.str('CONSUMER_SECRET')
STORE_ID = env.str('STORE_ID')

View File

@@ -0,0 +1,8 @@
from rest_framework import serializers
class PaymentSerializer(serializers.Serializer):
order_number = serializers.IntegerField()
price = serializers.IntegerField()

View File

@@ -1,7 +1,8 @@
from django.urls import path from django.urls import path
from .views import AtmosCallbackApiView from .views import AtmosCallbackApiView, PaymentGenerateLinkApiView
urlpatterns = [ urlpatterns = [
path('callback/', AtmosCallbackApiView.as_view()), path('callback/', AtmosCallbackApiView.as_view()),
path('payment/', PaymentGenerateLinkApiView.as_view()),
] ]

View File

@@ -1,12 +1,15 @@
import hashlib import hashlib
from django.conf import settings from django.conf import settings
from rest_framework.generics import GenericAPIView
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status, permissions
from core.apps.orders.models import Order from core.apps.orders.models import Order
from core.apps.payment.serializers import PaymentSerializer
API_KEY = "ATMOS_API_KEY" from core.services.payment import Atmos
def get_client_ip(request): def get_client_ip(request):
@@ -24,8 +27,8 @@ class AtmosCallbackApiView(APIView):
def post(self, request): 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: # if client_ip not in settings.ALLOWED_ATMOS_IPS:
return Response({"status": 0, "message": "IP ruxsat etilmagan"}, status=403) # return Response({"status": 0, "message": "IP ruxsat etilmagan"}, status=403)
data = request.data data = request.data
if not data: if not data:
return Response( return Response(
@@ -39,7 +42,7 @@ class AtmosCallbackApiView(APIView):
amount = data.get("amount") amount = data.get("amount")
sign = data.get("sign") sign = data.get("sign")
check_string = f"{store_id}{transaction_id}{invoice}{amount}{API_KEY}" check_string = f"{store_id}{transaction_id}{invoice}{amount}{settings.CONSUMER_KEY}"
generated_sign = hashlib.sha256(check_string.encode()).hexdigest() generated_sign = hashlib.sha256(check_string.encode()).hexdigest()
if generated_sign != sign: if generated_sign != sign:
@@ -69,3 +72,19 @@ class AtmosCallbackApiView(APIView):
{"status": 1, "message": "Успешно"}, {"status": 1, "message": "Успешно"},
status=status.HTTP_200_OK status=status.HTTP_200_OK
) )
class PaymentGenerateLinkApiView(GenericAPIView):
serializer_class = PaymentSerializer
queryset = None
permission_classes = [permissions.IsAuthenticated]
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid()
data = serializer.validated_data
service = Atmos()
res = service.create_transaction(data['price'], data['order_number'])
print(res)
return Response(res)

View File

@@ -1,13 +1,14 @@
import requests import requests, base64
import base64
from django.conf import settings
class Atmos: class Atmos:
def __init__(self, consumer_key, consumer_secret, terminal_id, store_id): def __init__(self, terminal_id = None):
self.consumer_key = consumer_key self.consumer_key = settings.CONSUMER_KEY
self.consumer_secret = consumer_secret self.consumer_secret = settings.CONSUMER_SECRET
self.terminal_id = terminal_id self.terminal_id = terminal_id
self.store_id = store_id self.store_id = settings.STORE_ID
def login(self): def login(self):
credentials = f"{self.consumer_key}:{self.consumer_secret}" credentials = f"{self.consumer_key}:{self.consumer_secret}"
@@ -34,20 +35,24 @@ class Atmos:
url = 'https://apigw.atmos.uz/merchant/pay/create' url = 'https://apigw.atmos.uz/merchant/pay/create'
headers = { headers = {
'Authorization': f'Bearer {access_token}', 'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json',
} }
data = { data = {
'amount': amount, 'amount': amount,
'account': account, 'account': str(account),
'terminal_id': self.terminal_id,
'store_id': self.store_id 'store_id': self.store_id
} }
res = requests.post(url, headers=headers, data=data) res = requests.post(url, headers=headers, json=data)
if res.json()['result']['code'] == 'OK': print(self.store_id)
return res.json() return res.json()
else: # try:
return None # data = res.json()
# except Exception as e:
# raise ValueError(f"Invalid JSON response: {res.text}") from e
# if data.get('result', {}).get('code') == 'OK':
# return data
# return None
def generate_url(self, transaction_id, redirect_url): def generate_url(self, transaction_id, redirect_url):
url = f'https://test-checkout.pays.uz/invoice/get?storeId={self.store_id}&transactionId={transaction_id}&redirectLink={redirect_url}' url = f'https://test-checkout.pays.uz/invoice/get?storeId={self.store_id}&transactionId={transaction_id}&redirectLink={redirect_url}'

View File

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