paytechuz 0.2.8b0__tar.gz → 0.2.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of paytechuz might be problematic. Click here for more details.

Files changed (77) hide show
  1. paytechuz-0.2.10/PKG-INFO +318 -0
  2. paytechuz-0.2.10/README.md +303 -0
  3. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/pyproject.toml +1 -1
  4. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/setup.py +1 -1
  5. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/click/client.py +13 -20
  6. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/fastapi/models.py +55 -23
  7. {paytechuz-0.2.8b0/src/paytechuz → paytechuz-0.2.10/src}/integrations/fastapi/schemas.py +31 -14
  8. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/fastapi/models.py +33 -11
  9. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/fastapi/routes.py +158 -60
  10. {paytechuz-0.2.8b0/src → paytechuz-0.2.10/src/paytechuz}/integrations/fastapi/schemas.py +26 -7
  11. paytechuz-0.2.10/src/paytechuz.egg-info/PKG-INFO +318 -0
  12. paytechuz-0.2.8b0/PKG-INFO +0 -170
  13. paytechuz-0.2.8b0/README.md +0 -155
  14. paytechuz-0.2.8b0/src/paytechuz.egg-info/PKG-INFO +0 -170
  15. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/MANIFEST.in +0 -0
  16. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/setup.cfg +0 -0
  17. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/__init__.py +0 -0
  18. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/core/__init__.py +0 -0
  19. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/core/base.py +0 -0
  20. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/core/constants.py +0 -0
  21. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/core/exceptions.py +0 -0
  22. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/core/http.py +0 -0
  23. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/core/payme/errors.py +0 -0
  24. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/core/utils.py +0 -0
  25. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/__init__.py +0 -0
  26. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/click/__init__.py +0 -0
  27. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/click/merchant.py +0 -0
  28. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/click/webhook.py +0 -0
  29. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/payme/__init__.py +0 -0
  30. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/payme/cards.py +0 -0
  31. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/payme/client.py +0 -0
  32. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/payme/receipts.py +0 -0
  33. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/gateways/payme/webhook.py +0 -0
  34. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/__init__.py +0 -0
  35. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/django/__init__.py +0 -0
  36. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/django/admin.py +0 -0
  37. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/django/apps.py +0 -0
  38. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/django/migrations/0001_initial.py +0 -0
  39. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/django/migrations/__init__.py +0 -0
  40. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/django/models.py +0 -0
  41. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/django/signals.py +0 -0
  42. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/django/views.py +0 -0
  43. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/django/webhooks.py +0 -0
  44. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/fastapi/__init__.py +0 -0
  45. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/integrations/fastapi/routes.py +0 -0
  46. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/__init__.py +0 -0
  47. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/core/__init__.py +0 -0
  48. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/core/base.py +0 -0
  49. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/core/constants.py +0 -0
  50. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/core/exceptions.py +0 -0
  51. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/core/http.py +0 -0
  52. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/core/payme/errors.py +0 -0
  53. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/core/utils.py +0 -0
  54. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/__init__.py +0 -0
  55. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/click/__init__.py +0 -0
  56. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/click/client.py +0 -0
  57. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/click/merchant.py +0 -0
  58. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/click/webhook.py +0 -0
  59. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/payme/__init__.py +0 -0
  60. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/payme/cards.py +0 -0
  61. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/payme/client.py +0 -0
  62. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/payme/receipts.py +0 -0
  63. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/gateways/payme/webhook.py +0 -0
  64. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/__init__.py +0 -0
  65. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/django/__init__.py +0 -0
  66. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/django/admin.py +0 -0
  67. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/django/apps.py +0 -0
  68. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/django/migrations/0001_initial.py +0 -0
  69. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/django/migrations/__init__.py +0 -0
  70. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/django/models.py +0 -0
  71. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/django/signals.py +0 -0
  72. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/django/views.py +0 -0
  73. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/django/webhooks.py +0 -0
  74. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz/integrations/fastapi/__init__.py +0 -0
  75. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz.egg-info/SOURCES.txt +0 -0
  76. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz.egg-info/dependency_links.txt +0 -0
  77. {paytechuz-0.2.8b0 → paytechuz-0.2.10}/src/paytechuz.egg-info/top_level.txt +0 -0
@@ -0,0 +1,318 @@
1
+ Metadata-Version: 2.4
2
+ Name: paytechuz
3
+ Version: 0.2.10
4
+ Summary: Unified Python package for Uzbekistan payment gateways
5
+ Home-page: https://github.com/Muhammadali-Akbarov/paytechuz
6
+ Author: Muhammadali Akbarov
7
+ Author-email: muhammadali17abc@gmail.com
8
+ License: MIT
9
+ Requires-Python: >=3.6
10
+ Description-Content-Type: text/markdown
11
+ Dynamic: author
12
+ Dynamic: author-email
13
+ Dynamic: home-page
14
+ Dynamic: requires-python
15
+
16
+ # paytechuz
17
+
18
+ [![PyPI version](https://badge.fury.io/py/paytechuz.svg)](https://badge.fury.io/py/paytechuz)
19
+ [![Python Versions](https://img.shields.io/pypi/pyversions/paytechuz.svg)](https://pypi.org/project/paytechuz/)
20
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
21
+
22
+ PayTechUZ is a unified payment library for integrating with popular payment systems in Uzbekistan. It provides a simple and consistent interface for working with Payme and Click payment gateways.
23
+
24
+ ## Features
25
+
26
+ - 🔄 **API**: Consistent interface for multiple payment providers
27
+ - 🛡️ **Secure**: Built-in security features for payment processing
28
+ - 🔌 **Framework Integration**: Native support for Django and FastAPI
29
+ - 🌐 **Webhook Handling**: Easy-to-use webhook handlers for payment notifications
30
+ - 📊 **Transaction Management**: Automatic transaction tracking and management
31
+ - 🧩 **Extensible**: Easy to add new payment providers
32
+ ## Installation
33
+
34
+ ### Basic Installation
35
+
36
+ ```bash
37
+ pip install paytechuz
38
+ ```
39
+
40
+ ### Framework-Specific Installation
41
+
42
+ ```bash
43
+ # For Django
44
+ pip install paytechuz[django]
45
+
46
+ # For FastAPI
47
+ pip install paytechuz[fastapi]
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ ### Generate Payment Links
53
+
54
+ ```python
55
+ from paytechuz.gateways.payme import PaymeGateway
56
+ from paytechuz.gateways.click import ClickGateway
57
+
58
+ # Initialize Payme gateway
59
+ payme = PaymeGateway(
60
+ payme_id="your_payme_id",
61
+ payme_key="your_payme_key",
62
+ is_test_mode=True # Set to False in production environment
63
+ )
64
+
65
+ # Initialize Click gateway
66
+ click = ClickGateway(
67
+ service_id="your_service_id",
68
+ merchant_id="your_merchant_id",
69
+ merchant_user_id="your_merchant_user_id",
70
+ secret_key="your_secret_key",
71
+ is_test_mode=True # Set to False in production environment
72
+ )
73
+
74
+ # Generate payment links
75
+ payme_link = payme.create_payment(
76
+ id="order_123",
77
+ amount=150000, # amount in UZS
78
+ return_url="https://example.com/return"
79
+ )
80
+
81
+ click_link = click.create_payment(
82
+ id="order_123",
83
+ amount=150000, # amount in UZS
84
+ description="Test payment",
85
+ return_url="https://example.com/return"
86
+ )
87
+ ```
88
+
89
+ ### Django Integration
90
+
91
+ 1. Create Order model:
92
+
93
+ ```python
94
+ # models.py
95
+ from django.db import models
96
+ from django.utils import timezone
97
+
98
+ class Order(models.Model):
99
+ STATUS_CHOICES = (
100
+ ('pending', 'Pending'),
101
+ ('paid', 'Paid'),
102
+ ('cancelled', 'Cancelled'),
103
+ ('delivered', 'Delivered'),
104
+ )
105
+
106
+ product_name = models.CharField(max_length=255)
107
+ amount = models.DecimalField(max_digits=12, decimal_places=2)
108
+ status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
109
+ created_at = models.DateTimeField(default=timezone.now)
110
+
111
+ def __str__(self):
112
+ return f"{self.id} - {self.product_name} ({self.amount})"
113
+ ```
114
+
115
+ 2. Add to `INSTALLED_APPS` and configure settings:
116
+
117
+ ```python
118
+ # settings.py
119
+ INSTALLED_APPS = [
120
+ # ...
121
+ 'paytechuz.integrations.django',
122
+ ]
123
+
124
+ PAYME_ID = 'your_payme_merchant_id'
125
+ PAYME_KEY = 'your_payme_merchant_key'
126
+ PAYME_ACCOUNT_MODEL = 'your_app.models.Order' # For example: 'orders.models.Order'
127
+ PAYME_ACCOUNT_FIELD = 'id'
128
+ PAYME_AMOUNT_FIELD = 'amount' # Field for storing payment amount
129
+ PAYME_ONE_TIME_PAYMENT = True # Allow only one payment per account
130
+
131
+ CLICK_SERVICE_ID = 'your_click_service_id'
132
+ CLICK_MERCHANT_ID = 'your_click_merchant_id'
133
+ CLICK_SECRET_KEY = 'your_click_secret_key'
134
+ CLICK_ACCOUNT_MODEL = 'your_app.models.Order'
135
+ CLICK_COMMISSION_PERCENT = 0.0
136
+ ```
137
+
138
+ 3. Create webhook handlers:
139
+
140
+ ```python
141
+ # views.py
142
+ from paytechuz.integrations.django.views import BasePaymeWebhookView, BaseClickWebhookView
143
+ from .models import Order
144
+
145
+ class PaymeWebhookView(BasePaymeWebhookView):
146
+ def successfully_payment(self, params, transaction):
147
+ order = Order.objects.get(id=transaction.account_id)
148
+ order.status = 'paid'
149
+ order.save()
150
+
151
+ def cancelled_payment(self, params, transaction):
152
+ order = Order.objects.get(id=transaction.account_id)
153
+ order.status = 'cancelled'
154
+ order.save()
155
+
156
+ class ClickWebhookView(BaseClickWebhookView):
157
+ def successfully_payment(self, params, transaction):
158
+ order = Order.objects.get(id=transaction.account_id)
159
+ order.status = 'paid'
160
+ order.save()
161
+
162
+ def cancelled_payment(self, params, transaction):
163
+ order = Order.objects.get(id=transaction.account_id)
164
+ order.status = 'cancelled'
165
+ order.save()
166
+ ```
167
+
168
+ 4. Add webhook URLs to `urls.py`:
169
+
170
+ ```python
171
+ # urls.py
172
+ from django.urls import path
173
+ from django.views.decorators.csrf import csrf_exempt
174
+ from .views import PaymeWebhookView, ClickWebhookView
175
+
176
+ urlpatterns = [
177
+ # ...
178
+ path('payments/webhook/payme/', csrf_exempt(PaymeWebhookView.as_view()), name='payme_webhook'),
179
+ path('payments/webhook/click/', csrf_exempt(ClickWebhookView.as_view()), name='click_webhook'),
180
+ ]
181
+ ```
182
+
183
+ ### FastAPI Integration
184
+
185
+ 1. Set up database models:
186
+
187
+ ```python
188
+ from datetime import datetime, timezone
189
+
190
+ from sqlalchemy.orm import sessionmaker
191
+ from sqlalchemy.ext.declarative import declarative_base
192
+ from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime
193
+
194
+ from paytechuz.integrations.fastapi import Base as PaymentsBase
195
+ from paytechuz.integrations.fastapi.models import run_migrations
196
+
197
+
198
+ # Create database engine
199
+ SQLALCHEMY_DATABASE_URL = "sqlite:///./payments.db"
200
+ engine = create_engine(SQLALCHEMY_DATABASE_URL)
201
+
202
+ # Create base declarative class
203
+ Base = declarative_base()
204
+
205
+ # Create Order model
206
+ class Order(Base):
207
+ __tablename__ = "orders"
208
+
209
+ id = Column(Integer, primary_key=True, index=True)
210
+ product_name = Column(String, index=True)
211
+ amount = Column(Float)
212
+ status = Column(String, default="pending")
213
+ created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
214
+
215
+ # Create payment tables using run_migrations
216
+ run_migrations(engine)
217
+
218
+ # Create Order table
219
+ Base.metadata.create_all(bind=engine)
220
+
221
+ # Create session
222
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
223
+ ```
224
+
225
+ 2. Create webhook handlers:
226
+
227
+ ```python
228
+ from fastapi import FastAPI, Request, Depends
229
+
230
+ from sqlalchemy.orm import Session
231
+
232
+ from paytechuz.integrations.fastapi import PaymeWebhookHandler, ClickWebhookHandler
233
+
234
+
235
+ app = FastAPI()
236
+
237
+ # Dependency to get the database session
238
+ def get_db():
239
+ db = SessionLocal()
240
+ try:
241
+ yield db
242
+ finally:
243
+ db.close()
244
+
245
+ class CustomPaymeWebhookHandler(PaymeWebhookHandler):
246
+ def successfully_payment(self, params, transaction):
247
+ # Handle successful payment
248
+ order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
249
+ order.status = "paid"
250
+ self.db.commit()
251
+
252
+ def cancelled_payment(self, params, transaction):
253
+ # Handle cancelled payment
254
+ order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
255
+ order.status = "cancelled"
256
+ self.db.commit()
257
+
258
+ class CustomClickWebhookHandler(ClickWebhookHandler):
259
+ def successfully_payment(self, params, transaction):
260
+ # Handle successful payment
261
+ order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
262
+ order.status = "paid"
263
+ self.db.commit()
264
+
265
+ def cancelled_payment(self, params, transaction):
266
+ # Handle cancelled payment
267
+ order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
268
+ order.status = "cancelled"
269
+ self.db.commit()
270
+
271
+ @app.post("/payments/payme/webhook")
272
+ async def payme_webhook(request: Request, db: Session = Depends(get_db)):
273
+ handler = CustomPaymeWebhookHandler(
274
+ db=db,
275
+ payme_id="your_merchant_id",
276
+ payme_key="your_merchant_key",
277
+ account_model=Order,
278
+ account_field='id',
279
+ amount_field='amount'
280
+ )
281
+ return await handler.handle_webhook(request)
282
+
283
+ @app.post("/payments/click/webhook")
284
+ async def click_webhook(request: Request, db: Session = Depends(get_db)):
285
+ handler = CustomClickWebhookHandler(
286
+ db=db,
287
+ service_id="your_service_id",
288
+ merchant_id="your_merchant_id",
289
+ secret_key="your_secret_key",
290
+ account_model=Order
291
+ )
292
+ return await handler.handle_webhook(request)
293
+ ```
294
+
295
+ ## Documentation
296
+
297
+ Detailed documentation is available in multiple languages:
298
+
299
+ - 📖 [English Documentation](src/docs/en/index.md)
300
+ - 📖 [O'zbek tilidagi hujjatlar](src/docs/index.md)
301
+
302
+ ### Framework-Specific Documentation
303
+
304
+ - [Django Integration Guide](src/docs/en/django_integration.md) | [Django integratsiyasi bo'yicha qo'llanma](src/docs/django_integration.md)
305
+ - [FastAPI Integration Guide](src/docs/en/fastapi_integration.md) | [FastAPI integratsiyasi bo'yicha qo'llanma](src/docs/fastapi_integration.md)
306
+
307
+ ## Supported Payment Systems
308
+
309
+ - **Payme** - [Official Website](https://payme.uz)
310
+ - **Click** - [Official Website](https://click.uz)
311
+
312
+ ## Contributing
313
+
314
+ Contributions are welcome! Please feel free to submit a Pull Request.
315
+
316
+ ## License
317
+
318
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,303 @@
1
+ # paytechuz
2
+
3
+ [![PyPI version](https://badge.fury.io/py/paytechuz.svg)](https://badge.fury.io/py/paytechuz)
4
+ [![Python Versions](https://img.shields.io/pypi/pyversions/paytechuz.svg)](https://pypi.org/project/paytechuz/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ PayTechUZ is a unified payment library for integrating with popular payment systems in Uzbekistan. It provides a simple and consistent interface for working with Payme and Click payment gateways.
8
+
9
+ ## Features
10
+
11
+ - 🔄 **API**: Consistent interface for multiple payment providers
12
+ - 🛡️ **Secure**: Built-in security features for payment processing
13
+ - 🔌 **Framework Integration**: Native support for Django and FastAPI
14
+ - 🌐 **Webhook Handling**: Easy-to-use webhook handlers for payment notifications
15
+ - 📊 **Transaction Management**: Automatic transaction tracking and management
16
+ - 🧩 **Extensible**: Easy to add new payment providers
17
+ ## Installation
18
+
19
+ ### Basic Installation
20
+
21
+ ```bash
22
+ pip install paytechuz
23
+ ```
24
+
25
+ ### Framework-Specific Installation
26
+
27
+ ```bash
28
+ # For Django
29
+ pip install paytechuz[django]
30
+
31
+ # For FastAPI
32
+ pip install paytechuz[fastapi]
33
+ ```
34
+
35
+ ## Quick Start
36
+
37
+ ### Generate Payment Links
38
+
39
+ ```python
40
+ from paytechuz.gateways.payme import PaymeGateway
41
+ from paytechuz.gateways.click import ClickGateway
42
+
43
+ # Initialize Payme gateway
44
+ payme = PaymeGateway(
45
+ payme_id="your_payme_id",
46
+ payme_key="your_payme_key",
47
+ is_test_mode=True # Set to False in production environment
48
+ )
49
+
50
+ # Initialize Click gateway
51
+ click = ClickGateway(
52
+ service_id="your_service_id",
53
+ merchant_id="your_merchant_id",
54
+ merchant_user_id="your_merchant_user_id",
55
+ secret_key="your_secret_key",
56
+ is_test_mode=True # Set to False in production environment
57
+ )
58
+
59
+ # Generate payment links
60
+ payme_link = payme.create_payment(
61
+ id="order_123",
62
+ amount=150000, # amount in UZS
63
+ return_url="https://example.com/return"
64
+ )
65
+
66
+ click_link = click.create_payment(
67
+ id="order_123",
68
+ amount=150000, # amount in UZS
69
+ description="Test payment",
70
+ return_url="https://example.com/return"
71
+ )
72
+ ```
73
+
74
+ ### Django Integration
75
+
76
+ 1. Create Order model:
77
+
78
+ ```python
79
+ # models.py
80
+ from django.db import models
81
+ from django.utils import timezone
82
+
83
+ class Order(models.Model):
84
+ STATUS_CHOICES = (
85
+ ('pending', 'Pending'),
86
+ ('paid', 'Paid'),
87
+ ('cancelled', 'Cancelled'),
88
+ ('delivered', 'Delivered'),
89
+ )
90
+
91
+ product_name = models.CharField(max_length=255)
92
+ amount = models.DecimalField(max_digits=12, decimal_places=2)
93
+ status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
94
+ created_at = models.DateTimeField(default=timezone.now)
95
+
96
+ def __str__(self):
97
+ return f"{self.id} - {self.product_name} ({self.amount})"
98
+ ```
99
+
100
+ 2. Add to `INSTALLED_APPS` and configure settings:
101
+
102
+ ```python
103
+ # settings.py
104
+ INSTALLED_APPS = [
105
+ # ...
106
+ 'paytechuz.integrations.django',
107
+ ]
108
+
109
+ PAYME_ID = 'your_payme_merchant_id'
110
+ PAYME_KEY = 'your_payme_merchant_key'
111
+ PAYME_ACCOUNT_MODEL = 'your_app.models.Order' # For example: 'orders.models.Order'
112
+ PAYME_ACCOUNT_FIELD = 'id'
113
+ PAYME_AMOUNT_FIELD = 'amount' # Field for storing payment amount
114
+ PAYME_ONE_TIME_PAYMENT = True # Allow only one payment per account
115
+
116
+ CLICK_SERVICE_ID = 'your_click_service_id'
117
+ CLICK_MERCHANT_ID = 'your_click_merchant_id'
118
+ CLICK_SECRET_KEY = 'your_click_secret_key'
119
+ CLICK_ACCOUNT_MODEL = 'your_app.models.Order'
120
+ CLICK_COMMISSION_PERCENT = 0.0
121
+ ```
122
+
123
+ 3. Create webhook handlers:
124
+
125
+ ```python
126
+ # views.py
127
+ from paytechuz.integrations.django.views import BasePaymeWebhookView, BaseClickWebhookView
128
+ from .models import Order
129
+
130
+ class PaymeWebhookView(BasePaymeWebhookView):
131
+ def successfully_payment(self, params, transaction):
132
+ order = Order.objects.get(id=transaction.account_id)
133
+ order.status = 'paid'
134
+ order.save()
135
+
136
+ def cancelled_payment(self, params, transaction):
137
+ order = Order.objects.get(id=transaction.account_id)
138
+ order.status = 'cancelled'
139
+ order.save()
140
+
141
+ class ClickWebhookView(BaseClickWebhookView):
142
+ def successfully_payment(self, params, transaction):
143
+ order = Order.objects.get(id=transaction.account_id)
144
+ order.status = 'paid'
145
+ order.save()
146
+
147
+ def cancelled_payment(self, params, transaction):
148
+ order = Order.objects.get(id=transaction.account_id)
149
+ order.status = 'cancelled'
150
+ order.save()
151
+ ```
152
+
153
+ 4. Add webhook URLs to `urls.py`:
154
+
155
+ ```python
156
+ # urls.py
157
+ from django.urls import path
158
+ from django.views.decorators.csrf import csrf_exempt
159
+ from .views import PaymeWebhookView, ClickWebhookView
160
+
161
+ urlpatterns = [
162
+ # ...
163
+ path('payments/webhook/payme/', csrf_exempt(PaymeWebhookView.as_view()), name='payme_webhook'),
164
+ path('payments/webhook/click/', csrf_exempt(ClickWebhookView.as_view()), name='click_webhook'),
165
+ ]
166
+ ```
167
+
168
+ ### FastAPI Integration
169
+
170
+ 1. Set up database models:
171
+
172
+ ```python
173
+ from datetime import datetime, timezone
174
+
175
+ from sqlalchemy.orm import sessionmaker
176
+ from sqlalchemy.ext.declarative import declarative_base
177
+ from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime
178
+
179
+ from paytechuz.integrations.fastapi import Base as PaymentsBase
180
+ from paytechuz.integrations.fastapi.models import run_migrations
181
+
182
+
183
+ # Create database engine
184
+ SQLALCHEMY_DATABASE_URL = "sqlite:///./payments.db"
185
+ engine = create_engine(SQLALCHEMY_DATABASE_URL)
186
+
187
+ # Create base declarative class
188
+ Base = declarative_base()
189
+
190
+ # Create Order model
191
+ class Order(Base):
192
+ __tablename__ = "orders"
193
+
194
+ id = Column(Integer, primary_key=True, index=True)
195
+ product_name = Column(String, index=True)
196
+ amount = Column(Float)
197
+ status = Column(String, default="pending")
198
+ created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
199
+
200
+ # Create payment tables using run_migrations
201
+ run_migrations(engine)
202
+
203
+ # Create Order table
204
+ Base.metadata.create_all(bind=engine)
205
+
206
+ # Create session
207
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
208
+ ```
209
+
210
+ 2. Create webhook handlers:
211
+
212
+ ```python
213
+ from fastapi import FastAPI, Request, Depends
214
+
215
+ from sqlalchemy.orm import Session
216
+
217
+ from paytechuz.integrations.fastapi import PaymeWebhookHandler, ClickWebhookHandler
218
+
219
+
220
+ app = FastAPI()
221
+
222
+ # Dependency to get the database session
223
+ def get_db():
224
+ db = SessionLocal()
225
+ try:
226
+ yield db
227
+ finally:
228
+ db.close()
229
+
230
+ class CustomPaymeWebhookHandler(PaymeWebhookHandler):
231
+ def successfully_payment(self, params, transaction):
232
+ # Handle successful payment
233
+ order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
234
+ order.status = "paid"
235
+ self.db.commit()
236
+
237
+ def cancelled_payment(self, params, transaction):
238
+ # Handle cancelled payment
239
+ order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
240
+ order.status = "cancelled"
241
+ self.db.commit()
242
+
243
+ class CustomClickWebhookHandler(ClickWebhookHandler):
244
+ def successfully_payment(self, params, transaction):
245
+ # Handle successful payment
246
+ order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
247
+ order.status = "paid"
248
+ self.db.commit()
249
+
250
+ def cancelled_payment(self, params, transaction):
251
+ # Handle cancelled payment
252
+ order = self.db.query(Order).filter(Order.id == transaction.account_id).first()
253
+ order.status = "cancelled"
254
+ self.db.commit()
255
+
256
+ @app.post("/payments/payme/webhook")
257
+ async def payme_webhook(request: Request, db: Session = Depends(get_db)):
258
+ handler = CustomPaymeWebhookHandler(
259
+ db=db,
260
+ payme_id="your_merchant_id",
261
+ payme_key="your_merchant_key",
262
+ account_model=Order,
263
+ account_field='id',
264
+ amount_field='amount'
265
+ )
266
+ return await handler.handle_webhook(request)
267
+
268
+ @app.post("/payments/click/webhook")
269
+ async def click_webhook(request: Request, db: Session = Depends(get_db)):
270
+ handler = CustomClickWebhookHandler(
271
+ db=db,
272
+ service_id="your_service_id",
273
+ merchant_id="your_merchant_id",
274
+ secret_key="your_secret_key",
275
+ account_model=Order
276
+ )
277
+ return await handler.handle_webhook(request)
278
+ ```
279
+
280
+ ## Documentation
281
+
282
+ Detailed documentation is available in multiple languages:
283
+
284
+ - 📖 [English Documentation](src/docs/en/index.md)
285
+ - 📖 [O'zbek tilidagi hujjatlar](src/docs/index.md)
286
+
287
+ ### Framework-Specific Documentation
288
+
289
+ - [Django Integration Guide](src/docs/en/django_integration.md) | [Django integratsiyasi bo'yicha qo'llanma](src/docs/django_integration.md)
290
+ - [FastAPI Integration Guide](src/docs/en/fastapi_integration.md) | [FastAPI integratsiyasi bo'yicha qo'llanma](src/docs/fastapi_integration.md)
291
+
292
+ ## Supported Payment Systems
293
+
294
+ - **Payme** - [Official Website](https://payme.uz)
295
+ - **Click** - [Official Website](https://click.uz)
296
+
297
+ ## Contributing
298
+
299
+ Contributions are welcome! Please feel free to submit a Pull Request.
300
+
301
+ ## License
302
+
303
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "paytechuz"
7
- version = "0.2.8b"
7
+ version = "0.2.10"
8
8
  description = "Unified Python package for Uzbekistan payment gateways"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.7"
@@ -8,7 +8,7 @@ long_description = (here / "README.md").read_text(encoding="utf-8")
8
8
 
9
9
  setup(
10
10
  name='paytechuz',
11
- version='0.2.8b',
11
+ version='0.2.10',
12
12
  license='MIT',
13
13
  author="Muhammadali Akbarov",
14
14
  author_email='muhammadali17abc@gmail.com',