@@ -1248,6 +1248,10 @@ def logger(module=None, with_more_info=True): | |||
from frappe.utils.logger import get_logger | |||
return get_logger(module or 'default', with_more_info=with_more_info) | |||
def log_error(message, title=None): | |||
'''Log error to Scheduler Log''' | |||
get_doc(dict(doctype='Scheduler Log', error=str(message), method=title)).insert() | |||
def get_desk_link(doctype, name): | |||
return '<a href="#Form/{0}/{1}" style="font-weight: bold;">{2} {1}</a>'.format(doctype, name, _(doctype)) | |||
@@ -10,7 +10,7 @@ from frappe.utils.background_jobs import enqueue, get_jobs | |||
import json, urlparse | |||
from frappe.utils import get_request_session | |||
class IntegrationService(Document): | |||
class IntegrationService(Document): | |||
def on_update(self): | |||
if self.enabled: | |||
self.enable_service() | |||
@@ -25,7 +25,7 @@ class IntegrationService(Document): | |||
parameters = {} | |||
if self.custom_settings_json: | |||
parameters = json.loads(self.custom_settings_json) | |||
return parameters | |||
return parameters | |||
def install_fixtures(self): | |||
pass | |||
@@ -52,13 +52,13 @@ class IntegrationService(Document): | |||
try: | |||
s = get_request_session() | |||
res = s.get(url, data={}, auth=auth) | |||
res.raise_for_status() | |||
return res.json() | |||
frappe.flags.integration_request = s.get(url, data={}, auth=auth) | |||
frappe.flags.integration_request.raise_for_status() | |||
return frappe.flags.integration_request.json() | |||
except Exception, exc: | |||
raise exc | |||
def post_request(self, url, auth=None, data=None): | |||
if not auth: | |||
auth = '' | |||
@@ -68,31 +68,31 @@ class IntegrationService(Document): | |||
s = get_request_session() | |||
res = s.post(url, data=data, auth=auth) | |||
res.raise_for_status() | |||
if res.headers.get("content-type") == "text/plain; charset=utf-8": | |||
return urlparse.parse_qs(res.text) | |||
return res.json() | |||
except Exception, exc: | |||
raise exc | |||
def put_request(url, auth=None, data=None): | |||
pass | |||
def create_request(self, data, integration_type, service_name, name=None): | |||
if not isinstance(data, basestring): | |||
data = json.dumps(data) | |||
integration_request = frappe.get_doc({ | |||
"doctype": "Integration Request", | |||
"integration_type": integration_type, | |||
"integration_request_service": service_name, | |||
"data": data | |||
}) | |||
if name: | |||
integration_request.flags._name = name | |||
integration_request.insert(ignore_permissions=True) | |||
frappe.db.commit() | |||
@@ -111,7 +111,7 @@ def get_js_resouce(service): | |||
return { | |||
"js": getattr(controller, "js", "") | |||
} | |||
def get_integration_controller(service_name, setup=True): | |||
'''Returns integration controller module from app_name.integrations.{service}''' | |||
def load_from_app(app, service_name): | |||
@@ -126,12 +126,12 @@ def get_integration_controller(service_name, setup=True): | |||
for d in getattr(controller, key, []): | |||
tmp.append(frappe._dict(d)) | |||
setattr(controller, key, tmp) | |||
return controller | |||
except ImportError: | |||
pass | |||
for app in frappe.get_installed_apps(): | |||
controller = load_from_app(app, service_name) | |||
if controller: | |||
@@ -144,13 +144,13 @@ def get_integration_services(): | |||
services = [""] | |||
for app in frappe.get_installed_apps(): | |||
services.extend(frappe.get_hooks("integration_services", app_name = app)) | |||
return services | |||
def trigger_integration_service_events(): | |||
for service in frappe.get_all("Integration Service", filters={"enabled": 1}, fields=["name"]): | |||
controller = get_integration_controller(service.name, setup=False) | |||
if hasattr(controller, "scheduled_jobs"): | |||
for job in controller.scheduled_jobs: | |||
for event, handlers in job.items(): | |||
@@ -127,6 +127,7 @@ class Controller(IntegrationController): | |||
return self.authorize_payment() | |||
except Exception: | |||
frappe.log_error(frappe.get_traceback()) | |||
return{ | |||
"redirect_to": frappe.redirect_to_message(_('Server Error'), _("Seems issue with server's razorpay config. Don't worry, in case of failure amount will get refunded to your account.")), | |||
"status": 401 | |||
@@ -141,28 +142,45 @@ class Controller(IntegrationController): | |||
settings = self.get_settings() | |||
data = json.loads(self.integration_request.data) | |||
redirect_to = data.get('notes', {}).get('redirect_to') or None | |||
redirect_message = data.get('notes', {}).get('redirect_message') or None | |||
if self.integration_request.status != "Authorized": | |||
resp = self.get_request("https://api.razorpay.com/v1/payments/{0}" | |||
.format(self.data.razorpay_payment_id), auth=(settings.api_key, | |||
settings.api_secret)) | |||
try: | |||
resp = self.get_request("https://api.razorpay.com/v1/payments/{0}" | |||
.format(self.data.razorpay_payment_id), auth=(settings.api_key, | |||
settings.api_secret)) | |||
if resp.get("status") == "authorized": | |||
self.integration_request.db_set('status', 'Authorized', update_modified=False) | |||
self.flags.status_changed_to = "Authorized" | |||
except: | |||
frappe.log_error(frappe.get_traceback()) | |||
# failed | |||
pass | |||
if resp.get("status") == "authorized": | |||
self.integration_request.db_set('status', 'Authorized', update_modified=False) | |||
self.flags.status_changed_to = "Authorized" | |||
status = frappe.flags.integration_request.status_code | |||
if self.flags.status_changed_to == "Authorized": | |||
if self.data.reference_doctype and self.data.reference_docname: | |||
redirect_to = frappe.get_doc(self.data.reference_doctype, | |||
custom_redirect_to = frappe.get_doc(self.data.reference_doctype, | |||
self.data.reference_docname).run_method("on_payment_authorized", self.flags.status_changed_to) | |||
if not redirect_to: | |||
if data.get('redirect_to'): | |||
redirect_to = data.get('redirect_to') | |||
if custom_redirect_to: | |||
redirect_to = custom_redirect_to | |||
return { | |||
"redirect_to": redirect_to or "payment-success", | |||
"status": 200 | |||
} | |||
redirect_url = 'payment-success' | |||
else: | |||
redirect_url = 'payment-failed' | |||
if redirect_to: | |||
redirect_url += '?' + urllib.urlencode({'redirect_to': redirect_to}) | |||
if redirect_message: | |||
redirect_url += '&' + urllib.urlencode({'redirect_message': redirect_message}) | |||
return { | |||
"redirect_to": redirect_url, | |||
"status": status | |||
} | |||
def capture_payment(is_sandbox=False, sanbox_response=None): | |||
""" | |||
@@ -5,7 +5,6 @@ $(document).ready(function(){ | |||
"amount": cint({{ amount }} * 100), // 2000 paise = INR 20 | |||
"name": "{{ title }}", | |||
"description": "{{ description }}", | |||
"image": "{{ brand_image }}", | |||
"handler": function (response){ | |||
razorpay.make_payment_log(response, options, "{{ reference_doctype }}", "{{ reference_docname }}"); | |||
}, | |||
@@ -14,14 +13,7 @@ $(document).ready(function(){ | |||
"email": "{{ payer_email }}", | |||
"order_id": "{{ order_id }}" | |||
}, | |||
"notes": { | |||
"doctype": "{{ doctype }}", | |||
"name": "{{ name }}", | |||
"payment_request": "{{ name }}" // backward compatibility | |||
}, | |||
"theme": { | |||
"color": "#4B4C9D" | |||
} | |||
"notes": {{ frappe.form_dict|json }} | |||
}; | |||
var rzp = new Razorpay(options); | |||
@@ -1,12 +1,12 @@ | |||
{% extends "templates/web.html" %} | |||
{% block title %}Make Payment{% endblock %} | |||
{% block title %}{{ _("Payment Cancelled") }}{% endblock %} | |||
{%- block header -%} | |||
<h2>Payment Cancelled<h2> | |||
<h2>{{ _("Payment Cancelled") }}<h2> | |||
{% endblock %} | |||
{%- block page_content -%} | |||
<p>You have cancelled your payment.</p> | |||
<p>{{ _("You have cancelled the payment") }}</p> | |||
<p><br><a href="/">Back to home page</a></p> | |||
{% endblock %} |
@@ -1,12 +1,12 @@ | |||
{% extends "templates/web.html" %} | |||
{% block title %}Payment Failed{% endblock %} | |||
{% block title %}{{ _("Payment Failed") }}{% endblock %} | |||
{%- block header -%} | |||
<h2>Payment Failed<h2> | |||
<h2>{{ _("Payment Failed") }}<h2> | |||
{% endblock %} | |||
{%- block page_content -%} | |||
<p class="lead">Your payment has failed. Do you mind trying again?</p> | |||
<p><a href="/" class="btn btn-default">Back to Home</a></p> | |||
<p class="lead">{{ _("Oops. Your payment has failed.") }}</p> | |||
<p><a href="{{ frappe.form_dict.redirect_to or "/" }}" class="btn btn-primary">{{ frappe.form_dict.redirect_message or _("Continue") }}</a></p> | |||
{% endblock %} |
@@ -1,12 +1,13 @@ | |||
{% extends "templates/web.html" %} | |||
{% block title %}Payment Success{% endblock %} | |||
{% block title %}{{ _("Payment Success") }}{% endblock %} | |||
{%- block header -%} | |||
<h2>Payment Success<h2> | |||
<h2>{{ _("Payment Success") }}<h2> | |||
{% endblock %} | |||
{%- block page_content -%} | |||
<p class="lead">Your payment has succeeded.</p> | |||
<p><a href="/" class="btn btn-default">Back to Home</a></p> | |||
<p class="lead">{{ _("Your payment was successfully accepted") }}</p> | |||
<p><a href="{{ frappe.form_dict.redirect_to or "/" }}" | |||
class="btn btn-primary">{{ frappe.form_dict.redirect_message or _("Continue") }}</a></p> | |||
{% endblock %} |
@@ -17,13 +17,8 @@ expected_keys = ('amount', 'title', 'description', 'reference_doctype', 'referen | |||
def get_context(context): | |||
context.no_cache = 1 | |||
context.api_key = Controller().get_settings().api_key | |||
installed_apps = frappe.get_installed_apps() | |||
if 'erpnext' in installed_apps: | |||
context.brand_image = "/assets/erpnext/images/erp-icon.svg" | |||
else: | |||
context.brand_image = '/assets/frappe_theme/img/erp-icon.svg' | |||
# all these keys exist in form_dict | |||
if not (set(expected_keys) - set(frappe.form_dict.keys())): | |||
@@ -40,14 +35,14 @@ def get_context(context): | |||
@frappe.whitelist(allow_guest=True) | |||
def make_payment(razorpay_payment_id, options, reference_doctype, reference_docname): | |||
data = {} | |||
if isinstance(options, basestring): | |||
data = json.loads(options) | |||
data.update({ | |||
"razorpay_payment_id": razorpay_payment_id, | |||
"reference_docname": reference_docname, | |||
"reference_doctype": reference_doctype | |||
}) | |||
return Controller().create_request(data) |