1 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
4 from hashlib import sha256
5 from django.conf import settings
6 from django.urls import reverse
7 from django.utils.timezone import now
8 from django.utils.translation import get_language
9 from paypal.rest import agreement_approval_url
10 from django.template.loader import render_to_string
11 from .payu import POSS
14 class PaymentMethod(object):
17 expiration_reliable = False
21 def initiate(self, request, schedule):
22 return reverse('club_dummy_payment', args=[schedule.key])
25 class PayU(PaymentMethod):
27 expiration_reliable = True
30 template_name = 'club/payment/payu.html'
32 def __init__(self, pos_id):
35 def invite_widget(self, schedule, request):
36 return render_to_string(
37 'club/payment/payu_invite.html',
44 def initiate(self, request, schedule):
45 # Create Order at once.
46 from .models import PayUOrder
47 order = PayUOrder.objects.create(
49 customer_ip=request.META['REMOTE_ADDR'],
55 class PayURe(PaymentMethod):
57 name = 'PayU recurring'
58 template_name = 'club/payment/payu-re.html'
60 expiration_reliable = True
64 def __init__(self, pos_id):
67 def initiate(self, request, schedule):
68 return reverse('club_payu_rec_payment', args=[schedule.key])
70 def invite_widget(self, schedule, request):
72 pos = POSS[self.pos_id]
74 'merchant-pos-id': pos.pos_id,
75 'shop-name': "SHOW NAME",
76 'total-amount': str(int(schedule.amount * 100)),
77 'currency-code': pos.currency_code,
78 'customer-language': get_language(), # filter to pos.languages
79 'customer-email': schedule.email,
81 'recurring-payment': 'true',
85 "".join(v for (k, v) in sorted(widget_args.items())) +
90 return render_to_string(
91 'payu/rec_widget.html',
93 'form': forms.PayUCardTokenForm(),
94 'pos': POSS[self.pos_id],
95 'widget_args': widget_args,
96 'widget_sig': widget_sig,
101 def pay(self, request, schedule):
102 # Create order, put it and see what happens next.
103 from .models import PayUOrder
104 if request is not None:
105 ip = request.META['REMOTE_ADDR']
110 if not self.needs_retry(schedule):
113 order = PayUOrder.objects.create(
120 def needs_retry(self, schedule):
121 retry_last = schedule.payuorder_set.exclude(
122 created_at=None).order_by('-created_at').first()
123 if retry_last is None:
127 days_since_last = (n - retry_last.created_at.date()).days
130 schedule.expires_at.date(),
131 settings.CLUB_RETRIES_START
133 retry_days = (n - retry_start).days
135 if retry_days > settings.CLUB_RETRY_DAYS_MAX:
138 if retry_days > settings.CLUB_RETRY_DAYS_DAILY:
139 print('retry less often now')
140 return days_since_last > settings.CLUB_RETRY_LESS
141 return days_since_last > 0
144 class PayPal(PaymentMethod):
147 template_name = 'club/payment/paypal.html'
151 def invite_widget(self, schedule, request):
152 return render_to_string(
153 'club/payment/paypal_invite.html',
155 'schedule': schedule,
160 def initiate(self, request, schedule):
161 app = request.GET.get('app')
162 return agreement_approval_url(schedule.amount, schedule.key, app=app)
164 def pay(self, request, schedule):
165 from datetime import date, timedelta, datetime, timezone
166 tomorrow = datetime(*(date.today() + timedelta(2)).timetuple()[:3], tzinfo=timezone.utc)
168 for ba in schedule.billingagreement_set.all():
169 active = ba.check_agreement()
175 schedule.expires_at = tomorrow
181 pos = getattr(settings, 'CLUB_PAYU_RECURRING_POS', None)
183 recurring_payment_method = PayURe(pos)
184 methods.append(recurring_payment_method)
186 recurring_payment_method = None
188 pos = getattr(settings, 'CLUB_PAYU_POS', None)
190 single_payment_method = PayU(pos)
191 methods.append(single_payment_method)
193 single_payment_method = None