django-chelseru 1.0.9__py3-none-any.whl → 1.1.0__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-chelseru
3
- Version: 1.0.9
3
+ Version: 1.1.0
4
4
  Summary: Authentication system, online and real-time chat, SMS system for Iranian SMS services.
5
5
  Home-page: https://pipdjango.chelseru.com
6
6
  Author: Sobhan Bahman Rashnu
@@ -1,19 +1,19 @@
1
- django_chelseru-1.0.9.dist-info/licenses/LICENSE,sha256=VupU5KV4NteHaNQb-WH31G_WZWezxXoomjiCIAHoQJo,1089
1
+ django_chelseru-1.1.0.dist-info/licenses/LICENSE,sha256=VupU5KV4NteHaNQb-WH31G_WZWezxXoomjiCIAHoQJo,1089
2
2
  drfchelseru/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- drfchelseru/admin.py,sha256=8X67Sy8k5qQzZ4ifuJ_5O-UqVWby4uX53Iq-KNuODxM,948
3
+ drfchelseru/admin.py,sha256=8glh59ggY-7ud76dIDfAXQwkBPq9Q80MF_qUC9ZOi0w,986
4
4
  drfchelseru/apps.py,sha256=hOTTzFGLXiTPZeN8p_LLcSECLtsR2Q0SUo8zJzgM-qQ,211
5
5
  drfchelseru/consumers.py,sha256=c8h9JYu5QUSKRREFrIrkjpkEQTzG5V8eg2lriaZODsc,2614
6
6
  drfchelseru/middlewares.py,sha256=2GT9wTkqfQIUQyVkecul2V4hssvhkKjYpHErvVmvY14,3808
7
- drfchelseru/models.py,sha256=9Wa-_Xk28zpFQ4HoRbQdcboZpjUFqxKHpZd05Vx8xXs,6296
7
+ drfchelseru/models.py,sha256=U_QqE2JdOGPP37rfB3-M4NcWysVc88xWDjWS9qo6fWI,9707
8
8
  drfchelseru/routing.py,sha256=shAlgzcIwVuVPlvKeWBLCqr6PuBTHyIrWNgHEfnqrxg,165
9
- drfchelseru/serializers.py,sha256=tM7dN362Vdx0UXq6OfNmYh6rTN1bwFoEgOn1MG4CZIY,1299
10
- drfchelseru/services.py,sha256=RAQsn95ByUoxUOnlRx-mVPr38mjwjP8Ff5tao_9t6YE,11550
11
- drfchelseru/settings.py,sha256=wKWud5LVHpuNhjRrkg3tvN5FkhSmQ-z8mQwQ42xfERs,11497
9
+ drfchelseru/serializers.py,sha256=I3kS2NhzIprY8-WWhjQPShAom6R7epg7do7RnDkpnys,1421
10
+ drfchelseru/services.py,sha256=zegZoUzusc8MUmcNFvt5uWbdzxfc5GD2LG0C2fQwR6g,17496
11
+ drfchelseru/settings.py,sha256=dcVmT1AdmIxeFs55R3hlCjEWYeUmYxUfEc21xi9RYag,11334
12
12
  drfchelseru/signals.py,sha256=nmFv208GW9nir9PAB0a1050OMh4I9em0n60O6Mgfwec,2554
13
13
  drfchelseru/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
14
- drfchelseru/urls.py,sha256=2RllsBPgojGLxLkyaBsSGk7fU1q44nuA7I_VpeHCmbs,702
14
+ drfchelseru/urls.py,sha256=zV4PJpJoxTMoYPLSQftdh-KDRG-WFgLBmJYQBlXnNMU,895
15
15
  drfchelseru/validators.py,sha256=jAJASfG4kPcqrGxxIcoR8VjS4L4n_EzZuxJtQ1g9qmo,480
16
- drfchelseru/views.py,sha256=9m0lNPQBBbw5cl_WLmWL_lf3DHRvp9v45AmiUYLviSE,12620
16
+ drfchelseru/views.py,sha256=U70GULWChKYo2aQqBUArUbS30slYbMNRDuEKP3hgvBU,15658
17
17
  drfchelseru/migrations/0001_initial.py,sha256=LfkWAeQuPXNW3_igM-w_pyKafCeHQF3aReYgMXfMzEE,1034
18
18
  drfchelseru/migrations/0002_otpcode_session_user.py,sha256=c3oyBTQo2kjsKr5r_XQrqaq-66F7pui-4H4mEyAXgJk,3126
19
19
  drfchelseru/migrations/0003_rename_mobile_otpcode_mobile_number.py,sha256=eiD7t6etg6nOeT7BhJrSfEcR1yTPePXtATgtyu30520,377
@@ -25,8 +25,13 @@ drfchelseru/migrations/0008_alter_chatroompermissions_user.py,sha256=d-LTEpAJhDl
25
25
  drfchelseru/migrations/0009_alter_chatroom_status.py,sha256=QaAEUpERV8rnN-ifimA-HfQ8yLk4Gc8T6kER_DtBznk,488
26
26
  drfchelseru/migrations/0010_chatroom_banneds_chatroom_descriptions_chatroom_name_and_more.py,sha256=aeotKPmdFJSjeA2-9VGApLfpx-NJkOrRJI2j2mdkf1U,1198
27
27
  drfchelseru/migrations/0011_alter_chatroom_user_1_alter_chatroom_user_2.py,sha256=9R66LzIujkh_4BpWtobpOvx3NALsMKUmtI5GDZXoSxQ,971
28
+ drfchelseru/migrations/0012_payment.py,sha256=X_f6BRih-9lYSTiS8WWyiF-XzZIVmBWXUqpF6nnqA7Q,1216
29
+ drfchelseru/migrations/0013_payment_authority_payment_data_payment_status_code.py,sha256=eTMFJBNAevC6jhGUALDkKcrbp4fwXgWVky2hay1cm68,715
30
+ drfchelseru/migrations/0014_payment_gateway_title_payment_gateway_url.py,sha256=7b4dn3_J4SNqTA5GqEHUmEGryJd26PSTaEoU0k_3BPk,616
31
+ drfchelseru/migrations/0015_payment_message.py,sha256=7aysohtF5ajAGFB88IRIy4nRagSi6GOIkQb9sTZp91o,436
32
+ drfchelseru/migrations/0016_payment_card_hash_payment_card_pan_and_more.py,sha256=bRGD0ZMJWW3R_c3mFAHsTMC8am2Xymh-48XRPVKmgvc,887
28
33
  drfchelseru/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- django_chelseru-1.0.9.dist-info/METADATA,sha256=sJiV6cXgiGsm0lYOZVWqr50BJPOtQI21aDJ6RoLzGXE,10944
30
- django_chelseru-1.0.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
- django_chelseru-1.0.9.dist-info/top_level.txt,sha256=fsaO1F03W3j4AYi0TfDGv5Cjb_Qrh6RSkwkWqfqaMns,12
32
- django_chelseru-1.0.9.dist-info/RECORD,,
34
+ django_chelseru-1.1.0.dist-info/METADATA,sha256=7Ojd9dovaki8_IwsuMiMWK7qPIRgh-foI9ekMOE8k4A,10944
35
+ django_chelseru-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
+ django_chelseru-1.1.0.dist-info/top_level.txt,sha256=fsaO1F03W3j4AYi0TfDGv5Cjb_Qrh6RSkwkWqfqaMns,12
37
+ django_chelseru-1.1.0.dist-info/RECORD,,
drfchelseru/admin.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from django.contrib import admin
2
- from .models import User, OTPCode, Session, MessageSMS, ChatRoom, MessageChat, ChatRoomPermissions, Organization
2
+ from .models import User, OTPCode, Session, MessageSMS, ChatRoom, MessageChat, ChatRoomPermissions, Organization, Payment
3
3
 
4
4
 
5
5
  @admin.register(User)
@@ -31,3 +31,4 @@ admin.site.register(ChatRoom)
31
31
  admin.site.register(MessageChat)
32
32
  admin.site.register(ChatRoomPermissions)
33
33
  admin.site.register(Organization)
34
+ admin.site.register(Payment)
@@ -0,0 +1,30 @@
1
+ # Generated by Django 5.1.6 on 2025-08-25 20:12
2
+
3
+ import django.db.models.deletion
4
+ from django.conf import settings
5
+ from django.db import migrations, models
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ('drfchelseru', '0011_alter_chatroom_user_1_alter_chatroom_user_2'),
12
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
13
+ ]
14
+
15
+ operations = [
16
+ migrations.CreateModel(
17
+ name='Payment',
18
+ fields=[
19
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20
+ ('order_id', models.CharField(max_length=20)),
21
+ ('amount', models.FloatField()),
22
+ ('description', models.TextField()),
23
+ ('callback_url', models.SlugField()),
24
+ ('mobile', models.CharField(blank=True, max_length=11, null=True)),
25
+ ('email', models.EmailField(blank=True, max_length=254, null=True)),
26
+ ('currency', models.CharField(blank=True, max_length=20, null=True)),
27
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
28
+ ],
29
+ ),
30
+ ]
@@ -0,0 +1,28 @@
1
+ # Generated by Django 5.1.6 on 2025-08-26 19:35
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('drfchelseru', '0012_payment'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='payment',
15
+ name='authority',
16
+ field=models.TextField(blank=True, null=True),
17
+ ),
18
+ migrations.AddField(
19
+ model_name='payment',
20
+ name='data',
21
+ field=models.TextField(blank=True, null=True),
22
+ ),
23
+ migrations.AddField(
24
+ model_name='payment',
25
+ name='status_code',
26
+ field=models.IntegerField(blank=True, null=True),
27
+ ),
28
+ ]
@@ -0,0 +1,23 @@
1
+ # Generated by Django 5.1.6 on 2025-08-26 20:22
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('drfchelseru', '0013_payment_authority_payment_data_payment_status_code'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='payment',
15
+ name='gateway_title',
16
+ field=models.CharField(blank=True, max_length=25, null=True),
17
+ ),
18
+ migrations.AddField(
19
+ model_name='payment',
20
+ name='gateway_url',
21
+ field=models.SlugField(blank=True, null=True),
22
+ ),
23
+ ]
@@ -0,0 +1,18 @@
1
+ # Generated by Django 5.1.6 on 2025-08-26 21:06
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('drfchelseru', '0014_payment_gateway_title_payment_gateway_url'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='payment',
15
+ name='message',
16
+ field=models.CharField(blank=True, max_length=25, null=True),
17
+ ),
18
+ ]
@@ -0,0 +1,33 @@
1
+ # Generated by Django 5.1.6 on 2025-08-26 21:10
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('drfchelseru', '0015_payment_message'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='payment',
15
+ name='card_hash',
16
+ field=models.TextField(blank=True, null=True),
17
+ ),
18
+ migrations.AddField(
19
+ model_name='payment',
20
+ name='card_pan',
21
+ field=models.TextField(blank=True, null=True),
22
+ ),
23
+ migrations.AddField(
24
+ model_name='payment',
25
+ name='data_verify',
26
+ field=models.TextField(blank=True, null=True),
27
+ ),
28
+ migrations.AddField(
29
+ model_name='payment',
30
+ name='ref_id',
31
+ field=models.IntegerField(blank=True, null=True),
32
+ ),
33
+ ]
drfchelseru/models.py CHANGED
@@ -164,4 +164,118 @@ class MessageChat(models.Model):
164
164
  created_at = models.DateTimeField(auto_now_add=True)
165
165
 
166
166
  def __str__(self):
167
- return f"iD: {self.id} | Message from {self.sender.username} at {self.timestamp} | Chatroom ID: {self.chat_room.id}"
167
+ return f"iD: {self.id} | Message from {self.sender.username} at {self.timestamp} | Chatroom ID: {self.chat_room.id}"
168
+
169
+
170
+ class Payment(models.Model):
171
+ user = models.ForeignKey(default_user, models.DO_NOTHING)
172
+ order_id = models.CharField(max_length=20)
173
+ amount = models.FloatField()
174
+ description = models.TextField()
175
+ callback_url = models.SlugField()
176
+ mobile = models.CharField(max_length=11, blank=True, null=True)
177
+ email = models.EmailField(blank=True, null=True)
178
+ currency = models.CharField(max_length=20, blank=True, null=True)
179
+
180
+ gateway_title = models.CharField(max_length=25, blank=True, null=True)
181
+ gateway_url = models.SlugField(blank=True, null=True)
182
+ authority = models.TextField(blank=True, null=True)
183
+ status_code = models.IntegerField(blank=True, null=True)
184
+ message = models.CharField(max_length=25, blank=True, null=True)
185
+ card_hash = models.TextField(blank=True, null=True)
186
+ card_pan = models.TextField(blank=True, null=True)
187
+ ref_id = models.IntegerField(blank=True, null=True)
188
+
189
+ data = models.TextField(blank=True, null=True)
190
+ data_verify = models.TextField(blank=True, null=True)
191
+
192
+ def __str__(self):
193
+ return f'payment id: {self.id} - order id: {self.order_id} amount: {self.amount}'
194
+
195
+ def set_request_data(self, **kwargs: dict):
196
+ '''
197
+ inputs:
198
+ currency
199
+ gateway_title
200
+ gateway_url
201
+ callback_url
202
+ authority
203
+ status_code
204
+ message
205
+ data
206
+ '''
207
+ currency = kwargs.get('currency')
208
+ gateway_title = kwargs.get('gateway_title')
209
+ gateway_url = kwargs.get('gateway_url')
210
+ callback_url = kwargs.get('callback_url')
211
+ authority = kwargs.get('authority')
212
+ status_code = kwargs.get('status_code')
213
+ message = kwargs.get('message')
214
+ data = kwargs.get('data')
215
+
216
+ if not callback_url:
217
+ return False
218
+
219
+ self.callback_url = callback_url
220
+
221
+ if currency is not None:
222
+ self.currency = currency
223
+
224
+ if gateway_title is not None:
225
+ self.gateway_title = gateway_title
226
+
227
+ if gateway_url is not None:
228
+ self.gateway_url = gateway_url
229
+
230
+ if authority is not None:
231
+ self.authority = authority
232
+
233
+ if status_code is not None:
234
+ self.status_code = status_code
235
+
236
+ if message is not None:
237
+ self.message = message
238
+
239
+ if data is not None:
240
+ self.data = data
241
+
242
+ self.save()
243
+
244
+ def set_verify_data(self, **kwargs: dict):
245
+ '''
246
+ inputs:
247
+ status_code
248
+ message
249
+ card_hash
250
+ card_pan
251
+ ref_id
252
+ data_verify
253
+ '''
254
+ status_code = kwargs.get('status_code')
255
+ message = kwargs.get('message')
256
+ card_hash = kwargs.get('card_hash')
257
+ card_pan = kwargs.get('card_pan')
258
+ ref_id = kwargs.get('ref_id')
259
+ data_verify = kwargs.get('data_verify')
260
+
261
+ if status_code is not None:
262
+ self.status_code = status_code
263
+
264
+ if message is not None:
265
+ self.message = message
266
+
267
+ if card_hash is not None:
268
+ self.card_hash = card_hash
269
+
270
+ if card_pan is not None:
271
+ self.card_pan = card_pan
272
+
273
+ if ref_id is not None:
274
+ self.ref_id = ref_id
275
+
276
+ if data_verify is not None:
277
+ self.data_verify = data_verify
278
+
279
+ self.save()
280
+ pass
281
+
@@ -1,6 +1,6 @@
1
1
  from rest_framework.serializers import ModelSerializer
2
2
  from django.contrib.auth.models import User
3
- from .models import User as mobile, OTPCode, Session, MessageSMS, ChatRoom, MessageChat
3
+ from .models import User as mobile, OTPCode, Session, MessageSMS, ChatRoom, MessageChat, Payment
4
4
 
5
5
  # from django.contrib.auth import get_user_model
6
6
 
@@ -51,4 +51,10 @@ class MessageChatSerializer(ModelSerializer):
51
51
  class Meta:
52
52
  model = MessageChat
53
53
  fields = '__all__'
54
- depth = 1
54
+ depth = 1
55
+
56
+
57
+ class PaymentSerializer(MobileSerializer):
58
+ class Meta:
59
+ model = Payment
60
+ fields = '__all__'
drfchelseru/services.py CHANGED
@@ -5,7 +5,8 @@ from zeep import Client
5
5
  from rest_framework.status import HTTP_200_OK, HTTP_204_NO_CONTENT, HTTP_500_INTERNAL_SERVER_ERROR, HTTP_502_BAD_GATEWAY, HTTP_401_UNAUTHORIZED, HTTP_400_BAD_REQUEST
6
6
 
7
7
 
8
- from .settings import sms_init_check, bank_init_check
8
+ from .settings import sms_init_check, bank_init_check, GATEWAY_ZARINPAL
9
+ from .models import Payment
9
10
 
10
11
 
11
12
  class ParsianWebcoIr:
@@ -274,14 +275,161 @@ class ZarinpalCom:
274
275
  },
275
276
  "errors": []
276
277
  }
278
+
279
+
280
+ merchant_id String بله كد ۳۶ كاراكتری اختصاصی پذیرنده
281
+ amount Integer بله مبلغ تراكنش
282
+ currency String خیر تعیین واحد پولی ریال (IRR) یا تومان(IRT)
283
+ description String بله توضیحات مربوط به تراکنش
284
+ callback_url String بله صفحه بازگشت مشتري، پس از انجام عمل پرداخت
285
+ metadata Array دارای مقدار های mobile و email و order_id
286
+ mobile String خیر شماره تماس خریدار
287
+ email String خیر ایمیل خریدار
288
+ order_id String خیر شماره سفارش
277
289
  '''
290
+ url = 'https://payment.zarinpal.com/pg/v4/payment/request.json'
291
+ headers = {
292
+ 'accept': 'application/json',
293
+ 'content-type': 'application/json'
294
+ }
278
295
  try:
279
- icheck = bank_init_check()
280
- if not icheck:
281
- raise ImproperlyConfigured('Configure Bank in DJANGO_CHELSERU.')
296
+ data = metadata
297
+ data['merchant_id'] = self.merchant_id
298
+ data['amount'] = amount
299
+ data['callback_url'] = callback_url
300
+ data['description'] = description
301
+ if order_id:
302
+ data['order_id'] = order_id
303
+
304
+ if mobile:
305
+ data['mobile'] = mobile
306
+
307
+ if email:
308
+ data['email'] = email
309
+
310
+ if currency:
311
+ data['currency'] = currency
312
+
313
+ response = requests.post(url=url, data=data)
314
+ return response.json()
282
315
 
283
- except ImproperlyConfigured as e:
284
- raise
285
316
  except:
286
- pass
287
- pass
317
+ return False
318
+
319
+
320
+ def verify_payment(self, authority, amount):
321
+ '''
322
+ curl -X POST \
323
+ https://payment.zarinpal.com/pg/v4/payment/verify.json \
324
+ -H 'accept: application/json' \
325
+ -H 'content-type: application/json' \
326
+ -d '{
327
+ "merchant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
328
+ "amount": 1000,
329
+ "authority": "A0000000000000000000000000000wwOGYpd"
330
+ }'
331
+
332
+
333
+ {
334
+ "data": {
335
+ "code": 100,
336
+ "message": "Verified",
337
+ "card_hash": "1EBE3EBEBE35C7EC0F8D6EE4F2F859107A87822CA179BC9528767EA7B5489B69",
338
+ "card_pan": "502229******5995",
339
+ "ref_id": 201,
340
+ "fee_type": "Merchant",
341
+ "fee": 0
342
+ },
343
+ "errors": []
344
+ }
345
+
346
+
347
+ code Integer عددی كه نشان دهنده موفق بودن یا موفق نبودن پرداخت است.
348
+ ref_id Integer در صورتی كه پرداخت موفق باشد، شماره تراكنش پرداخت انجام شده را بر می‌گرداند.
349
+ card_pan String شماره کارت به صورت Mask
350
+ card_hash String هش کارت به صورت SHA256
351
+ fee_type String پرداخت کننده کارمزد: که در پنل کاربری میان خریدار یا خود پذیرنده قابل انتخاب است.
352
+ fee Integer کارمزد
353
+ '''
354
+ url = 'https://payment.zarinpal.com/pg/v4/payment/verify.json'
355
+ headers = {
356
+ 'accept': 'application/json',
357
+ 'content-type': 'application/json'
358
+ }
359
+ data = {
360
+ 'merchant_id': self.merchant_id,
361
+ 'amount': int(amount),
362
+ 'authority': authority
363
+ }
364
+
365
+ print(data)
366
+
367
+ try:
368
+ response = requests.post(url=url, data=data).json()
369
+ return response
370
+ except:
371
+ return False
372
+
373
+
374
+
375
+ def create_payment(amount, description, merchant_id=None, callback_url=None, order_id=None, mobile=None, email=None, currency=None, **kwargs):
376
+ try:
377
+ ickeck = bank_init_check()
378
+ gateway = ickeck['gateway']
379
+ if not merchant_id:
380
+ merchant_id = ickeck['settings'].get('merchant_id')
381
+ if not callback_url:
382
+ callback_url = ickeck['settings'].get('callback_url')
383
+ if not currency:
384
+ currency = ickeck['settings'].get('currency')
385
+
386
+ callback_url = callback_url + '/payment/callback/' if callback_url[-1] != '/' else callback_url + 'payment/callback/'
387
+
388
+ response = None
389
+ match gateway:
390
+ case GATEWAY_ZARINPAL:
391
+ gw = ZarinpalCom(merchant_id=merchant_id)
392
+ _response = gw.create_payment(amount, callback_url, description, order_id, mobile, email, currency)
393
+ response = {
394
+ 'currency': currency,
395
+ 'gateway_title': GATEWAY_ZARINPAL,
396
+ 'gateway_url': f'https://payment.zarinpal.com/pg/StartPay/{_response['data'].get('authority')}',
397
+ 'callback_url': callback_url,
398
+ 'authority': _response['data'].get('authority'),
399
+ 'status_code': _response['data'].get('code'),
400
+ 'message': _response['data'].get('message'),
401
+ 'data': _response['data']
402
+ }
403
+
404
+ if response is not None:
405
+ return response
406
+ except ImproperlyConfigured as e:
407
+ raise
408
+ except:
409
+ pass
410
+
411
+
412
+ def verify_payment(authority, amount, merchant_id=None):
413
+ try:
414
+ ickeck = bank_init_check()
415
+ gateway = ickeck['gateway']
416
+ if not merchant_id:
417
+ merchant_id = ickeck['settings'].get('merchant_id')
418
+ response = None
419
+ match gateway:
420
+ case GATEWAY_ZARINPAL:
421
+ gw = ZarinpalCom(merchant_id=merchant_id)
422
+ _response = gw.verify_payment(authority, amount)
423
+ response = {
424
+ 'status_code': _response['data'].get('status_code'),
425
+ 'message': _response['data'].get('message'),
426
+ 'card_hash': _response['data'].get('card_hash'),
427
+ 'card_pan': _response['data'].get('card_pan'),
428
+ 'ref_id': _response['data'].get('ref_id'),
429
+ 'data_verify': _response['data'],
430
+ }
431
+
432
+ if response is not None:
433
+ return response
434
+ except ImproperlyConfigured as e:
435
+ raise
drfchelseru/settings.py CHANGED
@@ -53,7 +53,9 @@ AUTH_SERVICE_DJSESSION = 'django_session'
53
53
  AUTH_METHOD = [(0, 'OTP'), (1, 'PASSWD')]
54
54
  AUTH_SERVICES = [(0, AUTH_SERVICE_JWT)]
55
55
  SMS_SERVICES = [(0, 'PARSIAN_WEBCO_IR'),(1, 'MELI_PAYAMAK_COM') ,(2, 'KAVENEGAR_COM')]
56
- GATEWAYS = ((0, 'ZARINPAL_COM'),)
56
+
57
+ GATEWAY_ZARINPAL = 'ZARINPAL_COM'
58
+ GATEWAYS = ((0, GATEWAY_ZARINPAL),)
57
59
  CURRENCIES = ((0, 'IRT'), (1, 'IRR'))
58
60
 
59
61
 
@@ -247,13 +249,3 @@ def bank_init_check():
247
249
  return False
248
250
 
249
251
 
250
- '''
251
- 'BANK': {
252
- 'GATEWAY': 'ZARINPAL_COM',
253
- 'SETTINGS': {
254
- 'MERCHANT_ID': '',
255
- 'CALLBACK_URL': '',
256
- 'CURRENCY': 'IRT', # IRR, IRT
257
- }
258
- }
259
- '''
drfchelseru/urls.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from django.urls import path, include
2
2
  from rest_framework.routers import DefaultRouter
3
- from .views import MessageSend, OTPCodeSend ,Authentication, SessionList, MessageViewSet, ChatRoomViewSet
3
+ from .views import MessageSend, OTPCodeSend ,Authentication, SessionList, MessageViewSet, ChatRoomViewSet, PaymentCreate, PaymentCallback
4
4
 
5
5
  app_name = 'drfchelseru'
6
6
 
@@ -13,4 +13,7 @@ urlpatterns = [
13
13
  path('otp/send/', OTPCodeSend.as_view(), name='otp-send'),
14
14
  path('authenticate/', Authentication.as_view(), name='auth'),
15
15
  path('sessions/', SessionList.as_view(), name='sessions'),
16
+
17
+ path('payment/create/', PaymentCreate.as_view(), name='payment-create'),
18
+ path('payment/callback/', PaymentCallback.as_view(), name='payment-callback'),
16
19
  ] + [path('chat/', include(router.urls)),]
drfchelseru/views.py CHANGED
@@ -3,14 +3,14 @@ from rest_framework.views import APIView
3
3
  from rest_framework.permissions import AllowAny, IsAuthenticated
4
4
  from rest_framework.generics import ListAPIView
5
5
  from rest_framework.response import Response
6
- from rest_framework.status import HTTP_200_OK, HTTP_204_NO_CONTENT, HTTP_500_INTERNAL_SERVER_ERROR, HTTP_502_BAD_GATEWAY, HTTP_401_UNAUTHORIZED, HTTP_400_BAD_REQUEST, HTTP_409_CONFLICT
6
+ from rest_framework.status import HTTP_200_OK, HTTP_204_NO_CONTENT, HTTP_500_INTERNAL_SERVER_ERROR, HTTP_502_BAD_GATEWAY, HTTP_401_UNAUTHORIZED, HTTP_400_BAD_REQUEST, HTTP_409_CONFLICT, HTTP_404_NOT_FOUND
7
7
  from rest_framework.exceptions import NotFound, ValidationError
8
8
  from django.contrib.auth.models import User as UserDefault
9
9
 
10
- from .services import send_message
10
+ from .services import send_message, create_payment, verify_payment
11
11
  from .settings import sms_init_check, auth_init_check
12
12
  from .validators import mobile_number as mobile_validator
13
- from .serializers import MessageSerializer, OTPCodeSerializer, SessionSerializer, ChatRoomSerializer, MessageChatSerializer
13
+ from .serializers import MessageSerializer, OTPCodeSerializer, SessionSerializer, ChatRoomSerializer, MessageChatSerializer, PaymentSerializer
14
14
  from .models import User, ChatRoom
15
15
  from django.utils.timezone import now, timedelta
16
16
  from django.db import transaction
@@ -263,3 +263,84 @@ class MessageViewSet(ModelViewSet):
263
263
  chat = message.chat_room
264
264
  chat.save()
265
265
 
266
+
267
+
268
+ class PaymentCreate(APIView):
269
+ permission_classes = (AllowAny, )
270
+ serializer_class = PaymentSerializer
271
+ model = serializer_class.Meta.model
272
+
273
+ def post(self, request):
274
+ '''
275
+ order_id str
276
+ amount float
277
+ description str
278
+ callback_url str
279
+ mobile str
280
+ email str
281
+ currency str
282
+ '''
283
+
284
+ try:
285
+ assert 'order_id' in self.request.data, 'order_id is required.'
286
+ assert 'amount' in self.request.data, 'amount is required.'
287
+ assert 'description' in self.request.data, 'description is required.'
288
+
289
+ data = {
290
+ 'order_id': self.request.data['order_id'],
291
+ 'amount': self.request.data['amount'],
292
+ 'description': self.request.data['description'],
293
+ }
294
+
295
+ obj = self.model.objects.create(user=request.user, order_id=data['order_id'],
296
+ amount=data['amount'], description=data['description'])
297
+
298
+ if 'callback_url' in request.data:
299
+ data['callback_url'] = request.data['callback_url']
300
+ obj.callback_url = data['callback_url']
301
+
302
+ if 'mobile' in self.request.data:
303
+ data['mobile'] = self.request.data['mobile']
304
+ obj.mobile = data['mobile']
305
+
306
+ if 'email' in self.request.data:
307
+ data['email'] = self.request.data['email']
308
+ obj.email = data['email']
309
+
310
+ if 'currency' in self.request.data:
311
+ data['currency'] = self.request.data['currency']
312
+ obj.currency = data['currency']
313
+
314
+ obj.save()
315
+ response = create_payment(**data)
316
+ obj.set_request_data(**response)
317
+
318
+ return Response({'details': response}, status=HTTP_200_OK)
319
+ except AssertionError as e:
320
+ return Response({'error': str(e)}, status=HTTP_400_BAD_REQUEST)
321
+
322
+
323
+ class PaymentCallback(APIView):
324
+ permission_classes = (AllowAny, )
325
+ serializer_class = PaymentSerializer
326
+ model = serializer_class.Meta.model
327
+
328
+ def get(self, request):
329
+ '''
330
+ query params:
331
+ Authority
332
+ Status (OK, NOK)
333
+ '''
334
+ authority = request.GET.get('Authority')
335
+ status = request.GET.get('Status')
336
+
337
+ if status and status == 'OK' and authority:
338
+ try:
339
+ obj = self.model.objects.get(authority=authority)
340
+ response = verify_payment(authority=authority, amount=obj.amount)
341
+ obj.set_verify_data(**response)
342
+ return Response({'details': response}, status=HTTP_200_OK)
343
+ except self.model.DoesNotExist:
344
+ return Response({'error': 'payment not found.'}, status=HTTP_404_NOT_FOUND)
345
+
346
+ return Response({'error': 'The transaction was unsuccessful or canceled.'}, status=HTTP_400_BAD_REQUEST)