add visa/mastercard payment
This commit is contained in:
@@ -147,4 +147,8 @@ ALLOWED_ATMOS_IPS = []
|
|||||||
CONSUMER_KEY = env.str('CONSUMER_KEY')
|
CONSUMER_KEY = env.str('CONSUMER_KEY')
|
||||||
CONSUMER_SECRET = env.str('CONSUMER_SECRET')
|
CONSUMER_SECRET = env.str('CONSUMER_SECRET')
|
||||||
STORE_ID = env.str('STORE_ID')
|
STORE_ID = env.str('STORE_ID')
|
||||||
API_KEY = env.str('API_KEY')
|
API_KEY = env.str('API_KEY')
|
||||||
|
|
||||||
|
GLOBAL_CONSUMER_KEY = env.str('GLOBAL_CONSUMER_KEY')
|
||||||
|
GLOBAL_CONSUMER_SECRET = env.str('GLOBAL_CONSUMER_SECRET')
|
||||||
|
GLOBAL_STORE_ID = env.str('GLOBAL_STORE_ID')
|
||||||
@@ -7,6 +7,16 @@ class PaymentSerializer(serializers.Serializer):
|
|||||||
order_number = serializers.IntegerField()
|
order_number = serializers.IntegerField()
|
||||||
price = serializers.IntegerField()
|
price = serializers.IntegerField()
|
||||||
|
|
||||||
|
def validate_order_number(self, value):
|
||||||
|
if not Order.objects.filter(order_number=value).exists():
|
||||||
|
raise serializers.ValidationError("Order not found")
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class VisaPaymentSerializer(serializers.Serializer):
|
||||||
|
amount = serializers.IntegerField()
|
||||||
|
order_number = serializers.IntegerField()
|
||||||
|
|
||||||
def validate_order_number(self, value):
|
def validate_order_number(self, value):
|
||||||
if not Order.objects.filter(order_number=value).exists():
|
if not Order.objects.filter(order_number=value).exists():
|
||||||
raise serializers.ValidationError("Order not found")
|
raise serializers.ValidationError("Order not found")
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from .views import AtmosCallbackApiView, PaymentGenerateLinkApiView
|
from .views import AtmosCallbackApiView, PaymentGenerateLinkApiView, VisaMastercardPaymentApiView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('callback/', AtmosCallbackApiView.as_view()),
|
path('callback/', AtmosCallbackApiView.as_view()),
|
||||||
path('payment/', PaymentGenerateLinkApiView.as_view()),
|
path('payment/', PaymentGenerateLinkApiView.as_view()),
|
||||||
|
path('visa_mastercard/payment/', VisaMastercardPaymentApiView.as_view()),
|
||||||
]
|
]
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import uuid
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
@@ -11,7 +9,7 @@ from rest_framework.response import Response
|
|||||||
from rest_framework import status, permissions
|
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
|
from core.apps.payment.serializers import PaymentSerializer, VisaPaymentSerializer
|
||||||
from core.services.payment import Atmos
|
from core.services.payment import Atmos
|
||||||
|
|
||||||
|
|
||||||
@@ -44,15 +42,9 @@ class AtmosCallbackApiView(APIView):
|
|||||||
invoice = data.get("invoice")
|
invoice = data.get("invoice")
|
||||||
amount = data.get("amount")
|
amount = data.get("amount")
|
||||||
sign = data.get("sign")
|
sign = data.get("sign")
|
||||||
logger.info(f"Atmos yuborgan SIGN: {sign}")
|
|
||||||
print("Atmos yuborgan SIGN:", sign)
|
|
||||||
|
|
||||||
check_string = f"{store_id}{transaction_id}{invoice}{amount}{settings.API_KEY}"
|
check_string = f"{store_id}{transaction_id}{invoice}{amount}{settings.API_KEY}"
|
||||||
print(check_string)
|
|
||||||
generated_sign = hashlib.md5(check_string.encode()).hexdigest()
|
generated_sign = hashlib.md5(check_string.encode()).hexdigest()
|
||||||
logger.info(f"Biz generatsiya qilgan SIGN: {generated_sign}")
|
|
||||||
print("Biz generatsiya qilgan SIGN:", generated_sign)
|
|
||||||
|
|
||||||
|
|
||||||
if generated_sign != sign:
|
if generated_sign != sign:
|
||||||
return Response(
|
return Response(
|
||||||
@@ -68,12 +60,6 @@ class AtmosCallbackApiView(APIView):
|
|||||||
status=status.HTTP_200_OK
|
status=status.HTTP_200_OK
|
||||||
)
|
)
|
||||||
|
|
||||||
# if str(order.total_price) != str(amount):
|
|
||||||
# return Response(
|
|
||||||
# {"status": 0, "message": f"Инвойс с номером {invoice} отсутствует в системе"},
|
|
||||||
# status=status.HTTP_200_OK
|
|
||||||
# )
|
|
||||||
|
|
||||||
order.is_paid = True
|
order.is_paid = True
|
||||||
order.save()
|
order.save()
|
||||||
|
|
||||||
@@ -101,3 +87,21 @@ class PaymentGenerateLinkApiView(GenericAPIView):
|
|||||||
status=200
|
status=200
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VisaMastercardPaymentApiView(GenericAPIView):
|
||||||
|
queryset = None
|
||||||
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
serializer_class = VisaPaymentSerializer
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
serializer = self.serializer_class(data=request.data)
|
||||||
|
if not serializer.is_valid():
|
||||||
|
return Response({'success': False, 'message': serializer.errors}, status=400)
|
||||||
|
data = serializer.validated_data
|
||||||
|
service = Atmos()
|
||||||
|
res = service.global_payment(
|
||||||
|
account=data.get('order_number'),
|
||||||
|
request_id=str(uuid.uuid4()),
|
||||||
|
amount=data.get('amount'),
|
||||||
|
)
|
||||||
|
return Response(res)
|
||||||
@@ -9,7 +9,10 @@ class Atmos:
|
|||||||
self.consumer_secret = settings.CONSUMER_SECRET
|
self.consumer_secret = settings.CONSUMER_SECRET
|
||||||
self.terminal_id = terminal_id
|
self.terminal_id = terminal_id
|
||||||
self.store_id = settings.STORE_ID
|
self.store_id = settings.STORE_ID
|
||||||
|
self.global_consumer_key = settings.GLOBAL_CONSUMER_KEY
|
||||||
|
self.global_consumer_secret = settings.GLOBAL_CONSUMER_SECRET
|
||||||
|
self.global_store_id = settings.GLOBAL_STORE_ID
|
||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
credentials = f"{self.consumer_key}:{self.consumer_secret}"
|
credentials = f"{self.consumer_key}:{self.consumer_secret}"
|
||||||
encoded_credentials = base64.b64encode(credentials.encode()).decode()
|
encoded_credentials = base64.b64encode(credentials.encode()).decode()
|
||||||
@@ -46,4 +49,41 @@ class Atmos:
|
|||||||
url = f'http://test-checkout.pays.uz/invoice/get?storeId={self.store_id}&transactionId={transaction_id}&redirectLink={redirect_url}'
|
url = f'http://test-checkout.pays.uz/invoice/get?storeId={self.store_id}&transactionId={transaction_id}&redirectLink={redirect_url}'
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
|
||||||
|
# Visa/MasterCard
|
||||||
|
def login_global_payment(self):
|
||||||
|
credentials = f"{self.global_consumer_key}:{self.global_consumer_secret}"
|
||||||
|
encoded_credentials = base64.b64encode(credentials.encode()).decode()
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Basic {encoded_credentials}",
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"grant_type": "client_credentials"
|
||||||
|
}
|
||||||
|
url = 'https://apigw.atmos.uz/token'
|
||||||
|
res = requests.post(url, headers=headers, data=data)
|
||||||
|
return res.json()['access_token']
|
||||||
|
|
||||||
|
def global_payment(self, request_id, account, amount):
|
||||||
|
access = self.login_global_payment()
|
||||||
|
url = 'https://apigw.atmos.uz/checkout/invoice/create'
|
||||||
|
headers = {
|
||||||
|
'Authorization': f'Bearer {access}',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
data = {
|
||||||
|
"request_id": request_id,
|
||||||
|
"store_id": self.global_store_id,
|
||||||
|
"account": str(account),
|
||||||
|
"amount": amount * 100,
|
||||||
|
"success_url": "https://wisdom.uz",
|
||||||
|
}
|
||||||
|
|
||||||
|
res = requests.post(url=url, headers=headers, json=data)
|
||||||
|
if res.status_code == 200:
|
||||||
|
return res.json()
|
||||||
|
else:
|
||||||
|
return res.json()
|
||||||
Reference in New Issue
Block a user