1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 from datetime import timedelta
9 from django.contrib.sites.models import Site
10 from django.core.urlresolvers import reverse
11 from django.utils import timezone
12 from django.conf import settings
13 from .models import BillingPlan, BillingAgreement
15 paypalrestsdk.configure(settings.PAYPAL_CONFIG)
18 class PaypalError(Exception):
22 def absolute_url(url_name):
23 return "http://%s%s" % (Site.objects.get_current().domain, reverse(url_name))
26 def create_plan(amount):
27 billing_plan = paypalrestsdk.BillingPlan({
28 "name": "Cykliczna darowizna na Wolne Lektury: %s zł" % amount,
29 "description": "Cykliczna darowizna na wsparcie Wolnych Lektur",
30 "merchant_preferences": {
31 "auto_bill_amount": "yes",
32 "return_url": absolute_url('paypal_return'),
33 "cancel_url": absolute_url('paypal_cancel'),
34 # "initial_fail_amount_action": "continue",
35 "max_fail_attempts": "3",
37 "payment_definitions": [
45 "frequency_interval": "1",
46 "name": "Cykliczna darowizna",
53 if not billing_plan.create():
54 raise PaypalError(billing_plan.error)
55 if not billing_plan.activate():
56 raise PaypalError(billing_plan.error)
57 plan, created = BillingPlan.objects.get_or_create(amount=amount, defaults={'plan_id': billing_plan.id})
61 def get_link(links, rel):
67 def create_agreement(amount, app=False):
69 plan = BillingPlan.objects.get(amount=amount)
70 except BillingPlan.DoesNotExist:
71 plan_id = create_plan(amount)
73 plan_id = plan.plan_id
74 start = (timezone.now() + timedelta(0, 3600*24)).astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
75 billing_agreement = paypalrestsdk.BillingAgreement({
76 "name": u"Subskrypcja klubu WL",
77 "description": u"Stałe wsparcie Wolnych Lektur kwotą %s złotych" % amount,
83 "payment_method": "paypal"
87 billing_agreement['override_merchant_preferences'] = {
88 'return_url': absolute_url('paypal_app_return'),
91 response = billing_agreement.create()
93 return billing_agreement
95 raise PaypalError(billing_agreement.error)
98 def agreement_approval_url(amount, app=False):
99 agreement = create_agreement(amount, app=app)
100 return get_link(agreement.links, 'approval_url')
103 def get_agreement(agreement_id):
105 return paypalrestsdk.BillingAgreement.find(agreement_id)
106 except paypalrestsdk.ResourceNotFound:
110 def check_agreement(agreement_id):
111 a = get_agreement(agreement_id)
113 return a.state == 'Active'
116 def user_is_subscribed(user):
117 agreements = BillingAgreement.objects.filter(user=user)
118 return any(agreement.check_agreement() for agreement in agreements)
121 def execute_agreement(token):
122 return paypalrestsdk.BillingAgreement.execute(token)