Skip to main content

Django Integration

Complete guide for integrating PayTechUZ with Django applications.

Complete Example Project

Looking for a ready-to-use Django project? Check out our Django Example Repository with full payment integration!

Installation

Install PayTechUZ with Django support:

pip install paytechuz[django]

Django Settings

Add PayTechUZ configuration to your Django settings:

# 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',
'COMMISSION_PERCENT': 0.0,
'IS_TEST_MODE': True, # Set to False in production
},
'ATMOS': {
'CONSUMER_KEY': 'your_atmos_consumer_key',
'CONSUMER_SECRET': 'your_atmos_consumer_secret',
'STORE_ID': 'your_atmos_store_id',
'TERMINAL_ID': 'your_atmos_terminal_id', # Optional
'API_KEY': 'your_atmos_api_key', # For webhook signature verification
'ACCOUNT_MODEL': 'payment.models.Invoice',
'ACCOUNT_FIELD': 'id',
'IS_TEST_MODE': True, # Set to False in production
}
}

Create models for handling orders and payments:

# 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}"

Views

Create views for handling payments:

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

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()

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()

class AtmosWebhookView(BaseAtmosWebhookView):
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()

URLs

Configure URL patterns:

# urls.py
from django.urls import path
from payment.views import PaymeWebhookView, ClickWebhookView, AtmosWebhookView
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/atmos/', AtmosWebhookView.as_view(), name='atmos_webhook'),

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

Here is an example of a Django Rest Framework (DRF) View that handles order creation and generates a payment link based on the selected payment provider (without using serializers):

# 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 paytechuz.gateways.atmos import AtmosGateway

from shop.models import Order
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', or 'atmos'

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=int(invoice.amount * 100), # Payme works with tiyin
return_url="https://example.com/success"
)

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"
)

elif payment_type == 'atmos':
gateway = AtmosGateway(
consumer_key=settings.PAYTECHUZ['ATMOS']['CONSUMER_KEY'],
consumer_secret=settings.PAYTECHUZ['ATMOS']['CONSUMER_SECRET'],
store_id=settings.PAYTECHUZ['ATMOS']['STORE_ID'],
is_test_mode=settings.PAYTECHUZ['ATMOS']['IS_TEST_MODE']
)
payment_data = gateway.create_payment(
account_id=invoice.id,
amount=int(invoice.amount * 100) # Atmos works with tiyin
)
payment_url = payment_data['payment_url']

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