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 paypalrestsdk import BillingPlan, BillingAgreement, ResourceNotFound
13 from django.conf import settings
14 from .models import BillingPlan as BillingPlanModel, BillingAgreement as BillingAgreementModel
16 paypalrestsdk.configure(settings.PAYPAL_CONFIG)
19 class PaypalError(Exception):
23 def absolute_url(url_name):
24 return "http://%s%s" % (Site.objects.get_current().domain, reverse(url_name))
27 def create_plan(amount):
28 billing_plan = BillingPlan({
29 "name": "Cykliczna darowizna na Wolne Lektury: %s zł" % amount,
30 "description": "Cykliczna darowizna na wsparcie Wolnych Lektur",
31 "merchant_preferences": {
32 "auto_bill_amount": "yes",
33 "return_url": absolute_url('paypal_return'),
34 "cancel_url": absolute_url('paypal_cancel'),
35 # "initial_fail_amount_action": "continue",
36 "max_fail_attempts": "3",
38 "payment_definitions": [
46 "frequency_interval": "1",
47 "name": "Cykliczna darowizna",
54 if not billing_plan.create():
55 raise PaypalError(billing_plan.error)
56 if not billing_plan.activate():
57 raise PaypalError(billing_plan.error)
58 plan, created = BillingPlanModel.objects.get_or_create(amount=amount, defaults={'plan_id': billing_plan.id})
62 def get_link(links, rel):
68 def create_agreement(amount, app=False):
70 plan = BillingPlanModel.objects.get(amount=amount)
71 except BillingPlanModel.DoesNotExist:
72 plan_id = create_plan(amount)
74 plan_id = plan.plan_id
75 start = (timezone.now() + timedelta(0, 3600*24)).astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
76 billing_agreement = BillingAgreement({
77 "name": u"Subskrypcja klubu WL",
78 "description": u"Stałe wsparcie Wolnych Lektur kwotą %s złotych" % amount,
84 "payment_method": "paypal"
88 billing_agreement['override_merchant_preferences'] = {
89 'return_url': absolute_url('paypal_app_return'),
92 response = billing_agreement.create()
94 return billing_agreement
96 raise PaypalError(billing_agreement.error)
99 def agreement_approval_url(amount, app=False):
100 agreement = create_agreement(amount, app=app)
101 return get_link(agreement.links, 'approval_url')
104 def get_agreement(agreement_id):
106 return BillingAgreement.find(agreement_id)
107 except ResourceNotFound:
111 def check_agreement(agreement_id):
112 a = get_agreement(agreement_id)
114 return a.state == 'Active'
117 def user_is_subscribed(user):
119 agreement = BillingAgreementModel.objects.get(user=user)
120 except BillingAgreementModel.DoesNotExist:
122 return agreement.check_agreement()
125 def execute_agreement(token):
126 return BillingAgreement.execute(token)