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 datetime import timedelta
 
   8 from django.contrib.sites.models import Site
 
   9 from django.urls import reverse
 
  10 from django.utils import timezone
 
  11 from django.conf import settings
 
  12 from .models import BillingPlan, BillingAgreement
 
  14 paypalrestsdk.configure(settings.PAYPAL_CONFIG)
 
  17 class PaypalError(Exception):
 
  21 def absolute_url(url_name, kwargs=None):
 
  22     return "http://%s%s" % (Site.objects.get_current().domain, reverse(url_name, kwargs=kwargs))
 
  25 def create_plan(amount):
 
  26     billing_plan = paypalrestsdk.BillingPlan({
 
  27         "name": "Cykliczna darowizna na Wolne Lektury: %s zł" % amount,
 
  28         "description": "Cykliczna darowizna na wsparcie Wolnych Lektur",
 
  29         "merchant_preferences": {
 
  30             "auto_bill_amount": "yes",
 
  31             "return_url": absolute_url('paypal_return', {'key': '-'}),
 
  32             "cancel_url": absolute_url('paypal_cancel'),
 
  33             # "initial_fail_amount_action": "continue",
 
  34             "max_fail_attempts": "3",
 
  36         "payment_definitions": [
 
  44                 "frequency_interval": "1",
 
  45                 "name": "Cykliczna darowizna",
 
  52     if not billing_plan.create():
 
  53         raise PaypalError(billing_plan.error)
 
  54     if not billing_plan.activate():
 
  55         raise PaypalError(billing_plan.error)
 
  56     plan, created = BillingPlan.objects.get_or_create(amount=amount, defaults={'plan_id': billing_plan.id})
 
  60 def get_link(links, rel):
 
  66 def create_agreement(amount, key, app=False):
 
  68         plan = BillingPlan.objects.get(amount=amount)
 
  69     except BillingPlan.DoesNotExist:
 
  70         plan_id = create_plan(amount)
 
  72         plan_id = plan.plan_id
 
  73     start = (timezone.now() + timedelta(0, 3600*24)).astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
 
  74     billing_agreement = paypalrestsdk.BillingAgreement({
 
  75         "name": "Subskrypcja klubu WL",
 
  76         "description": "Stałe wsparcie Wolnych Lektur kwotą %s złotych" % amount,
 
  82             "payment_method": "paypal"
 
  86         billing_agreement['override_merchant_preferences'] = {
 
  87             'return_url': absolute_url('paypal_app_return', {'key': key}),
 
  90         billing_agreement['override_merchant_preferences'] = {
 
  91             'return_url': absolute_url('paypal_return', {'key': key}),
 
  95     response = billing_agreement.create()
 
  97         return billing_agreement
 
  99         raise PaypalError(billing_agreement.error)
 
 102 def agreement_approval_url(amount, key, app=False):
 
 103     agreement = create_agreement(amount, key, app=app)
 
 104     return get_link(agreement.links, 'approval_url')
 
 107 def get_agreement(agreement_id):
 
 109         return paypalrestsdk.BillingAgreement.find(agreement_id)
 
 110     except paypalrestsdk.ResourceNotFound:
 
 114 def check_agreement(agreement_id):
 
 115     a = get_agreement(agreement_id)
 
 117         return a.state == 'Active'
 
 120 def user_is_subscribed(user):
 
 121     agreements = BillingAgreement.objects.filter(user=user)
 
 122     return any(agreement.check_agreement() for agreement in agreements)
 
 125 def execute_agreement(token):
 
 126     return paypalrestsdk.BillingAgreement.execute(token)