* [fix] remove razorpay from integration service * [fix] clean-up js side integration service dependancies * [fix] remove integration service, .py cleanup, move integration request to integration * [fix] move oauth to integrations and deprecate integration broker * [fix] mark services enabled and update integrations listing * [fix] V7.1 and V7.2 integration service related pathch fixes and move payment gateway dotype to core module * [fix] create payment gateway records if not exists * [fix] module page for integrations * [minor][fix] minor checks * [fix] remove integration broker module only if not allocated to any doctypepull/2/head
@@ -1,31 +1,8 @@ | |||||
// Copyright (c) 2016, Frappe Technologies and contributors | // Copyright (c) 2016, Frappe Technologies and contributors | ||||
// For license information, please see license.txt | // For license information, please see license.txt | ||||
frappe.provide("frappe.integration_service") | |||||
frappe.ui.form.on('PayPal Settings', { | frappe.ui.form.on('PayPal Settings', { | ||||
refresh: function(frm) { | refresh: function(frm) { | ||||
} | } | ||||
}); | }); | ||||
frappe.integration_service.paypal_settings = Class.extend({ | |||||
init: function(frm) { | |||||
}, | |||||
get_scheduler_job_info: function() { | |||||
return {} | |||||
}, | |||||
get_service_info: function(frm) { | |||||
frappe.call({ | |||||
method: "frappe.integrations.doctype.paypal_settings.paypal_settings.get_service_details", | |||||
callback: function(r){ | |||||
var integration_service_help = frm.fields_dict.integration_service_help.wrapper; | |||||
$(integration_service_help).empty(); | |||||
$(integration_service_help).append(r.message); | |||||
} | |||||
}) | |||||
} | |||||
}) |
@@ -9,9 +9,9 @@ | |||||
Example: | Example: | ||||
from frappe.integration_broker.doctype.integration_service.integration_service import get_integration_controller | |||||
from frappe.integrations.utils import get_payment_gateway_controller | |||||
controller = get_integration_controller("PayPal") | |||||
controller = get_payment_gateway_controller("PayPal") | |||||
controller().validate_transaction_currency(currency) | controller().validate_transaction_currency(currency) | ||||
### 2. Redirect for payment | ### 2. Redirect for payment | ||||
@@ -27,7 +27,8 @@ Example: | |||||
"payer_email": "NuranVerkleij@example.com", | "payer_email": "NuranVerkleij@example.com", | ||||
"payer_name": "Nuran Verkleij", | "payer_name": "Nuran Verkleij", | ||||
"order_id": "111", | "order_id": "111", | ||||
"currency": "USD" | |||||
"currency": "USD", | |||||
"payment_gateway": "Razorpay" | |||||
} | } | ||||
# redirect the user to this url | # redirect the user to this url | ||||
@@ -60,12 +61,11 @@ import json | |||||
from frappe import _ | from frappe import _ | ||||
from frappe.utils import get_url, call_hook_method, cint | from frappe.utils import get_url, call_hook_method, cint | ||||
from urllib import urlencode | from urllib import urlencode | ||||
from frappe.integration_broker.doctype.integration_service.integration_service import IntegrationService | |||||
from frappe.model.document import Document | |||||
import urllib | import urllib | ||||
from frappe.integrations.utils import create_request_log, make_post_request, create_payment_gateway | |||||
class PayPalSettings(IntegrationService): | |||||
service_name = "PayPal" | |||||
class PayPalSettings(Document): | |||||
supported_currencies = ["AUD", "BRL", "CAD", "CZK", "DKK", "EUR", "HKD", "HUF", "ILS", "JPY", "MYR", "MXN", | supported_currencies = ["AUD", "BRL", "CAD", "CZK", "DKK", "EUR", "HKD", "HUF", "ILS", "JPY", "MYR", "MXN", | ||||
"TWD", "NZD", "NOK", "PHP", "PLN", "GBP", "RUB", "SGD", "SEK", "CHF", "THB", "TRY", "USD"] | "TWD", "NZD", "NOK", "PHP", "PLN", "GBP", "RUB", "SGD", "SEK", "CHF", "THB", "TRY", "USD"] | ||||
@@ -77,20 +77,17 @@ class PayPalSettings(IntegrationService): | |||||
setattr(self, "use_sandbox", cint(frappe._dict(data).use_sandbox) or 0) | setattr(self, "use_sandbox", cint(frappe._dict(data).use_sandbox) or 0) | ||||
def validate(self): | def validate(self): | ||||
create_payment_gateway("PayPal") | |||||
call_hook_method('payment_gateway_enabled', gateway="PayPal") | |||||
if not self.flags.ignore_mandatory: | if not self.flags.ignore_mandatory: | ||||
self.validate_paypal_credentails() | self.validate_paypal_credentails() | ||||
def on_update(self): | def on_update(self): | ||||
pass | pass | ||||
def enable(self): | |||||
call_hook_method('payment_gateway_enabled', gateway=self.service_name) | |||||
if not self.flags.ignore_mandatory: | |||||
self.validate_paypal_credentails() | |||||
def validate_transaction_currency(self, currency): | def validate_transaction_currency(self, currency): | ||||
if currency not in self.supported_currencies: | if currency not in self.supported_currencies: | ||||
frappe.throw(_("Please select another payment method. {0} does not support transactions in currency '{1}'").format(self.service_name, currency)) | |||||
frappe.throw(_("Please select another payment method. PayPal does not support transactions in currency '{0}'").format(currency)) | |||||
def get_paypal_params_and_url(self): | def get_paypal_params_and_url(self): | ||||
params = { | params = { | ||||
@@ -117,7 +114,7 @@ class PayPalSettings(IntegrationService): | |||||
params = urlencode(params) | params = urlencode(params) | ||||
try: | try: | ||||
res = self.post_request(url=url, data=params.encode("utf-8")) | |||||
res = make_post_request(url=url, data=params.encode("utf-8")) | |||||
if res["ACK"][0] == "Failure": | if res["ACK"][0] == "Failure": | ||||
raise Exception | raise Exception | ||||
@@ -140,7 +137,7 @@ class PayPalSettings(IntegrationService): | |||||
"correlation_id": response.get("CORRELATIONID")[0] | "correlation_id": response.get("CORRELATIONID")[0] | ||||
}) | }) | ||||
self.integration_request = self.create_request(kwargs, "Remote", self.service_name, response.get("TOKEN")[0]) | |||||
self.integration_request = create_request_log(kwargs, "Remote", "PayPal", response.get("TOKEN")[0]) | |||||
return return_url.format(kwargs["token"]) | return return_url.format(kwargs["token"]) | ||||
@@ -157,49 +154,12 @@ class PayPalSettings(IntegrationService): | |||||
params = urlencode(params) | params = urlencode(params) | ||||
response = self.post_request(url, data=params.encode("utf-8")) | |||||
response = make_post_request(url, data=params.encode("utf-8")) | |||||
if response.get("ACK")[0] != "Success": | if response.get("ACK")[0] != "Success": | ||||
frappe.throw("Looks like something is wrong with this site's Paypal configuration.") | frappe.throw("Looks like something is wrong with this site's Paypal configuration.") | ||||
return response | return response | ||||
@frappe.whitelist() | |||||
def get_service_details(): | |||||
return """ | |||||
<div> | |||||
<p> Steps to configure Service | |||||
<ol> | |||||
<li> Get PayPal api credentials from link: | |||||
<a href="https://developer.paypal.com/docs/classic/api/apiCredentials/" target="_blank"> | |||||
https://developer.paypal.com/docs/classic/api/apiCredentials/ | |||||
</a> | |||||
</li> | |||||
<br> | |||||
<li> Setup credentials on PayPal settings doctype. | |||||
Click on | |||||
<button class="btn btn-default btn-xs disabled"> PayPal Settings </button> | |||||
top right corner | |||||
</li> | |||||
<br> | |||||
<li> | |||||
After saving settings, | |||||
<label> | |||||
<span class="input-area"> | |||||
<input type="checkbox" class="input-with-feedback" checked disabled> | |||||
</span> | |||||
<span class="label-area small">Enabled</span> | |||||
</label> | |||||
PayPal Integration Service and Save a document. | |||||
</li> | |||||
<br> | |||||
<li> | |||||
To view PayPal payment logs, | |||||
<button class="btn btn-default btn-xs disabled"> Show Log </button> | |||||
</li> | |||||
</ol> | |||||
</div> | |||||
""" | |||||
@frappe.whitelist(allow_guest=True, xss_safe=True) | @frappe.whitelist(allow_guest=True, xss_safe=True) | ||||
def get_express_checkout_details(token): | def get_express_checkout_details(token): | ||||
try: | try: | ||||
@@ -212,7 +172,7 @@ def get_express_checkout_details(token): | |||||
"TOKEN": token | "TOKEN": token | ||||
}) | }) | ||||
response = doc.post_request(url, data=params) | |||||
response = make_post_request(url, data=params) | |||||
if response.get("ACK")[0] != "Success": | if response.get("ACK")[0] != "Success": | ||||
frappe.respond_as_web_page(_("Something went wrong"), | frappe.respond_as_web_page(_("Something went wrong"), | ||||
@@ -259,7 +219,7 @@ def confirm_payment(token): | |||||
"PAYMENTREQUEST_0_CURRENCYCODE": data.get("currency").upper() | "PAYMENTREQUEST_0_CURRENCYCODE": data.get("currency").upper() | ||||
}) | }) | ||||
response = doc.post_request(url, data=params) | |||||
response = make_post_request(url, data=params) | |||||
if response.get("ACK")[0] == "Success": | if response.get("ACK")[0] == "Success": | ||||
update_integration_request_status(token, { | update_integration_request_status(token, { | ||||
@@ -291,14 +251,3 @@ def confirm_payment(token): | |||||
def update_integration_request_status(token, data, status, error=False): | def update_integration_request_status(token, data, status, error=False): | ||||
frappe.get_doc("Integration Request", token).update_status(data, status) | frappe.get_doc("Integration Request", token).update_status(data, status) | ||||
@frappe.whitelist(allow_guest=True, xss_safe=True) | |||||
def get_checkout_url(**kwargs): | |||||
try: | |||||
doc = frappe.get_doc("PayPal Settings") | |||||
return doc.get_payment_url(**kwargs) | |||||
except Exception: | |||||
frappe.respond_as_web_page(_("Something went wrong"), | |||||
_("Looks like something is wrong with this site's Paypal configuration. Don't worry! No payment has been made from your Paypal account."), | |||||
indicator_color='red', | |||||
http_status_code=frappe.ValidationError.http_status_code) |
@@ -1,33 +1,8 @@ | |||||
// Copyright (c) 2016, Frappe Technologies and contributors | // Copyright (c) 2016, Frappe Technologies and contributors | ||||
// For license information, please see license.txt | // For license information, please see license.txt | ||||
frappe.provide("frappe.integration_service") | |||||
frappe.ui.form.on('Razorpay Settings', { | frappe.ui.form.on('Razorpay Settings', { | ||||
refresh: function(frm) { | refresh: function(frm) { | ||||
} | } | ||||
}); | |||||
frappe.integration_service.razorpay_settings = Class.extend({ | |||||
init: function(frm) { | |||||
}, | |||||
get_scheduler_job_info: function() { | |||||
return { | |||||
"Execute on every few minits of interval": " Captures all authorised payments" | |||||
} | |||||
}, | |||||
get_service_info: function(frm) { | |||||
frappe.call({ | |||||
method: "frappe.integrations.doctype.razorpay_settings.razorpay_settings.get_service_details", | |||||
callback: function(r){ | |||||
var integration_service_help = frm.fields_dict.integration_service_help.wrapper; | |||||
$(integration_service_help).empty(); | |||||
$(integration_service_help).append(r.message); | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
}); |
@@ -9,9 +9,9 @@ | |||||
Example: | Example: | ||||
from frappe.integration_broker.doctype.integration_service.integration_service import get_integration_controller | |||||
from frappe.integrations.utils import get_payment_gateway_controller | |||||
controller = get_integration_controller("Razorpay") | |||||
controller = get_payment_gateway_controller("Razorpay") | |||||
controller().validate_transaction_currency(currency) | controller().validate_transaction_currency(currency) | ||||
### 2. Redirect for payment | ### 2. Redirect for payment | ||||
@@ -27,7 +27,8 @@ Example: | |||||
"payer_email": "NuranVerkleij@example.com", | "payer_email": "NuranVerkleij@example.com", | ||||
"payer_name": "Nuran Verkleij", | "payer_name": "Nuran Verkleij", | ||||
"order_id": "111", | "order_id": "111", | ||||
"currency": "INR" | |||||
"currency": "INR", | |||||
"payment_gateway": "Razorpay" | |||||
} | } | ||||
# Redirect the user to this url | # Redirect the user to this url | ||||
@@ -53,45 +54,32 @@ For razorpay payment status is Authorized | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
from frappe.utils import get_url, call_hook_method, cint | |||||
from frappe import _ | from frappe import _ | ||||
import urllib, json | import urllib, json | ||||
from frappe.integration_broker.doctype.integration_service.integration_service import IntegrationService | |||||
from frappe.model.document import Document | |||||
from frappe.utils import get_url, call_hook_method, cint | |||||
from frappe.integrations.utils import make_get_request, make_post_request, create_request_log, create_payment_gateway | |||||
class RazorpaySettings(IntegrationService): | |||||
service_name = "Razorpay" | |||||
class RazorpaySettings(Document): | |||||
supported_currencies = ["INR"] | supported_currencies = ["INR"] | ||||
scheduler_events = { | |||||
"all": [ | |||||
"frappe.integrations.doctype.razorpay_settings.razorpay_settings.capture_payment" | |||||
] | |||||
} | |||||
def validate(self): | def validate(self): | ||||
if not self.flags.ignore_mandatory: | |||||
self.validate_razorpay_credentails() | |||||
def on_update(self): | |||||
pass | |||||
def enable(self): | |||||
create_payment_gateway('Razorpay') | |||||
call_hook_method('payment_gateway_enabled', gateway='Razorpay') | call_hook_method('payment_gateway_enabled', gateway='Razorpay') | ||||
if not self.flags.ignore_mandatory: | if not self.flags.ignore_mandatory: | ||||
self.validate_razorpay_credentails() | self.validate_razorpay_credentails() | ||||
def validate_razorpay_credentails(self): | def validate_razorpay_credentails(self): | ||||
if self.api_key and self.api_secret: | if self.api_key and self.api_secret: | ||||
try: | try: | ||||
self.get_request(url="https://api.razorpay.com/v1/payments", | |||||
make_get_request(url="https://api.razorpay.com/v1/payments", | |||||
auth=(self.api_key, self.get_password(fieldname="api_secret", raise_exception=False))) | auth=(self.api_key, self.get_password(fieldname="api_secret", raise_exception=False))) | ||||
except Exception: | except Exception: | ||||
frappe.throw(_("Seems API Key or API Secret is wrong !!!")) | frappe.throw(_("Seems API Key or API Secret is wrong !!!")) | ||||
def validate_transaction_currency(self, currency): | def validate_transaction_currency(self, currency): | ||||
if currency not in self.supported_currencies: | if currency not in self.supported_currencies: | ||||
frappe.throw(_("Please select another payment method. {0} does not support transactions in currency '{1}'").format(self.service_name, currency)) | |||||
frappe.throw(_("Please select another payment method. Razorpay does not support transactions in currency '{0}'").format(currency)) | |||||
def get_payment_url(self, **kwargs): | def get_payment_url(self, **kwargs): | ||||
return get_url("./integrations/razorpay_checkout?{0}".format(urllib.urlencode(kwargs))) | return get_url("./integrations/razorpay_checkout?{0}".format(urllib.urlencode(kwargs))) | ||||
@@ -100,8 +88,7 @@ class RazorpaySettings(IntegrationService): | |||||
self.data = frappe._dict(data) | self.data = frappe._dict(data) | ||||
try: | try: | ||||
self.integration_request = super(RazorpaySettings, self).create_request(self.data, "Host", \ | |||||
"Razorpay") | |||||
self.integration_request = create_request_log(self.data, "Host", "Razorpay") | |||||
return self.authorize_payment() | return self.authorize_payment() | ||||
except Exception: | except Exception: | ||||
@@ -124,7 +111,7 @@ class RazorpaySettings(IntegrationService): | |||||
redirect_message = data.get('notes', {}).get('redirect_message') or None | redirect_message = data.get('notes', {}).get('redirect_message') or None | ||||
try: | try: | ||||
resp = self.get_request("https://api.razorpay.com/v1/payments/{0}" | |||||
resp = make_get_request("https://api.razorpay.com/v1/payments/{0}" | |||||
.format(self.data.razorpay_payment_id), auth=(settings.api_key, | .format(self.data.razorpay_payment_id), auth=(settings.api_key, | ||||
settings.api_secret)) | settings.api_secret)) | ||||
@@ -201,7 +188,7 @@ def capture_payment(is_sandbox=False, sanbox_response=None): | |||||
data = json.loads(doc.data) | data = json.loads(doc.data) | ||||
settings = controller.get_settings(data) | settings = controller.get_settings(data) | ||||
resp = controller.post_request("https://api.razorpay.com/v1/payments/{0}/capture".format(data.get("razorpay_payment_id")), | |||||
resp = make_post_request("https://api.razorpay.com/v1/payments/{0}/capture".format(data.get("razorpay_payment_id")), | |||||
auth=(settings.api_key, settings.api_secret), data={"amount": data.get("amount")}) | auth=(settings.api_key, settings.api_secret), data={"amount": data.get("amount")}) | ||||
if resp.get("status") == "captured": | if resp.get("status") == "captured": | ||||
@@ -211,51 +198,4 @@ def capture_payment(is_sandbox=False, sanbox_response=None): | |||||
doc = frappe.get_doc("Integration Request", doc.name) | doc = frappe.get_doc("Integration Request", doc.name) | ||||
doc.status = "Failed" | doc.status = "Failed" | ||||
doc.error = frappe.get_traceback() | doc.error = frappe.get_traceback() | ||||
frappe.log_error(doc.error, '{0} Failed'.format(doc.name)) | |||||
@frappe.whitelist(allow_guest=True, xss_safe=True) | |||||
def get_checkout_url(**kwargs): | |||||
try: | |||||
return frappe.get_doc("Razorpay Settings").get_payment_url(**kwargs) | |||||
except Exception: | |||||
frappe.respond_as_web_page(_("Something went wrong"), | |||||
_("Looks like something is wrong with this site's Razorpay configuration. No payment has been made."), | |||||
indicator_color='red', | |||||
http_status_code=frappe.ValidationError.http_status_code) | |||||
@frappe.whitelist() | |||||
def get_service_details(): | |||||
return """ | |||||
<div> | |||||
<p> Steps to configure Service | |||||
<ol> | |||||
<li> Get Razorpay api credentials by login to: | |||||
<a href="https://razorpay.com/" target="_blank"> | |||||
https://razorpay.com/ | |||||
</a> | |||||
</li> | |||||
<br> | |||||
<li> Setup credentials on Razorpay Settings doctype. | |||||
Click on | |||||
<button class="btn btn-default btn-xs disabled"> Razorpay Settings </button> | |||||
top right corner | |||||
</li> | |||||
<br> | |||||
<li> | |||||
After saving settings, | |||||
<label> | |||||
<span class="input-area"> | |||||
<input type="checkbox" class="input-with-feedback" checked disabled> | |||||
</span> | |||||
<span class="label-area small">Enable</span> | |||||
</label> | |||||
Razorpay Integration Service and Save a document. | |||||
</li> | |||||
<br> | |||||
<li> | |||||
To view Razorpays payment logs, | |||||
<button class="btn btn-default btn-xs disabled"> Show Log </button> | |||||
</li> | |||||
</ol> | |||||
</div> | |||||
""" | |||||
frappe.log_error(doc.error, '{0} Failed'.format(doc.name)) |
@@ -0,0 +1,8 @@ | |||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors | |||||
// For license information, please see license.txt | |||||
frappe.ui.form.on('Payment Gateway', { | |||||
refresh: function(frm) { | |||||
} | |||||
}); |
@@ -0,0 +1,91 @@ | |||||
{ | |||||
"allow_copy": 0, | |||||
"allow_guest_to_view": 0, | |||||
"allow_import": 0, | |||||
"allow_rename": 0, | |||||
"autoname": "field:gateway", | |||||
"beta": 0, | |||||
"creation": "2015-12-15 22:26:45.221162", | |||||
"custom": 0, | |||||
"docstatus": 0, | |||||
"doctype": "DocType", | |||||
"document_type": "", | |||||
"editable_grid": 1, | |||||
"fields": [ | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "gateway", | |||||
"fieldtype": "Data", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_global_search": 0, | |||||
"in_list_view": 0, | |||||
"in_standard_filter": 0, | |||||
"label": "Gateway", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"remember_last_selected_value": 0, | |||||
"report_hide": 0, | |||||
"reqd": 1, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
} | |||||
], | |||||
"has_web_view": 0, | |||||
"hide_heading": 0, | |||||
"hide_toolbar": 0, | |||||
"idx": 0, | |||||
"image_view": 0, | |||||
"in_create": 1, | |||||
"is_submittable": 0, | |||||
"issingle": 0, | |||||
"istable": 0, | |||||
"max_attachments": 0, | |||||
"modified": "2017-03-09 12:40:56.176464", | |||||
"modified_by": "Administrator", | |||||
"module": "Core", | |||||
"name": "Payment Gateway", | |||||
"name_case": "", | |||||
"owner": "Administrator", | |||||
"permissions": [ | |||||
{ | |||||
"amend": 0, | |||||
"apply_user_permissions": 0, | |||||
"cancel": 0, | |||||
"create": 0, | |||||
"delete": 0, | |||||
"email": 0, | |||||
"export": 0, | |||||
"if_owner": 0, | |||||
"import": 0, | |||||
"permlevel": 0, | |||||
"print": 0, | |||||
"read": 1, | |||||
"report": 0, | |||||
"role": "System Manager", | |||||
"set_user_permissions": 0, | |||||
"share": 0, | |||||
"submit": 0, | |||||
"write": 0 | |||||
} | |||||
], | |||||
"quick_entry": 1, | |||||
"read_only": 0, | |||||
"read_only_onload": 0, | |||||
"show_name_in_global_search": 0, | |||||
"sort_field": "modified", | |||||
"sort_order": "DESC", | |||||
"track_changes": 0, | |||||
"track_seen": 0 | |||||
} |
@@ -0,0 +1,10 @@ | |||||
# -*- coding: utf-8 -*- | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors | |||||
# For license information, please see license.txt | |||||
from __future__ import unicode_literals | |||||
import frappe | |||||
from frappe.model.document import Document | |||||
class PaymentGateway(Document): | |||||
pass |
@@ -0,0 +1,12 @@ | |||||
# -*- coding: utf-8 -*- | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||||
# See license.txt | |||||
from __future__ import unicode_literals | |||||
import frappe | |||||
import unittest | |||||
# test_records = frappe.get_test_records('Payment Gateway') | |||||
class TestPaymentGateway(unittest.TestCase): | |||||
pass |