paypal subscriptions - stub
[wolnelektury.git] / src / paypal / rest.py
diff --git a/src/paypal/rest.py b/src/paypal/rest.py
new file mode 100644 (file)
index 0000000..68ac30f
--- /dev/null
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
+from datetime import timedelta
+
+import paypalrestsdk
+import pytz
+from django.contrib.sites.models import Site
+from django.core.urlresolvers import reverse
+from django.utils import timezone
+from paypalrestsdk import BillingPlan, BillingAgreement, ResourceNotFound
+from django.conf import settings
+from .models import BillingPlan as BillingPlanModel
+
+paypalrestsdk.configure(settings.PAYPAL_CONFIG)
+
+
+class PaypalError(Exception):
+    pass
+
+
+def absolute_url(url_name):
+    return "http://%s%s" % (Site.objects.get_current().domain, reverse(url_name))
+
+
+def create_plan(amount):
+    billing_plan = BillingPlan({
+        "name": "Cykliczna darowizna na Wolne Lektury: %s zł" % amount,
+        "description": "Cykliczna darowizna na wsparcie Wolnych Lektur",
+        "merchant_preferences": {
+            "auto_bill_amount": "yes",
+            "return_url": absolute_url('paypal_return'),
+            "cancel_url": absolute_url('paypal_cancel'),
+            # "initial_fail_amount_action": "continue",
+            "max_fail_attempts": "3",
+        },
+        "payment_definitions": [
+            {
+                "amount": {
+                    "currency": "PLN",
+                    "value": str(amount),
+                },
+                "cycles": "0",
+                "frequency": "MONTH",
+                "frequency_interval": "1",
+                "name": "Cykliczna darowizna",
+                "type": "REGULAR",
+            }
+        ],
+        "type": "INFINITE",
+    })
+
+    if not billing_plan.create():
+        raise PaypalError(billing_plan.error)
+    if not billing_plan.activate():
+        raise PaypalError(billing_plan.error)
+    plan, created = BillingPlanModel.objects.get_or_create(amount=amount, defaults={'plan_id': billing_plan.id})
+    return plan.plan_id
+
+
+def get_link(links, rel):
+    for link in links:
+        if link.rel == rel:
+            return link.href
+
+
+def create_agreement(amount):
+    try:
+        plan = BillingPlanModel.objects.get(amount=amount)
+    except BillingPlanModel.DoesNotExist:
+        plan_id = create_plan(amount)
+    else:
+        plan_id = plan.plan_id
+    start = (timezone.now() + timedelta(0, 3600*24)).astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
+    billing_agreement = BillingAgreement({
+        "name": "Subskrypcja klubu WL",
+        "description": "Cykliczne wspieranie Wolnych Lektur kwotą %s złotych" % amount,
+        "start_date": start,
+        "plan": {
+            "id": plan_id,
+        },
+        "payer": {
+            "payment_method": "paypal"
+        },
+    })
+
+    response = billing_agreement.create()
+    if response:
+        return billing_agreement
+    else:
+        raise PaypalError(billing_agreement.error)
+
+
+def agreement_approval_url(amount):
+    agreement = create_agreement(amount)
+    return get_link(agreement.links, 'approval_url')
+
+
+def get_agreement(agreement_id):
+    try:
+        return BillingAgreement.find(agreement_id)
+    except ResourceNotFound:
+        return None
+
+
+def check_agreement(agreement_id):
+    a = get_agreement(agreement_id)
+    if a:
+        return a.state == 'Active'
+
+
+def execute_agreement(token):
+    return BillingAgreement.execute(token)