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
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):
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": "Subskrypcja klubu WL",
78 "description": "Cykliczne wspieranie Wolnych Lektur kwotą %s złotych" % amount,
84 "payment_method": "paypal"
88 response = billing_agreement.create()
90 return billing_agreement
92 raise PaypalError(billing_agreement.error)
95 def agreement_approval_url(amount):
96 agreement = create_agreement(amount)
97 return get_link(agreement.links, 'approval_url')
100 def get_agreement(agreement_id):
102 return BillingAgreement.find(agreement_id)
103 except ResourceNotFound:
107 def check_agreement(agreement_id):
108 a = get_agreement(agreement_id)
110 return a.state == 'Active'
113 def execute_agreement(token):
114 return BillingAgreement.execute(token)