@@ -68,10 +68,10 @@ import frappe | |||||
import json | import json | ||||
from frappe import _ | from frappe import _ | ||||
from datetime import datetime | from datetime import datetime | ||||
from frappe.utils import get_url, call_hook_method, cint, get_timestamp, cstr, now, date_diff, get_datetime | |||||
from six.moves.urllib.parse import urlencode | from six.moves.urllib.parse import urlencode | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
from frappe.integrations.utils import create_request_log, make_post_request, create_payment_gateway | from frappe.integrations.utils import create_request_log, make_post_request, create_payment_gateway | ||||
from frappe.utils import get_url, call_hook_method, cint, get_timestamp, cstr, now, date_diff, get_datetime | |||||
api_path = '/api/method/frappe.integrations.doctype.paypal_settings.paypal_settings' | api_path = '/api/method/frappe.integrations.doctype.paypal_settings.paypal_settings' | ||||
@@ -367,3 +367,53 @@ def manage_recurring_payment_profile_status(profile_id, action, args, url): | |||||
if response.get("ACK")[0] != "Success": | if response.get("ACK")[0] != "Success": | ||||
frappe.throw(_("Failed while amending subscription")) | frappe.throw(_("Failed while amending subscription")) | ||||
@frappe.whitelist(allow_guest=True) | |||||
def ipn_handler(): | |||||
try: | |||||
data = frappe.local.form_dict | |||||
validate_ipn_request(data) | |||||
data.update({ | |||||
"payment_gateway": "PayPal" | |||||
}) | |||||
doc = frappe.get_doc({ | |||||
"data": json.dumps(frappe.local.form_dict), | |||||
"doctype": "Integration Request", | |||||
"integration_type": "Subscription Notification", | |||||
"status": "Queued" | |||||
}).insert(ignore_permissions=True) | |||||
frappe.db.commit() | |||||
frappe.enqueue(method='frappe.integrations.doctype.paypal_settings.paypal_settings.handle_subscription_notification', | |||||
queue='long', timeout=600, is_async=True, **{"doctype": "Integration Request", "docname": doc.name}) | |||||
except frappe.InvalidStatusError: | |||||
pass | |||||
except Exception as e: | |||||
frappe.log(frappe.log_error(title=e)) | |||||
def validate_ipn_request(data): | |||||
def _throw(): | |||||
frappe.throw(_("In Valid Request"), exc=frappe.InvalidStatusError) | |||||
if not data.get("recurring_payment_id"): | |||||
_throw() | |||||
doc = frappe.get_doc("PayPal Settings") | |||||
params, url = doc.get_paypal_params_and_url() | |||||
params.update({ | |||||
"METHOD": "GetRecurringPaymentsProfileDetails", | |||||
"PROFILEID": data.get("recurring_payment_id") | |||||
}) | |||||
params = urlencode(params) | |||||
res = make_post_request(url=url, data=params.encode("utf-8")) | |||||
if res['ACK'][0] != 'Success': | |||||
_throw() | |||||
def handle_subscription_notification(doctype, docname): | |||||
call_hook_method("handle_subscription_notification", doctype=doctype, docname=docname) |
@@ -119,7 +119,6 @@ class RazorpaySettings(Document): | |||||
"content-type": "application/json" | "content-type": "application/json" | ||||
} | } | ||||
) | ) | ||||
if not resp.get('id'): | if not resp.get('id'): | ||||
frappe.log_error(str(resp), 'Razorpay Failed while creating subscription') | frappe.log_error(str(resp), 'Razorpay Failed while creating subscription') | ||||
except: | except: | ||||
@@ -283,13 +282,12 @@ class RazorpaySettings(Document): | |||||
}) | }) | ||||
return settings | return settings | ||||
def cancel_subscription(self, subscription_id): | def cancel_subscription(self, subscription_id): | ||||
settings = self.get_settings() | |||||
settings = self.get_settings({}) | |||||
try: | try: | ||||
resp = make_get_request("https://api.razorpay.com/v1/subscriptions/{0}/cancel" | |||||
resp = make_post_request("https://api.razorpay.com/v1/subscriptions/{0}/cancel" | |||||
.format(subscription_id), auth=(settings.api_key, | .format(subscription_id), auth=(settings.api_key, | ||||
settings.api_secret)) | settings.api_secret)) | ||||
except Exception: | except Exception: | ||||
@@ -329,5 +327,54 @@ def capture_payment(is_sandbox=False, sanbox_response=None): | |||||
def convert_rupee_to_paisa(**kwargs): | def convert_rupee_to_paisa(**kwargs): | ||||
for addon in kwargs.get('addons'): | for addon in kwargs.get('addons'): | ||||
addon['item']['amount'] *= 100 | addon['item']['amount'] *= 100 | ||||
frappe.conf.converted_rupee_to_paisa = True | |||||
frappe.conf.converted_rupee_to_paisa = True | |||||
@frappe.whitelist(allow_guest=True) | |||||
def razorpay_subscription_callback(): | |||||
try: | |||||
data = frappe.local.form_dict | |||||
validate_payment_callback(data) | |||||
data.update({ | |||||
"payment_gateway": "Razorpay" | |||||
}) | |||||
doc = frappe.get_doc({ | |||||
"data": json.dumps(frappe.local.form_dict), | |||||
"doctype": "Integration Request", | |||||
"integration_type": "Subscription Notification", | |||||
"status": "Queued" | |||||
}).insert(ignore_permissions=True) | |||||
frappe.db.commit() | |||||
frappe.enqueue(method='frappe.integrations.doctype.razorpay_settings.razorpay_settings.handle_subscription_notification', | |||||
queue='long', timeout=600, is_async=True, **{"doctype": "Integration Request", "docname": doc.name}) | |||||
except frappe.InvalidStatusError: | |||||
pass | |||||
except Exception as e: | |||||
frappe.log(frappe.log_error(title=e)) | |||||
def validate_payment_callback(data): | |||||
def _throw(): | |||||
frappe.throw(_("Invalid Subscription"), exc=frappe.InvalidStatusError) | |||||
subscription_id = data.get('payload').get("subscription").get("entity").get("id") | |||||
if not(subscription_id): | |||||
_throw() | |||||
controller = frappe.get_doc("Razorpay Settings") | |||||
settings = controller.get_settings(data) | |||||
resp = make_get_request("https://api.razorpay.com/v1/subscriptions/{0}".format(subscription_id), | |||||
auth=(settings.api_key, settings.api_secret)) | |||||
if resp.get("status") != "active": | |||||
_throw() | |||||
def handle_subscription_notification(doctype, docname): | |||||
call_hook_method("handle_subscription_notification", doctype=doctype, docname=docname) |
@@ -4,6 +4,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
no_cache = True | |||||
def get_context(context): | def get_context(context): | ||||
token = frappe.local.form_dict.token | token = frappe.local.form_dict.token |