Skip to main content

django-click-uz

CI PyPI Python Django Click.uz

Django 5+ integration for the Click.uz Shop API: payment URLs, prepare/complete webhooks, MD5 signatures, optional audit log, replay protection, HTTPS and optional IP checks on callbacks.

O‘zbekcha (batafsil) README_UZ.md
Changelog CHANGELOG.md
Repository github.com/Matnazar-Matnazarov/django-click-uz
Extra docs (Markdown) docs/

What’s in the package

Part Role
click_uz Django app: add to INSTALLED_APPS, run migrations, include urls. Endpoints: prepare/, complete/, callback/, webhook/. Includes webhook_guard, ModelOrderHandler, signals, Uzbek locale/uz.
click_up Compatibility imports only: ClickUp, ClickWebhook, unique_transaction_param. Do not add to INSTALLED_APPS.
Config CLICK dict or flat CLICK_*; optional WEBHOOK_ALLOWED_CIDRS, WEBHOOK_REQUIRE_HTTPS, WEBHOOK_STRICT_IN_DEBUG.

Requirements

  • Python 3.12+
  • Django 5.0+

Installation

pip install django-click-uz
# settings.py
INSTALLED_APPS = [
    # ...
    "django.contrib.contenttypes",
    "django.contrib.auth",
    "click_uz",
    "orders",  # your app with Order model
]

Configuration

Use either the CLICK dict or flat CLICK_* variables. If both are set, CLICK wins.

Option A — CLICK dict (recommended)

import os

CLICK = {
    "SERVICE_ID": int(os.environ["CLICK_SERVICE_ID"]),
    "MERCHANT_ID": int(os.environ["CLICK_MERCHANT_ID"]),
    "SECRET_KEY": os.environ["CLICK_SECRET_KEY"],
    # Optional Click user id for Merchant API; defaults to MERCHANT_ID if omitted
    # "USER_ID": 12345,
    "ACCOUNT_MODEL": "orders.Order",
    "AMOUNT_FIELD": "amount",
    "STATUS_FIELD": "status",
    "STATUS_PENDING": "pending",
    "STATUS_WAITING": "waiting_payment",
    "STATUS_PAID": "paid",
    "STATUS_CANCELLED": "cancelled",
    "MERCHANT_TRANS_FIELD": "transaction_param",
    "COMMISSION_PERCENT": 0,
    "DISABLE_ADMIN": False,
    "ENABLE_AUDIT": True,
    # Production hardening (optional):
    # "WEBHOOK_ALLOWED_CIDRS": ["203.0.113.0/24"],
    # "WEBHOOK_STRICT_IN_DEBUG": True,
}

Option B — flat settings (legacy / click-pkg style)

CLICK_SERVICE_ID = 12345
CLICK_MERCHANT_ID = 67890
CLICK_SECRET_KEY = "your-secret-key"
CLICK_ACCOUNT_MODEL = "orders.Order"
CLICK_AMOUNT_FIELD = "amount"
CLICK_STATUS_FIELD = "status"
CLICK_MERCHANT_TRANS_FIELD = "transaction_param"
CLICK_COMMISSION_PERCENT = 0
CLICK_DISABLE_ADMIN = False

Webhooks require HANDLER_CLASS or ACCOUNT_MODEL + AMOUNT_FIELD + STATUS_FIELD.


Example: Order model

After prepare, the default handler sets status to waiting_payment; on success complete → paid; on rejection → cancelled. Align STATUS_* in CLICK with your choices.

# orders/models.py
from django.conf import settings
from django.db import models


class Order(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        null=True,
        blank=True,
    )
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    status = models.CharField(
        max_length=32,
        choices=[
            ("pending", "Pending"),
            ("waiting_payment", "Waiting payment"),
            ("paid", "Paid"),
            ("cancelled", "Cancelled"),
        ],
        default="pending",
    )
    transaction_param = models.CharField(max_length=255, blank=True, default="")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self) -> str:
        return f"Order {self.pk} — {self.amount}"
python manage.py makemigrations
python manage.py migrate

URLs

A) Include package routes (single webhook URL for the Click cabinet):

from django.urls import include, path

urlpatterns = [
    path("payment/click/", include("click_uz.urls")),
]

Webhook example: https://your-domain.example/payment/click/webhook/
(same prefix: prepare/, complete/, callback/).

B) Custom path with your ClickWebhook subclass:

from django.urls import path

from orders.views import ClickWebhookAPIView

urlpatterns = [
    path("payment/click/update/", ClickWebhookAPIView.as_view(), name="click-webhook"),
]

Register the full HTTPS URL in the Click merchant cabinet.


Views: webhook + pay link

Webhook subclass

params contains snapshot fields (id, merchant_trans_id, amount, state, …) and a nested payload with Click fields.

# orders/views.py
from click_up.views import ClickWebhook

from .models import Order


class ClickWebhookAPIView(ClickWebhook):
    def successfully_payment(self, params):
        order_id = params.get("id")
        try:
            order = Order.objects.get(pk=order_id)
            # Model handler already set status to paid; add email, analytics, etc.
        except Order.DoesNotExist:
            pass

    def cancelled_payment(self, params):
        pass

    def prepare_accepted(self, params):
        """Optional: runs after prepare succeeds."""
        pass

Create order + payment link (simple — order PK as transaction_param)

import json

from django.http import JsonResponse
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt

from click_up import ClickUp

from .models import Order


@method_decorator(csrf_exempt, name="dispatch")
class CreateOrderView(View):
    def post(self, request):
        body = json.loads(request.body or "{}")
        amount = body.get("amount")
        order = Order.objects.create(
            user=request.user if getattr(request, "user", None) and request.user.is_authenticated else None,
            amount=amount,
        )
        paylink = ClickUp().initializer.generate_pay_link(
            id=order.pk,
            amount=order.amount,
            return_url="https://example.com/orders/done/",
            unique_transaction_id=False,
        )
        return JsonResponse({"order_id": order.pk, "payment_link": paylink})

Recommended: unique transaction_param per checkout

from click_up import ClickUp, unique_transaction_param

from .models import Order

tid = unique_transaction_param(order.pk)
order.transaction_param = tid
order.save(update_fields=["transaction_param"])

paylink = ClickUp().initializer.generate_pay_link(
    id=order.pk,
    amount=order.amount,
    return_url="https://example.com/orders/done/",
    transaction_param=tid,
)

Requires MERCHANT_TRANS_FIELD / CLICK_MERCHANT_TRANS_FIELD pointing at transaction_param (see configuration above).

Django REST Framework: same logic inside APIView.post, using request.data instead of json.loads.


Security & operations

  • Callback JSON to Click stays in English; Django admin / config messages can use click_uz translations (locale/uz/).
  • MD5 sign_string verification is the main authenticity check.
  • click_uz.webhook_guard: enforce HTTPS in production; optional WEBHOOK_ALLOWED_CIDRS. Behind a TLS-terminating proxy, set SECURE_PROXY_SSL_HEADER.

Documentation (local)

No hosted doc site is provided. To build the MkDocs site locally:

pip install -e ".[dev]"
# or: uv sync --all-extras
mkdocs serve

Open the URL printed in the terminal (usually http://127.0.0.1:8000).


Development

pip install -e ".[dev]"
pytest

Releases: bump version in pyproject.toml, update CHANGELOG.md, commit, then tag and push vX.Y.Z (e.g. v0.1.2) to trigger publish.yml. Each PyPI upload needs a new version.


vs older click-pkg tutorials

Old tutorial This package
pip install click-pkg pip install django-click-uz
INSTALLED_APPS: click_up Only click_uz
is_test_mode Use Click test credentials / PAY_URL from Click docs if applicable

License

MIT — see LICENSE.

Click API reference: docs.click.uz.

Metadata

Release files for django-click-uz 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-click-uz 0.1.2
File Size Uploaded
django_click_uz-0.1.2.tar.gz 27.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-click-uz 0.1.2
File Interpreter ABI Platform
django_click_uz-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 56.3 kB

Release files / django_click_uz-0.1.2.tar.gz

Download URL django_click_uz-0.1.2.tar.gz
Size 27.1 kB
Tags Source
SHA-256 checksum
How to use checksums
088b8506f4e82184128acf638fc630ac88cd4c61e65ed39037e2511b29e52b4a
BLAKE2b-256 checksum
How to use checksums
d0be79a934edfadd4069cacbb299c5263d560c4f882d4e1ea414f865a4354142
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 5, 2026.

Transparency log

Release files / django_click_uz-0.1.2-py3-none-any.whl

Download URL django_click_uz-0.1.2-py3-none-any.whl
Size 29.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0fccc6ce14f4d4bb7ba5b4d587398459b7b0f3fb721266a63a8b8c882d07bb2d
BLAKE2b-256 checksum
How to use checksums
cbdf56c61e3fa81c930daac6e898e51e32a12e03442328a74e08e4f8388d777d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page