paytechuz 0.2.15__tar.gz → 0.2.16__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 (84) hide show
  1. {paytechuz-0.2.15 → paytechuz-0.2.16}/PKG-INFO +1 -1
  2. {paytechuz-0.2.15 → paytechuz-0.2.16}/pyproject.toml +1 -1
  3. {paytechuz-0.2.15 → paytechuz-0.2.16}/setup.py +1 -1
  4. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/click/client.py +4 -1
  5. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz.egg-info/PKG-INFO +1 -1
  6. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz.egg-info/SOURCES.txt +2 -1
  7. paytechuz-0.2.16/tests/test_click_gateway.py +217 -0
  8. {paytechuz-0.2.15 → paytechuz-0.2.16}/MANIFEST.in +0 -0
  9. {paytechuz-0.2.15 → paytechuz-0.2.16}/README.md +0 -0
  10. {paytechuz-0.2.15 → paytechuz-0.2.16}/examples/paytechuz_fastapi/__init__.py +0 -0
  11. {paytechuz-0.2.15 → paytechuz-0.2.16}/examples/paytechuz_fastapi/app/__init__.py +0 -0
  12. {paytechuz-0.2.15 → paytechuz-0.2.16}/examples/paytechuz_fastapi/app/database.py +0 -0
  13. {paytechuz-0.2.15 → paytechuz-0.2.16}/examples/paytechuz_fastapi/app/models.py +0 -0
  14. {paytechuz-0.2.15 → paytechuz-0.2.16}/examples/paytechuz_fastapi/app/typing.py +0 -0
  15. {paytechuz-0.2.15 → paytechuz-0.2.16}/examples/paytechuz_fastapi/app/webhook_handlers.py +0 -0
  16. {paytechuz-0.2.15 → paytechuz-0.2.16}/examples/paytechuz_fastapi/main.py +0 -0
  17. {paytechuz-0.2.15 → paytechuz-0.2.16}/examples/paytechuz_fastapi/payments.db +0 -0
  18. {paytechuz-0.2.15 → paytechuz-0.2.16}/examples/paytechuz_fastapi/run.sh +0 -0
  19. {paytechuz-0.2.15 → paytechuz-0.2.16}/setup.cfg +0 -0
  20. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/__init__.py +0 -0
  21. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/core/__init__.py +0 -0
  22. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/core/base.py +0 -0
  23. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/core/constants.py +0 -0
  24. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/core/exceptions.py +0 -0
  25. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/core/http.py +0 -0
  26. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/core/payme/errors.py +0 -0
  27. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/core/utils.py +0 -0
  28. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/__init__.py +0 -0
  29. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/click/__init__.py +0 -0
  30. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/click/client.py +0 -0
  31. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/click/merchant.py +0 -0
  32. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/click/webhook.py +0 -0
  33. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/payme/__init__.py +0 -0
  34. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/payme/cards.py +0 -0
  35. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/payme/client.py +0 -0
  36. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/payme/receipts.py +0 -0
  37. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/gateways/payme/webhook.py +0 -0
  38. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/__init__.py +0 -0
  39. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/django/__init__.py +0 -0
  40. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/django/admin.py +0 -0
  41. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/django/apps.py +0 -0
  42. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/django/migrations/0001_initial.py +0 -0
  43. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/django/migrations/__init__.py +0 -0
  44. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/django/models.py +0 -0
  45. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/django/signals.py +0 -0
  46. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/django/views.py +0 -0
  47. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/django/webhooks.py +0 -0
  48. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/fastapi/__init__.py +0 -0
  49. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/fastapi/models.py +0 -0
  50. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/fastapi/routes.py +0 -0
  51. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/integrations/fastapi/schemas.py +0 -0
  52. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/__init__.py +0 -0
  53. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/core/__init__.py +0 -0
  54. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/core/base.py +0 -0
  55. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/core/constants.py +0 -0
  56. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/core/exceptions.py +0 -0
  57. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/core/http.py +0 -0
  58. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/core/payme/errors.py +0 -0
  59. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/core/utils.py +0 -0
  60. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/__init__.py +0 -0
  61. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/click/__init__.py +0 -0
  62. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/click/merchant.py +0 -0
  63. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/click/webhook.py +0 -0
  64. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/payme/__init__.py +0 -0
  65. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/payme/cards.py +0 -0
  66. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/payme/client.py +0 -0
  67. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/payme/receipts.py +0 -0
  68. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/gateways/payme/webhook.py +0 -0
  69. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/__init__.py +0 -0
  70. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/django/__init__.py +0 -0
  71. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/django/admin.py +0 -0
  72. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/django/apps.py +0 -0
  73. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/django/migrations/0001_initial.py +0 -0
  74. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/django/migrations/__init__.py +0 -0
  75. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/django/models.py +0 -0
  76. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/django/signals.py +0 -0
  77. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/django/views.py +0 -0
  78. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/django/webhooks.py +0 -0
  79. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/fastapi/__init__.py +0 -0
  80. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/fastapi/models.py +0 -0
  81. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/fastapi/routes.py +0 -0
  82. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz/integrations/fastapi/schemas.py +0 -0
  83. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz.egg-info/dependency_links.txt +0 -0
  84. {paytechuz-0.2.15 → paytechuz-0.2.16}/src/paytechuz.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: paytechuz
3
- Version: 0.2.15
3
+ Version: 0.2.16
4
4
  Summary: Unified Python package for Uzbekistan payment gateways
5
5
  Home-page: https://github.com/Muhammadali-Akbarov/paytechuz
6
6
  Author: Muhammadali Akbarov
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "paytechuz"
7
- version = "0.2.15"
7
+ version = "0.2.16"
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.15',
11
+ version='0.2.16',
12
12
  license='MIT',
13
13
  author="Muhammadali Akbarov",
14
14
  author_email='muhammadali17abc@gmail.com',
@@ -109,7 +109,10 @@ class ClickGateway(BasePaymentGateway):
109
109
  payment_url += f"&callback_url={callback_url}"
110
110
 
111
111
  if description:
112
- payment_url += f"&merchant_user_id={description}"
112
+ payment_url += f"&description={description}"
113
+
114
+ if self.merchant_user_id:
115
+ payment_url += f"&merchant_user_id={self.merchant_user_id}"
113
116
 
114
117
  # Generate a unique transaction ID
115
118
  transaction_id = f"click_{id}_{int(amount_tiyin)}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: paytechuz
3
- Version: 0.2.15
3
+ Version: 0.2.16
4
4
  Summary: Unified Python package for Uzbekistan payment gateways
5
5
  Home-page: https://github.com/Muhammadali-Akbarov/paytechuz
6
6
  Author: Muhammadali Akbarov
@@ -78,4 +78,5 @@ src/paytechuz/integrations/django/migrations/__init__.py
78
78
  src/paytechuz/integrations/fastapi/__init__.py
79
79
  src/paytechuz/integrations/fastapi/models.py
80
80
  src/paytechuz/integrations/fastapi/routes.py
81
- src/paytechuz/integrations/fastapi/schemas.py
81
+ src/paytechuz/integrations/fastapi/schemas.py
82
+ tests/test_click_gateway.py
@@ -0,0 +1,217 @@
1
+ """
2
+ Unit tests for ClickGateway class.
3
+ """
4
+ import pytest
5
+ from unittest.mock import Mock, patch
6
+ from paytechuz.gateways.click.client import ClickGateway
7
+
8
+
9
+ class TestClickGateway:
10
+ """Test cases for ClickGateway class."""
11
+
12
+ @pytest.fixture
13
+ def click_gateway(self):
14
+ """Create a ClickGateway instance for testing."""
15
+ return ClickGateway(
16
+ service_id="test_service_id",
17
+ merchant_id="test_merchant_id",
18
+ merchant_user_id="test_merchant_user_id",
19
+ secret_key="test_secret_key",
20
+ is_test_mode=True
21
+ )
22
+
23
+ @pytest.fixture
24
+ def click_gateway_no_merchant_user(self):
25
+ """Create a ClickGateway instance without merchant_user_id."""
26
+ return ClickGateway(
27
+ service_id="test_service_id",
28
+ merchant_id="test_merchant_id",
29
+ is_test_mode=True
30
+ )
31
+
32
+ def test_create_payment_basic(self, click_gateway):
33
+ """Test basic payment creation."""
34
+ payment_result = click_gateway.create_payment(
35
+ id="order_123",
36
+ amount=150000
37
+ )
38
+
39
+ expected_params = [
40
+ "service_id=test_service_id",
41
+ "merchant_id=test_merchant_id",
42
+ "amount=150000",
43
+ "transaction_param=order_123",
44
+ "description=Payment for account order_123",
45
+ "merchant_user_id=test_merchant_user_id"
46
+ ]
47
+
48
+ assert isinstance(payment_result, dict)
49
+ assert 'payment_url' in payment_result
50
+ payment_url = payment_result['payment_url']
51
+ assert payment_url.startswith("https://my.click.uz/services/pay?")
52
+ for param in expected_params:
53
+ assert param in payment_url
54
+
55
+ def test_create_payment_with_optional_params(self, click_gateway):
56
+ """Test payment creation with optional parameters."""
57
+ payment_result = click_gateway.create_payment(
58
+ id="order_456",
59
+ amount=250000,
60
+ description="Custom payment description",
61
+ return_url="https://example.com/return",
62
+ callback_url="https://example.com/callback"
63
+ )
64
+
65
+ expected_params = [
66
+ "service_id=test_service_id",
67
+ "merchant_id=test_merchant_id",
68
+ "amount=250000",
69
+ "transaction_param=order_456",
70
+ "description=Custom payment description",
71
+ "return_url=https://example.com/return",
72
+ "callback_url=https://example.com/callback",
73
+ "merchant_user_id=test_merchant_user_id"
74
+ ]
75
+
76
+ assert isinstance(payment_result, dict)
77
+ assert 'payment_url' in payment_result
78
+ payment_url = payment_result['payment_url']
79
+ for param in expected_params:
80
+ assert param in payment_url
81
+
82
+ def test_create_payment_without_merchant_user_id(self, click_gateway_no_merchant_user):
83
+ """Test payment creation without merchant_user_id."""
84
+ payment_result = click_gateway_no_merchant_user.create_payment(
85
+ id="order_789",
86
+ amount=100000
87
+ )
88
+
89
+ assert isinstance(payment_result, dict)
90
+ assert 'payment_url' in payment_result
91
+ payment_url = payment_result['payment_url']
92
+ assert "merchant_user_id" not in payment_url
93
+ assert "service_id=test_service_id" in payment_url
94
+ assert "merchant_id=test_merchant_id" in payment_url
95
+
96
+ @patch('paytechuz.gateways.click.client.ClickMerchantApi')
97
+ def test_check_payment_success(self, mock_merchant_api, click_gateway):
98
+ """Test successful payment status check."""
99
+ # Mock the merchant API response
100
+ mock_api_instance = Mock()
101
+ mock_merchant_api.return_value = mock_api_instance
102
+ mock_api_instance.check_payment.return_value = {
103
+ 'status': 'success',
104
+ 'amount': 150000,
105
+ 'paid_at': '2024-01-01T12:00:00Z',
106
+ 'created_at': '2024-01-01T11:00:00Z'
107
+ }
108
+
109
+ # Reinitialize gateway to use mocked merchant API
110
+ gateway = ClickGateway(
111
+ service_id="test_service_id",
112
+ merchant_id="test_merchant_id",
113
+ merchant_user_id="test_merchant_user_id",
114
+ secret_key="test_secret_key",
115
+ is_test_mode=True
116
+ )
117
+
118
+ result = gateway.check_payment("click_order_123_150000")
119
+
120
+ assert result['transaction_id'] == "click_order_123_150000"
121
+ assert result['status'] == 'paid'
122
+ assert result['amount'] == 150000
123
+ assert result['paid_at'] == '2024-01-01T12:00:00Z'
124
+ mock_api_instance.check_payment.assert_called_once_with("order_123")
125
+
126
+ def test_check_payment_invalid_transaction_id(self, click_gateway):
127
+ """Test payment check with invalid transaction ID format."""
128
+ with pytest.raises(ValueError, match="Invalid transaction ID format"):
129
+ click_gateway.check_payment("invalid_format")
130
+
131
+ with pytest.raises(ValueError, match="Invalid transaction ID format"):
132
+ click_gateway.check_payment("payme_order_123_150000")
133
+
134
+ @patch('paytechuz.gateways.click.client.ClickMerchantApi')
135
+ def test_cancel_payment_success(self, mock_merchant_api, click_gateway):
136
+ """Test successful payment cancellation."""
137
+ # Mock the merchant API response
138
+ mock_api_instance = Mock()
139
+ mock_merchant_api.return_value = mock_api_instance
140
+ mock_api_instance.cancel_payment.return_value = {
141
+ 'cancelled_at': '2024-01-01T13:00:00Z'
142
+ }
143
+
144
+ # Reinitialize gateway to use mocked merchant API
145
+ gateway = ClickGateway(
146
+ service_id="test_service_id",
147
+ merchant_id="test_merchant_id",
148
+ merchant_user_id="test_merchant_user_id",
149
+ secret_key="test_secret_key",
150
+ is_test_mode=True
151
+ )
152
+
153
+ result = gateway.cancel_payment("click_order_123_150000", "Customer request")
154
+
155
+ assert result['transaction_id'] == "click_order_123_150000"
156
+ assert result['status'] == 'cancelled'
157
+ assert result['cancelled_at'] == '2024-01-01T13:00:00Z'
158
+ mock_api_instance.cancel_payment.assert_called_once_with("order_123", "Customer request")
159
+
160
+ def test_cancel_payment_invalid_transaction_id(self, click_gateway):
161
+ """Test payment cancellation with invalid transaction ID format."""
162
+ with pytest.raises(ValueError, match="Invalid transaction ID format"):
163
+ click_gateway.cancel_payment("invalid_format")
164
+
165
+ @pytest.mark.parametrize("click_status,expected_status", [
166
+ ('success', 'paid'),
167
+ ('processing', 'waiting'),
168
+ ('failed', 'failed'),
169
+ ('cancelled', 'cancelled'),
170
+ ('unknown_status', 'unknown')
171
+ ])
172
+ @patch('paytechuz.gateways.click.client.ClickMerchantApi')
173
+ def test_status_mapping(self, mock_merchant_api, click_gateway, click_status, expected_status):
174
+ """Test status mapping from Click to internal status."""
175
+ mock_api_instance = Mock()
176
+ mock_merchant_api.return_value = mock_api_instance
177
+ mock_api_instance.check_payment.return_value = {
178
+ 'status': click_status,
179
+ 'amount': 150000
180
+ }
181
+
182
+ gateway = ClickGateway(
183
+ service_id="test_service_id",
184
+ merchant_id="test_merchant_id",
185
+ is_test_mode=True
186
+ )
187
+
188
+ result = gateway.check_payment("click_order_123_150000")
189
+ assert result['status'] == expected_status
190
+
191
+ def test_initialization_test_mode(self):
192
+ """Test gateway initialization in test mode."""
193
+ gateway = ClickGateway(
194
+ service_id="test_service_id",
195
+ merchant_id="test_merchant_id",
196
+ is_test_mode=True
197
+ )
198
+
199
+ assert gateway.service_id == "test_service_id"
200
+ assert gateway.merchant_id == "test_merchant_id"
201
+ assert gateway.merchant_user_id is None
202
+ assert gateway.secret_key is None
203
+
204
+ def test_initialization_production_mode(self):
205
+ """Test gateway initialization in production mode."""
206
+ gateway = ClickGateway(
207
+ service_id="prod_service_id",
208
+ merchant_id="prod_merchant_id",
209
+ merchant_user_id="prod_user_id",
210
+ secret_key="prod_secret",
211
+ is_test_mode=False
212
+ )
213
+
214
+ assert gateway.service_id == "prod_service_id"
215
+ assert gateway.merchant_id == "prod_merchant_id"
216
+ assert gateway.merchant_user_id == "prod_user_id"
217
+ assert gateway.secret_key == "prod_secret"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes