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',
94 'form': forms.PayUCardTokenForm(),
95 'pos': POSS[self.pos_id],
96 'widget_args': widget_args,
97 'widget_sig': widget_sig,
102 def pay(self, request, schedule):
103 # Create order, put it and see what happens next.
104 from .models import PayUOrder
105 if request is not None:
106 ip = request.META['REMOTE_ADDR']
111 if not self.needs_retry(schedule):
114 order = PayUOrder.objects.create(
121 def needs_retry(self, schedule):
122 retry_last = schedule.payuorder_set.exclude(
123 created_at=None).order_by('-created_at').first()
124 if retry_last is None:
128 days_since_last = (n - retry_last.created_at.date()).days
131 schedule.expires_at.date(),
132 settings.CLUB_RETRIES_START
134 retry_days = (n - retry_start).days
136 if retry_days > settings.CLUB_RETRY_DAYS_MAX:
139 if retry_days > settings.CLUB_RETRY_DAYS_DAILY:
140 print('retry less often now')
141 return days_since_last > settings.CLUB_RETRY_LESS
142 return days_since_last > 0
145 class PayPal(PaymentMethod):
148 template_name = 'club/payment/paypal.html'
152 def invite_widget(self, schedule, request):
153 return render_to_string(
154 'club/payment/paypal_invite.html',
156 '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