diff --git a/abonapp/pay_systems.py b/abonapp/pay_systems.py index e5f5da1..b09ecc1 100644 --- a/abonapp/pay_systems.py +++ b/abonapp/pay_systems.py @@ -4,23 +4,23 @@ from mydefs import safe_int, safe_float from .models import Abon, AllTimePayLog from django.db import DatabaseError from django.conf import settings +from xmlview.decorators import xml_view SECRET = getattr(settings, 'PAY_SECRET') SERV_ID = getattr(settings, 'PAY_SERV_ID') +@xml_view(root_node='pay-response') def allpay(request): def bad_ret(err_id, err_description=None): - current_date = timezone.now() - res = [ - "", - "", - " %d" % safe_int(err_id), - " %s" % current_date.strftime("%d.%m.%Y %H:%M:%S"), - " %s" % err_description if err_description is not None else '', - "" - ] - return '\n'.join(res) + now = timezone.now() + r = { + 'status_code': safe_int(err_id), + 'time_stamp': now.strftime("%d.%m.%Y %H:%M") + } + if err_description: + r.update({'description': err_description}) + return r try: serv_id = request.GET.get('SERVICE_ID') @@ -29,8 +29,10 @@ def allpay(request): pay_id = request.GET.get('PAY_ID') pay_amount = safe_float(request.GET.get('PAY_AMOUNT')) sign = request.GET.get('SIGN').lower() + current_date = timezone.now().strftime("%d.%m.%Y %H:%M") - if act <= 0: return bad_ret(-101, 'ACT less than zero') + if act <= 0: + return bad_ret(-101, 'ACT less than zero') # check sign md = md5() @@ -44,18 +46,16 @@ def allpay(request): abon = Abon.objects.get(username=pay_account) fio = abon.fio ballance = float(abon.ballance) - current_date = timezone.now().strftime("%d.%m.%Y %H:%M:%S") - return "\n" \ - "\n" \ - " %.2f\n" % ballance + \ - " %s\n" % fio + \ - " %s\n" % pay_account + \ - " %s\n" % SERV_ID + \ - " 10.0\n" \ - " 50000\n" \ - " 21\n" \ - " %s\n" % current_date + \ - "" + return { + 'balance': ballance, + 'name': fio, + 'account': pay_account, + 'service_id': SERV_ID, + 'min_amount': 10.0, + 'max_amount': 5000, + 'status_code': 21, + 'time_stamp': current_date + } elif act == 4: trade_point = safe_int(request.GET.get('TRADE_POINT')) receipt_num = safe_int(request.GET.get('RECEIPT_NUM')) @@ -74,30 +74,26 @@ def allpay(request): trade_point=trade_point, receipt_num=receipt_num ) - current_date = timezone.now().strftime("%d.%m.%Y %H:%M:%S") - return "" \ - "\n" + \ - " %s\n" % pay_id + \ - " %s\n" % serv_id + \ - " %.2f\n" % pay_amount + \ - " 22\n" + \ - " %s\n" % current_date + \ - "" + return { + 'pay_id': pay_id, + 'service_id': serv_id, + 'amount': pay_amount, + 'status_code': 22, + 'time_stamp': current_date + } elif act == 7: pay = AllTimePayLog.objects.get(pay_id=pay_id) - current_date = timezone.now().strftime("%d.%m.%Y %H:%M:%S") - return "\n" \ - "\n" \ - " 11\n" \ - " %s\n" % current_date + \ - " \n" \ - " %s\n" % pay_id + \ - " %s\n" % serv_id + \ - " %.2f\n" % float(pay.summ) + \ - " 111\n" + \ - " %s\n" % current_date + \ - " \n" \ - "" + return { + 'status_code': 11, + 'time_stamp': current_date, + 'transaction': { + 'pay_id': pay_id, + 'service_id': serv_id, + 'amount': pay.summ, + 'status': 111, + 'time_stamp': pay.date_add.strftime("%d.%m.%Y %H:%M") + } + } else: return bad_ret(-101, 'ACT is not passed') diff --git a/abonapp/tests.py b/abonapp/tests.py new file mode 100644 index 0000000..d1cc940 --- /dev/null +++ b/abonapp/tests.py @@ -0,0 +1,198 @@ +from hashlib import md5 + +from django.test import TestCase, RequestFactory +from django.conf import settings +from django.utils import timezone +from xmltodict import parse + +from abonapp.models import Abon +from abonapp.pay_systems import allpay + +rf = RequestFactory() +SERVICE_ID = getattr(settings, 'PAY_SERV_ID') +SECRET = getattr(settings, 'PAY_SECRET') + + +def _make_sign(act: int, pay_account: str, serv_id: str, pay_id): + md = md5() + s = "%d_%s_%s_%s_%s" % (act, pay_account, serv_id, pay_id, SECRET) + md.update(bytes(s, 'utf-8')) + return md.hexdigest() + + +class AllPayTestCase(TestCase): + pay_url = '/' + time_format = '%d.%m.%Y %H:%M' + + def setUp(self): + a1 = Abon.objects.create_user( + telephone='+79785276481', + username='pay_account1', + password='passw1' + ) + a1.ballance = -13.12 + a1.fio = 'Test Name' + a1.save(update_fields=['ballance', 'fio']) + # Abon.objects.create_user( + # telephone='+79788163841', + # username='pay_account2', + # password='passw2' + # ) + + def user_pay_view(self): + print('test_user_pay_view') + current_date = timezone.now().strftime(self.time_format) + r = allpay(rf.get(self.pay_url, { + 'ACT': 1, + 'PAY_ACCOUNT': 'pay_account1', + 'SERVICE_ID': SERVICE_ID, + 'PAY_ID': '840ab457-e7d1-4494-8197-9570da035170', + 'TRADE_POINT': 'term1', + 'SIGN': _make_sign(1, 'pay_account1', SERVICE_ID, '840ab457-e7d1-4494-8197-9570da035170') + } + )) + r = r.content.decode('utf-8') + self.assertXMLEqual(r, ''.join([ + "", + "-13.12", + "Test Name", + "pay_account1", + "%s" % SERVICE_ID, + "10.0", + "5000", + "21", + "%s" % current_date, + "" + ])) + + def user_pay_pay(self): + print('test_user_pay_pay') + current_date = timezone.now().strftime(self.time_format) + r = allpay(rf.get(self.pay_url, { + 'ACT': 4, + 'PAY_ACCOUNT': 'pay_account1', + 'PAY_AMOUNT': 18.21, + 'RECEIPT_NUM': 2126235, + 'SERVICE_ID': SERVICE_ID, + 'PAY_ID': '840ab457-e7d1-4494-8197-9570da035170', + 'TRADE_POINT': 'term1', + 'SIGN': _make_sign(4, 'pay_account1', SERVICE_ID, '840ab457-e7d1-4494-8197-9570da035170') + })) + r = r.content.decode('utf-8') + xml = ''.join([ + "", + "840ab457-e7d1-4494-8197-9570da035170", + "%s" % SERVICE_ID, + "18.21", + "22", + "%s" % current_date, + "" + ]) + self.test_pay_time = current_date + self.assertXMLEqual(r, xml) + + def user_pay_check(self): + print('test_user_pay_check') + current_date = timezone.now().strftime(self.time_format) + r = allpay(rf.get(self.pay_url, + { + 'ACT': 7, + 'SERVICE_ID': SERVICE_ID, + 'PAY_ID': '840ab457-e7d1-4494-8197-9570da035170', + 'SIGN': _make_sign(7, '', SERVICE_ID, '840ab457-e7d1-4494-8197-9570da035170') + } + )) + r = r.content.decode('utf-8') + xml = ''.join([ + "", + "11", + "%s" % current_date, + "", + "840ab457-e7d1-4494-8197-9570da035170", + "%s" % SERVICE_ID, + "18.21", + "111", + "%s" % self.test_pay_time, + "" + "" + ]) + self.assertXMLEqual(r, xml) + + def check_ballance(self): + print('check_ballance') + r = allpay(rf.get(self.pay_url, + { + 'ACT': 1, + 'PAY_ACCOUNT': 'pay_account1', + 'SERVICE_ID': SERVICE_ID, + 'PAY_ID': '840ab457-e7d1-4494-8197-9570da035170', + 'TRADE_POINT': 'term1', + 'SIGN': _make_sign(1, 'pay_account1', SERVICE_ID, '840ab457-e7d1-4494-8197-9570da035170') + } + )) + r = r.content.decode('utf-8') + r = parse(r) + bl = float(r['pay-response']['balance']) + self.assertEqual(bl, 5.09) + + def test_client_does_not_exist(self): + print('test_client_does_not_exist') + current_date = timezone.now().strftime(self.time_format) + r = allpay(rf.get(self.pay_url, { + 'ACT': 1, + 'PAY_ACCOUNT': 'not_existing_acc', + 'SERVICE_ID': SERVICE_ID, + 'PAY_ID': '840ab457-e7d1-4494-8197-9570da035170', + 'TRADE_POINT': 'term1', + 'SIGN': _make_sign(1, 'not_existing_acc', SERVICE_ID, '840ab457-e7d1-4494-8197-9570da035170') + } + )) + r = r.content.decode('utf-8') + self.assertXMLEqual(r, ''.join([ + "", + "-40", + "%s" % current_date, + "" + ])) + + def try_pay_double(self): + print('try_pay_double') + r = allpay(rf.get(self.pay_url, { + 'ACT': 4, + 'PAY_ACCOUNT': 'pay_account1', + 'SERVICE_ID': SERVICE_ID, + 'PAY_ID': '840ab457-e7d1-4494-8197-9570da035170', + 'TRADE_POINT': 'term1', + 'SIGN': _make_sign(4, 'pay_account1', SERVICE_ID, '840ab457-e7d1-4494-8197-9570da035170') + })) + r = r.content.decode('utf-8') + r = parse(r) + status_code = int(r['pay-response']['status_code']) + self.assertEqual(status_code, -100) + + def non_existing_pay(self): + print('non_existing_pay') + current_date = timezone.now().strftime(self.time_format) + uuid = '9f154e93-d800-419a-92f7-da33529138be' + r = allpay(rf.get(self.pay_url, { + 'ACT': 7, + 'SERVICE_ID': SERVICE_ID, + 'PAY_ID': uuid, + 'SIGN': _make_sign(7, '', SERVICE_ID, uuid) + })) + r = r.content.decode('utf-8') + xml = ''.join([ + "", + "-10", + "%s" % current_date, + "" + ]) + self.assertXMLEqual(r, xml) + + def test_pays(self): + self.user_pay_view() + self.user_pay_pay() + self.user_pay_check() + self.check_ballance() + self.try_pay_double() + self.non_existing_pay() diff --git a/djing/local_settings.py.template b/djing/local_settings.py.template index 6686794..a3b6704 100644 --- a/djing/local_settings.py.template +++ b/djing/local_settings.py.template @@ -25,7 +25,11 @@ DATABASES = { 'NAME': 'djing_db', 'USER': 'DJING_MYSQL_USERNAME', # You can change the user name 'PASSWORD': 'DJING_MYSQL_PASSWORD', # You can change the password - 'HOST': 'localhost' + 'HOST': 'localhost', + 'TEST': { + 'CHARSET': 'utf8', + 'COLLATION': 'utf8_general_ci' + } } } diff --git a/requirements.txt b/requirements.txt index 2ab81bd..0083cb2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,4 +22,7 @@ webdavclient pyst2 django-jsonview django-bitfield -transliterate \ No newline at end of file +transliterate + +# django-xmlview for pay system allpay +-e git://github.com/nerosketch/django-xmlview.git#egg=django-xmlview