Skip to main content

Django Integratsiyasi

Django ilovalariga PayTechUZ ni integratsiya qilish bo'yicha to'liq qo'llanma.

Tayyor misol loyihalar

Tayyor Django loyihalari kerakmi? Bizda turli to'lov stsenariylari uchun keng qamrovli misollar mavjud:

  • 🛒 Shop misoli - Buyurtmalar asosidagi to'lovlar bilan to'liq elektron tijorat integratsiyasi (Payme, Click). Onlayn do'konlar va bozorlar uchun ideal.

  • 🚕 Taxi misoli - Payme, Click, Uzum, va Paynet yordamida hamyon balansini to'ldirishning to'liq implementatsiyasi. Xizmat ilovalar, taksi xizmatlari va balansga asoslangan tizimlar uchun mos.

Ikkala misol ham to'liq Django sozlamasi, webhook handlerlari va ishlab chiqarish uchun tayyor kod bilan birga keladi!

O'rnatish

PayTechUZ ni Django qo'llab-quvvatlashi bilan o'rnating:

pip install paytechuz[django]

Django Sozlamalari

Django sozlamalariga PayTechUZ konfiguratsiyasini qo'shing:

note

Sizga kerak bo'lmagan to'lov provayderlarining konfiguratsiyasini o'chirib yuborishingiz mumkin. Faqat loyihangizda foydalanmoqchi bo'lgan provayderlarni sozlang.

# settings.py

INSTALLED_APPS = [
# ...
'paytechuz.integrations.django',
]

PAYTECHUZ = {
'PAYME': {
'PAYME_ID': 'your_payme_id',
'PAYME_KEY': 'your_payme_key',
'ACCOUNT_MODEL': 'payment.models.Invoice', # Your invoice model
'ACCOUNT_FIELD': 'id',
'AMOUNT_FIELD': 'amount',
'ONE_TIME_PAYMENT': True,
'IS_TEST_MODE': True, # Set to False in production
},
'CLICK': {
'SERVICE_ID': 'your_service_id',
'MERCHANT_ID': 'your_merchant_id',
'MERCHANT_USER_ID': 'your_merchant_user_id',
'SECRET_KEY': 'your_secret_key',
'ACCOUNT_MODEL': 'payment.models.Invoice',
'ACCOUNT_FIELD': 'id',
'COMMISSION_PERCENT': 0.0,
'ONE_TIME_PAYMENT': True,
'IS_TEST_MODE': True, # Set to False in production
},
'UZUM': {
'SERVICE_ID': 'your_service_id', # Biller URL uchun Uzum Service ID
'USERNAME': 'your_uzum_username', # Webhook Basic Auth uchun
'PASSWORD': 'your_uzum_password', # Webhook Basic Auth uchun
'ACCOUNT_MODEL': 'payment.models.Invoice',
'ACCOUNT_FIELD': 'id', # yoki 'order_id'
'AMOUNT_FIELD': 'amount',
'ONE_TIME_PAYMENT': True, # Set to False if you want to allow multiple payments for the same invoice
'IS_TEST_MODE': True, # Production da False qilib belgilang
},
'PAYNET': {
'SERVICE_ID': 'your_paynet_service_id',
'USERNAME': 'your_paynet_username',
'PASSWORD': 'your_paynet_password',
'ACCOUNT_MODEL': 'payment.models.Invoice',
'ACCOUNT_FIELD': 'id',
'AMOUNT_FIELD': 'amount',
'ONE_TIME_PAYMENT': True,
'IS_TEST_MODE': True,
}
}

Buyurtmalar va to'lovlarni boshqarish uchun modellar yarating:

# shop/models.py
from django.db import models
from django.contrib.auth.models import User

class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
product_name = models.CharField(max_length=255)
total_amount = models.DecimalField(max_digits=12, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return f"Order {self.id} - {self.product_name}"

# payment/models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from shop.models import Order # Import Order from shop app

class Invoice(models.Model):
STATUS_CHOICES = (
('pending', 'Pending'),
('paid', 'Paid'),
('cancelled', 'Cancelled'),
)

user = models.ForeignKey(User, on_delete=models.CASCADE)
order = models.ForeignKey(Order, on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=12, decimal_places=2)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
created_at = models.DateTimeField(default=timezone.now)

def __str__(self):
return f"Invoice {self.id} for Order {self.order.id}"

Ko'rinishlar (Views)

To'lovlarni boshqarish uchun ko'rinishlar yarating:

note

Faqat foydalanayotgan to'lov provayderlaringiz uchun webhook ko'rinishlarini yaratishingiz kerak. Kerak bo'lmagan provayderlar uchun importlar va klasslarni o'chirib tashlang.

# payment/views.py
from paytechuz.integrations.django.views import (
BasePaymeWebhookView,
BaseClickWebhookView,
BaseUzumWebhookView,
BasePaynetWebhookView
)

from payment.models import Invoice
from shop.models import Order

class PaymeWebhookView(BasePaymeWebhookView):
def successfully_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'paid'
invoice.save()

def cancelled_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'cancelled'
invoice.save()

def get_check_data(self, params, account): # optional
"""
Return additional data for CheckPerformTransaction (fiscal receipt)

You can override this method to return additional data for fiscal receipt
"""
return {
"additional": {"first_name": account.user.first_name}, # optional
"detail": { # optional
"receipt_type": 0,
"shipping": {"title": "Yetkazib berish", "price": 10000},
"items": [
{
"discount": 0,
"title": account.product_name,
"price": account.amount,
"count": 1,
"code": "00001",
"units": 1,
"vat_percent": 0,
"package_code": "123456"
}
]
}
}

class ClickWebhookView(BaseClickWebhookView):
def successfully_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'paid'
invoice.save()

def cancelled_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'cancelled'
invoice.save()

def successfully_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'paid'
invoice.save()

def cancelled_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'cancelled'
invoice.save()

class UzumWebhookView(BaseUzumWebhookView):
def successfully_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'paid'
invoice.save()

def cancelled_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'cancelled'
invoice.save()

class PaynetWebhookView(BasePaynetWebhookView):
def successfully_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'paid'
invoice.save()

def cancelled_payment(self, params, transaction):
invoice = Invoice.objects.get(id=transaction.account_id)
invoice.status = 'cancelled'
invoice.save()

def get_check_data(self, params, account): # ixtiyoriy
# GetInformation uchun qo'shimcha ma'lumotlarni qaytarish
# Istalgan kalit-qiymat juftliklaridan foydalanishingiz mumkin
return {
"fields": {
"first_name": account.user.first_name,
"balance": 0 # account.user.balance
}
}

URL Yo'nalishlari

URL yo'nalishlarini sozlang:

note

Faqat foydalanayotgan to'lov provayderlaringiz uchun URL yo'nalishlarini qo'shing. Kerak bo'lmagan provayderlar uchun importlar va pathlarni o'chirib tashlang.

# urls.py
from django.urls import path
from payment.views import PaymeWebhookView, ClickWebhookView, UzumWebhookView, PaynetWebhookView
from shop.views import OrderCreateView

urlpatterns = [
# ...
path('webhooks/payme/', PaymeWebhookView.as_view(), name='payme_webhook'),
path('webhooks/click/', ClickWebhookView.as_view(), name='click_webhook'),
path('webhooks/uzum/<str:action>/', UzumWebhookView.as_view(), name='uzum_webhook'),
path('webhooks/paynet/', PaynetWebhookView.as_view(), name='paynet_webhook'),

# Order creation endpoint
path('order/create/', OrderCreateView.as_view(), name='order_create'),
]

To'lov Havolalarini Yaratish

Quyida Django Rest Framework (DRF) ko'rinishi misoli keltirilgan, u buyurtma yaratishni boshqaradi va tanlangan to'lov provayderi asosida to'lov havolasini generatsiya qiladi (serializerlardan foydalanmasdan):

note

Mantiqni faqat siz qo'llab-quvvatlamoqchi bo'lgan to'lov tizimlarini o'z ichiga oladigan qilib o'zgartiring. Foydalanilmayotgan tizimlar uchun importlar va elif bloklarini olib tashlang.

# shop/views.py
from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from paytechuz.gateways.payme import PaymeGateway
from paytechuz.gateways.click import ClickGateway
from payment.models import Invoice

class OrderCreateView(APIView):
def post(self, request):
data = request.data
product_name = data.get('product_name')
amount = data.get('amount')
payment_type = data.get('payment_type') # 'payme', 'click', 'uzum', 'paynet'

if not all([product_name, amount, payment_type]):
return Response(
{'error': 'product_name, amount, and payment_type are required.'},
status=status.HTTP_400_BAD_REQUEST
)

# 1. Create Order
order = Order.objects.create(
user=request.user,
product_name=product_name,
total_amount=amount
)

# 2. Create Invoice linked to the Order
invoice = Invoice.objects.create(
user=request.user,
order=order,
amount=amount,
status='pending'
)

payment_url = None

# 3. Generate Payment Link based on payment_type
if payment_type == 'payme':
gateway = PaymeGateway(
payme_id=settings.PAYTECHUZ['PAYME']['PAYME_ID'],
payme_key=settings.PAYTECHUZ['PAYME']['PAYME_KEY'],
is_test_mode=settings.PAYTECHUZ['PAYME']['IS_TEST_MODE']
)
payment_url = gateway.create_payment(
id=invoice.id,
amount=invoice.amount,
return_url="https://example.com/success",
account_field_name=settings.PAYTECHUZ['PAYME']['ACCOUNT_FIELD']
)

elif payment_type == 'click':
gateway = ClickGateway(
service_id=settings.PAYTECHUZ['CLICK']['SERVICE_ID'],
merchant_id=settings.PAYTECHUZ['CLICK']['MERCHANT_ID'],
merchant_user_id=settings.PAYTECHUZ['CLICK']['MERCHANT_USER_ID'],
secret_key=settings.PAYTECHUZ['CLICK']['SECRET_KEY'],
is_test_mode=settings.PAYTECHUZ['CLICK']['IS_TEST_MODE']
)
payment_url = gateway.create_payment(
id=invoice.id,
amount=invoice.amount,
return_url="https://example.com/success"
)

payment_url = gateway.create_payment(
account_id=invoice.id,
amount=invoice.amount,
)

elif payment_type == 'uzum':
gateway = UzumGateway(
service_id=settings.PAYTECHUZ['UZUM']['SERVICE_ID'],
is_test_mode=settings.PAYTECHUZ['UZUM']['IS_TEST_MODE']
)
payment_url = gateway.create_payment(
id=invoice.id,
amount=invoice.amount,
return_url="https://example.com/success"
)

elif payment_type == 'paynet':
gateway = PaynetGateway(
merchant_id='your_paynet_merchant_id',
is_test_mode=settings.PAYTECHUZ['PAYNET']['IS_TEST_MODE']
)
# Paynet to'lov URL yaratish
# URL formati: https://app.paynet.uz/?m={merchant_id}&c={payment_id}&a={amount}
payment_url = gateway.create_payment(
id=invoice.id, # To'lov ID (c parametri)
amount=invoice.amount # tiyinda summa (ixtiyoriy, a parametri)
)
# Yoki summasiz (summa Paynet tomonida sozlanadi)
# payment_url = gateway.create_payment(id=invoice.id)

return Response({
'order_id': order.id,
'invoice_id': invoice.id,
'payment_url': payment_url
}, status=status.HTTP_201_CREATED)