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 raise NotImplementedError
25 class PayU(PaymentMethod):
27 expiration_reliable = True
31 def __init__(self, pos_id):
34 def invite_widget(self, schedule, request):
35 return render_to_string(
36 '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'
58 expiration_reliable = True
62 def __init__(self, pos_id):
65 def initiate(self, request, schedule):
66 return reverse('club_payu_rec_payment', args=[schedule.key])
68 def invite_widget(self, schedule, request):
70 pos = POSS[self.pos_id]
72 'merchant-pos-id': pos.pos_id,
73 'shop-name': "SHOW NAME",
74 'total-amount': str(int(schedule.amount * 100)),
75 'currency-code': pos.currency_code,
76 'customer-language': get_language(), # filter to pos.languages
77 'customer-email': schedule.email,
79 'recurring-payment': 'true',
83 "".join(v for (k, v) in sorted(widget_args.items())) +
88 return render_to_string(
89 'payu/rec_widget.html',
92 'form': forms.PayUCardTokenForm(),
93 'pos': POSS[self.pos_id],
94 'widget_args': widget_args,
95 'widget_sig': widget_sig,
100 def pay(self, request, schedule):
101 # Create order, put it and see what happens next.
102 from .models import PayUOrder
103 if request is not None:
104 ip = request.META['REMOTE_ADDR']
109 if not self.needs_retry(schedule):
112 order = PayUOrder.objects.create(
119 def needs_retry(self, schedule):
120 retry_last = schedule.payuorder_set.exclude(
121 created_at=None).order_by('-created_at').first()
122 if retry_last is None:
126 days_since_last = (n - retry_last.created_at.date()).days
129 schedule.expires_at.date(),
130 settings.CLUB_RETRIES_START
132 retry_days = (n - retry_start).days
134 if retry_days > settings.CLUB_RETRY_DAYS_MAX:
137 if retry_days > settings.CLUB_RETRY_DAYS_DAILY:
138 print('retry less often now')
139 return days_since_last > settings.CLUB_RETRY_LESS
140 return days_since_last > 0
143 class PayPal(PaymentMethod):
149 def invite_widget(self, schedule, request):
150 if settings.PAYPAL_ENABLED:
151 return render_to_string(
152 'club/payment/paypal_invite.html',
154 'schedule': schedule,
161 def initiate(self, request, schedule):
162 app = request.GET.get('app')
163 return agreement_approval_url(schedule.amount, schedule.key, app=app)
165 def pay(self, request, schedule):
166 from datetime import date, timedelta, datetime, timezone
167 tomorrow = datetime(*(date.today() + timedelta(2)).timetuple()[:3], tzinfo=timezone.utc)
169 for ba in schedule.billingagreement_set.all():
170 active = ba.check_agreement()
176 schedule.expires_at = tomorrow
182 pos = getattr(settings, 'CLUB_PAYU_RECURRING_POS', None)
184 recurring_payment_method = PayURe(pos)
185 methods.append(recurring_payment_method)
187 recurring_payment_method = None
189 pos = getattr(settings, 'CLUB_PAYU_POS', None)
191 single_payment_method = PayU(pos)
192 methods.append(single_payment_method)
194 single_payment_method = None