Browse Source

Support for paypal subscription

pull/2/head
Saurabh 6 years ago
parent
commit
fd3b828b17
1 changed files with 117 additions and 14 deletions
  1. +117
    -14
      payments/payment_gateways/doctype/paypal_settings/paypal_settings.py

+ 117
- 14
payments/payment_gateways/doctype/paypal_settings/paypal_settings.py View File

@@ -28,7 +28,14 @@ Example:
"payer_name": "Nuran Verkleij",
"order_id": "111",
"currency": "USD",
"payment_gateway": "Razorpay"
"payment_gateway": "Razorpay",
"subscription_details": {
"plan_id": "plan_12313", # if Required
"start_date": "2018-08-30",
"billing_period": "Month" #(Day, Week, SemiMonth, Month, Year),
"billing_frequency": 1,
"customer_notify": 1
}
}

# redirect the user to this url
@@ -59,7 +66,8 @@ from __future__ import unicode_literals
import frappe
import json
from frappe import _
from frappe.utils import get_url, call_hook_method, cint
from datetime import datetime
from frappe.utils import get_url, call_hook_method, cint, get_timestamp
from six.moves.urllib.parse import urlencode
from frappe.model.document import Document
from frappe.integrations.utils import create_request_log, make_post_request, create_payment_gateway
@@ -124,7 +132,7 @@ class PayPalSettings(Document):
def get_payment_url(self, **kwargs):
setattr(self, "use_sandbox", cint(kwargs.get("use_sandbox", 0)))

response = self.execute_set_express_checkout(kwargs["amount"], kwargs["currency"])
response = self.execute_set_express_checkout(**kwargs)

if self.paypal_sandbox or self.use_sandbox:
return_url = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={0}"
@@ -135,21 +143,31 @@ class PayPalSettings(Document):
"token": response.get("TOKEN")[0],
"correlation_id": response.get("CORRELATIONID")[0]
})
print(kwargs)
self.integration_request = create_request_log(kwargs, "Remote", "PayPal", response.get("TOKEN")[0])
print(return_url.format(kwargs["token"]))
return return_url.format(kwargs["token"])

def execute_set_express_checkout(self, amount, currency):
def execute_set_express_checkout(self, **kwargs):
params, url = self.get_paypal_params_and_url()

params.update({
"METHOD": "SetExpressCheckout",
"PAYMENTREQUEST_0_PAYMENTACTION": "SALE",
"PAYMENTREQUEST_0_AMT": amount,
"PAYMENTREQUEST_0_CURRENCYCODE": currency.upper(),
"returnUrl": get_url("/api/method/frappe.integrations.doctype.paypal_settings.paypal_settings.get_express_checkout_details"),
"cancelUrl": get_url("/payment-cancel")
})
if kwargs.get('subscription_details'):
params.update({
"L_BILLINGTYPE0": "RecurringPayments", #The type of billing agreement
"L_BILLINGAGREEMENTDESCRIPTION0": kwargs['description']
})
else:
params.update({
"PAYMENTREQUEST_0_PAYMENTACTION": "SALE",
"PAYMENTREQUEST_0_AMT": kwargs['amount'],
"PAYMENTREQUEST_0_CURRENCYCODE": kwargs['currency'].upper(),
})

params = urlencode(params)

@@ -181,14 +199,16 @@ def get_express_checkout_details(token):

return

doc = frappe.get_doc("Integration Request", token)
update_integration_request_status(token, {
"payerid": response.get("PAYERID")[0],
"payer_email": response.get("EMAIL")[0]
}, "Authorized")
}, "Authorized", doc=doc)

frappe.local.response["type"] = "redirect"
frappe.local.response["location"] = get_url( \
"/api/method/frappe.integrations.doctype.paypal_settings.paypal_settings.confirm_payment?token={0}".format(token))
frappe.local.response["location"] = get_redirect_uri(doc, token, response.get("PAYERID")[0])

except Exception:
frappe.log_error(frappe.get_traceback())
@@ -251,5 +271,88 @@ def confirm_payment(token):
except Exception:
frappe.log_error(frappe.get_traceback())

def update_integration_request_status(token, data, status, error=False):
frappe.get_doc("Integration Request", token).update_status(data, status)
@frappe.whitelist(allow_guest=True, xss_safe=True)
def create_recurring_profile(token, payerid):
try:
redirect = True
status_changed_to, redirect_to = None, None

doc = frappe.get_doc("PayPal Settings")
doc.setup_sandbox_env(token)

integration_request = frappe.get_doc("Integration Request", token)
data = json.loads(integration_request.data)

subscription_details = data.get("subscription_details")
redirect_to = data.get('redirect_to') or None
redirect_message = data.get('redirect_message') or None

params, url = doc.get_paypal_params_and_url()
params.update({
"METHOD": "CreateRecurringPaymentsProfile",
"PAYERID": payerid,
"TOKEN": token,
"DESC": data.get("description"),
"BILLINGPERIOD": subscription_details.get("billing_period"),
"BILLINGFREQUENCY": subscription_details.get("billing_frequency"),
"AMT": data.get("amount"),
"CURRENCYCODE": data.get("currency").upper()
})

if subscription_details.get("start_date"):
starts_at = subscription_details.get("start_date")
else:
starts_at = frappe.utils.now()

params.update({
"PROFILESTARTDATE": datetime.utcfromtimestamp(get_timestamp(starts_at)).isoformat()
})

response = make_post_request(url, data=params)

if response.get("ACK")[0] == "Success":
update_integration_request_status(token, {
"profile_id": response.get("PROFILEID")[0],
}, "Completed")

if data.get("reference_doctype") and data.get("reference_docname"):
frappe.flags.data = data
custom_redirect_to = frappe.get_doc(data.get("reference_doctype"),
data.get("reference_docname")).run_method("on_payment_authorized", "Completed")
frappe.db.commit()

if custom_redirect_to:
redirect_to = custom_redirect_to

redirect_url = '/integrations/payment-success'
else:
redirect_url = "/integrations/payment-failed"

if redirect_to:
redirect_url += '?' + urlencode({'redirect_to': redirect_to})
if redirect_message:
redirect_url += '&' + urlencode({'redirect_message': redirect_message})

# this is done so that functions called via hooks can update flags.redirect_to
if redirect:
frappe.local.response["type"] = "redirect"
frappe.local.response["location"] = get_url(redirect_url)

except Exception:
frappe.log_error(frappe.get_traceback())

def update_integration_request_status(token, data, status, error=False, doc=None):
if not doc:
doc = frappe.get_doc("Integration Request", token)

doc.update_status(data, status)

def get_redirect_uri(doc, token, payerid):
data = json.loads(doc.data)
if data.get("subscription_details"):
return get_url( \
"/api/method/frappe.integrations.doctype.paypal_settings.paypal_settings.create_recurring_profile?token={0}&payerid={1}".format(token, payerid))
else:
return get_url( \
"/api/method/frappe.integrations.doctype.paypal_settings.paypal_settings.confirm_payment?token={0}".format(token))

Loading…
Cancel
Save