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):
36 return render_to_string(
37 'club/payment/payu_invite.html',
43 def initiate(self, request, schedule):
44 # Create Order at once.
45 from .models import PayUOrder
46 order = PayUOrder.objects.create(
48 customer_ip=request.META['REMOTE_ADDR'],
54 class PayURe(PaymentMethod):
56 name = 'PayU recurring'
57 template_name = 'club/payment/payu-re.html'
59 expiration_reliable = True
63 def __init__(self, pos_id):
66 def initiate(self, request, schedule):
67 return reverse('club_payu_rec_payment', args=[schedule.key])
69 def invite_widget(self, schedule):
71 pos = POSS[self.pos_id]
73 'merchant-pos-id': pos.pos_id,
74 'shop-name': "SHOW NAME",
75 'total-amount': str(int(schedule.amount * 100)),
76 'currency-code': pos.currency_code,
77 'customer-language': get_language(), # filter to pos.languages
78 'customer-email': schedule.email,
80 'recurring-payment': 'true',
84 "".join(v for (k, v) in sorted(widget_args.items())) +
89 return render_to_string(
90 'payu/rec_widget.html',
92 'form': forms.PayUCardTokenForm(),
93 'pos': POSS[self.pos_id],
94 'widget_args': widget_args,
95 'widget_sig': widget_sig,
99 def pay(self, request, schedule):
100 # Create order, put it and see what happens next.
101 from .models import PayUOrder
102 if request is not None:
103 ip = request.META['REMOTE_ADDR']
108 if not self.needs_retry(schedule):
111 order = PayUOrder.objects.create(
118 def needs_retry(self, schedule):
119 retry_last = schedule.payuorder_set.exclude(
120 created_at=None).order_by('-created_at').first()
121 if retry_last is None:
125 days_since_last = (n - retry_last.created_at.date()).days
128 schedule.expires_at.date(),
129 settings.CLUB_RETRIES_START
131 retry_days = (n - retry_start).days
133 if retry_days > settings.CLUB_RETRY_DAYS_MAX:
136 if retry_days > settings.CLUB_RETRY_DAYS_DAILY:
137 print('retry less often now')
138 return days_since_last > settings.CLUB_RETRY_LESS
139 return days_since_last > 0
142 class PayPal(PaymentMethod):
145 template_name = 'club/payment/paypal.html'
149 def invite_widget(self, schedule):
150 return render_to_string(
151 'club/payment/paypal_invite.html',
153 'schedule': schedule,
157 def initiate(self, request, schedule):
158 app = request.GET.get('app')
159 return agreement_approval_url(schedule.amount, schedule.key, app=app)
161 def pay(self, request, schedule):
162 from datetime import date, timedelta, datetime, timezone
163 tomorrow = datetime(*(date.today() + timedelta(2)).timetuple()[:3], tzinfo=timezone.utc)
165 for ba in schedule.billingagreement_set.all():
166 active = ba.check_agreement()
172 schedule.expires_at = tomorrow
178 pos = getattr(settings, 'CLUB_PAYU_RECURRING_POS', None)
180 recurring_payment_method = PayURe(pos)
181 methods.append(recurring_payment_method)
183 recurring_payment_method = None
185 pos = getattr(settings, 'CLUB_PAYU_POS', None)
187 single_payment_method = PayU(pos)
188 methods.append(single_payment_method)
190 single_payment_method = None