Bläddra i källkod

Initial

master
Anoop 2 år sedan
förälder
incheckning
79ffde8cd0
39 ändrade filer med 351 tillägg och 351 borttagningar
  1. +4
    -4
      .github/workflows/ci.yml
  2. +4
    -4
      .github/workflows/linter.yml
  3. +3
    -3
      README.md
  4. +1
    -1
      license.txt
  5. +1
    -1
      payments/config/desktop.py
  6. +8
    -8
      payments/hooks.py
  7. +24
    -24
      payments/overrides/payment_webform.py
  8. +2
    -2
      payments/payment_gateways/doctype/braintree_settings/braintree_settings.js
  9. +19
    -19
      payments/payment_gateways/doctype/braintree_settings/braintree_settings.py
  10. +1
    -1
      payments/payment_gateways/doctype/braintree_settings/test_braintree_settings.py
  11. +2
    -2
      payments/payment_gateways/doctype/paypal_settings/paypal_settings.js
  12. +49
    -49
      payments/payment_gateways/doctype/paypal_settings/paypal_settings.py
  13. +3
    -3
      payments/payment_gateways/doctype/paytm_settings/paytm_settings.js
  14. +20
    -20
      payments/payment_gateways/doctype/paytm_settings/paytm_settings.py
  15. +2
    -2
      payments/payment_gateways/doctype/paytm_settings/test_paytm_settings.py
  16. +3
    -3
      payments/payment_gateways/doctype/razorpay_settings/razorpay_settings.js
  17. +63
    -63
      payments/payment_gateways/doctype/razorpay_settings/razorpay_settings.py
  18. +2
    -2
      payments/payment_gateways/doctype/stripe_settings/stripe_settings.js
  19. +18
    -18
      payments/payment_gateways/doctype/stripe_settings/stripe_settings.py
  20. +1
    -1
      payments/payment_gateways/doctype/stripe_settings/test_stripe_settings.py
  21. +2
    -2
      payments/payments/doctype/payment_gateway/payment_gateway.js
  22. +2
    -2
      payments/payments/doctype/payment_gateway/payment_gateway.py
  23. +2
    -2
      payments/payments/doctype/payment_gateway/test_payment_gateway.py
  24. +9
    -9
      payments/public/js/razorpay.js
  25. +2
    -2
      payments/templates/includes/braintree_checkout.js
  26. +3
    -3
      payments/templates/includes/razorpay_checkout.js
  27. +3
    -3
      payments/templates/includes/stripe_checkout.js
  28. +13
    -13
      payments/templates/pages/braintree_checkout.py
  29. +1
    -1
      payments/templates/pages/payment-cancel.html
  30. +1
    -1
      payments/templates/pages/payment-failed.html
  31. +4
    -4
      payments/templates/pages/payment-success.html
  32. +5
    -5
      payments/templates/pages/payment_cancel.py
  33. +4
    -4
      payments/templates/pages/payment_success.py
  34. +8
    -8
      payments/templates/pages/paytm_checkout.py
  35. +15
    -15
      payments/templates/pages/razorpay_checkout.py
  36. +21
    -21
      payments/templates/pages/stripe_checkout.py
  37. +22
    -22
      payments/utils/utils.py
  38. +1
    -1
      requirements.txt
  39. +3
    -3
      setup.py

+ 4
- 4
.github/workflows/ci.yml Visa fil

@@ -65,13 +65,13 @@ jobs:


- name: Setup - name: Setup
run: | run: |
pip install frappe-bench
bench init --skip-redis-config-generation --skip-assets --frappe-branch ${GITHUB_BASE_REF:-${GITHUB_REF##*/}} --python "$(which python)" ~/frappe-bench
pip install xhiveframework-bench
bench init --skip-redis-config-generation --skip-assets --xhiveframework-branch ${GITHUB_BASE_REF:-${GITHUB_REF##*/}} --python "$(which python)" ~/xhiveframework-bench
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'" mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'"
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'" mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"


- name: Install - name: Install
working-directory: /home/runner/frappe-bench
working-directory: /home/runner/xhiveframework-bench
run: | run: |
bench get-app payments $GITHUB_WORKSPACE bench get-app payments $GITHUB_WORKSPACE
bench setup requirements --dev bench setup requirements --dev
@@ -83,7 +83,7 @@ jobs:
CI: 'Yes' CI: 'Yes'


- name: Run Tests - name: Run Tests
working-directory: /home/runner/frappe-bench
working-directory: /home/runner/xhiveframework-bench
run: | run: |
bench --site test_site set-config allow_tests true bench --site test_site set-config allow_tests true
bench --site test_site run-tests --app payments bench --site test_site run-tests --app payments


+ 4
- 4
.github/workflows/linter.yml Visa fil

@@ -10,7 +10,7 @@ permissions:
contents: read contents: read


concurrency: concurrency:
group: commitcheck-frappe-${{ github.event.number }}
group: commitcheck-xhiveframework-${{ github.event.number }}
cancel-in-progress: true cancel-in-progress: true


jobs: jobs:
@@ -34,7 +34,7 @@ jobs:
npx commitlint --verbose --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} npx commitlint --verbose --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }}


linter: linter:
name: 'Frappe Linter'
name: 'Xhiveframework Linter'
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'


@@ -46,9 +46,9 @@ jobs:
- uses: pre-commit/action@v3.0.0 - uses: pre-commit/action@v3.0.0


- name: Download Semgrep rules - name: Download Semgrep rules
run: git clone --depth 1 https://github.com/frappe/semgrep-rules.git frappe-semgrep-rules
run: git clone --depth 1 https://github.com/xhiveframework/semgrep-rules.git xhiveframework-semgrep-rules


- name: Run Semgrep rules - name: Run Semgrep rules
run: | run: |
pip install semgrep==0.97.0 pip install semgrep==0.97.0
semgrep ci --config ./frappe-semgrep-rules/rules --config r/python.lang.correctness
semgrep ci --config ./xhiveframework-semgrep-rules/rules --config r/python.lang.correctness

+ 3
- 3
README.md Visa fil

@@ -1,9 +1,9 @@
# Payments # Payments


A payments app for frappe.
A payments app for xhiveframework.


## Installation ## Installation
1. Install [bench & frappe](https://frappeframework.com/docs/v14/user/en/installation).
1. Install [bench & xhiveframework](https://xhiveframework.com/docs/v14/user/en/installation).


2. Once setup is complete, add the payments app to your bench by running 2. Once setup is complete, add the payments app to your bench by running
``` ```
@@ -23,7 +23,7 @@ App adds custom fields to Web Form for facilitating payments upon installation a


All general utils are stored in [utils](payments/utils) directory. The utils are written in [utils.py](payments/utils/utils.py) and then imported into the [`__init__.py`](payments/utils/__init__.py) file for easier importing/namespacing. All general utils are stored in [utils](payments/utils) directory. The utils are written in [utils.py](payments/utils/utils.py) and then imported into the [`__init__.py`](payments/utils/__init__.py) file for easier importing/namespacing.


[overrides](payments/overrides) directory has all the overrides for overriding standard frappe code. Currently it overrides WebForm DocType controller as well as a WebForm whitelisted method.
[overrides](payments/overrides) directory has all the overrides for overriding standard xhiveframework code. Currently it overrides WebForm DocType controller as well as a WebForm whitelisted method.


[templates](payments/templates) directory has all the payment gateways' custom checkout pages. [templates](payments/templates) directory has all the payment gateways' custom checkout pages.




+ 1
- 1
license.txt Visa fil

@@ -1,6 +1,6 @@
The MIT License The MIT License


Copyright (c) 2016-2021 Frappe Technologies Pvt. Ltd. <developers@frappe.io>
Copyright (c) 2016-2021 Xhive LLC Pvt. Ltd. <developers@xhiveframework.com>


Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal


+ 1
- 1
payments/config/desktop.py Visa fil

@@ -1,4 +1,4 @@
from frappe import _
from xhiveframework import _




def get_data(): def get_data():


+ 8
- 8
payments/hooks.py Visa fil

@@ -2,9 +2,9 @@ from . import __version__ as app_version


app_name = "payments" app_name = "payments"
app_title = "Payments" app_title = "Payments"
app_publisher = "Frappe Technologies"
app_description = "Payments app for frappe"
app_email = "hello@frappe.io"
app_publisher = "Xhive LLC"
app_description = "Payments app for xhiveframework"
app_email = "hello@xhiveframework.com"
app_license = "MIT" app_license = "MIT"


# Includes in <head> # Includes in <head>
@@ -74,7 +74,7 @@ before_uninstall = "payments.utils.delete_custom_fields"


# Desk Notifications # Desk Notifications
# ------------------ # ------------------
# See frappe.core.notifications.get_notification_config
# See xhiveframework.core.notifications.get_notification_config


# notification_config = "pay.notifications.get_notification_config" # notification_config = "pay.notifications.get_notification_config"


@@ -83,11 +83,11 @@ before_uninstall = "payments.utils.delete_custom_fields"
# Permissions evaluated in scripted ways # Permissions evaluated in scripted ways


# permission_query_conditions = { # permission_query_conditions = {
# "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions",
# "Event": "xhiveframework.desk.doctype.event.event.get_permission_query_conditions",
# } # }
# #
# has_permission = { # has_permission = {
# "Event": "frappe.desk.doctype.event.event.has_permission",
# "Event": "xhiveframework.desk.doctype.event.event.has_permission",
# } # }


# DocType Class # DocType Class
@@ -128,12 +128,12 @@ scheduler_events = {
# ------------------------------ # ------------------------------
# #
override_whitelisted_methods = { override_whitelisted_methods = {
"frappe.website.doctype.web_form.web_form.accept": "payments.overrides.payment_webform.accept"
"xhiveframework.website.doctype.web_form.web_form.accept": "payments.overrides.payment_webform.accept"
} }
# #
# each overriding function accepts a `data` argument; # each overriding function accepts a `data` argument;
# generated from the base implementation of the doctype dashboard, # generated from the base implementation of the doctype dashboard,
# along with any modifications made in other Frappe apps
# along with any modifications made in other Xhiveframework apps
# override_doctype_dashboards = { # override_doctype_dashboards = {
# "Task": "pay.task.get_dashboard_data" # "Task": "pay.task.get_dashboard_data"
# } # }


+ 24
- 24
payments/overrides/payment_webform.py Visa fil

@@ -1,10 +1,10 @@
import json import json


import frappe
from frappe.core.doctype.file import remove_file_by_url
from frappe.rate_limiter import rate_limit
from frappe.utils import flt
from frappe.website.doctype.web_form.web_form import WebForm
import xhiveframework
from xhiveframework.core.doctype.file import remove_file_by_url
from xhiveframework.rate_limiter import rate_limit
from xhiveframework.utils import flt
from xhiveframework.website.doctype.web_form.web_form import WebForm


from payments.utils import get_payment_gateway_controller from payments.utils import get_payment_gateway_controller


@@ -18,9 +18,9 @@ class PaymentWebForm(WebForm):


def validate_payment_amount(self): def validate_payment_amount(self):
if self.amount_based_on_field and not self.amount_field: if self.amount_based_on_field and not self.amount_field:
frappe.throw(frappe._("Please select a Amount Field."))
xhiveframework.throw(xhiveframework._("Please select a Amount Field."))
elif not self.amount_based_on_field and not flt(self.amount) > 0: elif not self.amount_based_on_field and not flt(self.amount) > 0:
frappe.throw(frappe._("Amount must be greater than 0."))
xhiveframework.throw(xhiveframework._("Amount must be greater than 0."))


def get_payment_gateway_url(self, doc): def get_payment_gateway_url(self, doc):
if getattr(self, "accept_payment", False): if getattr(self, "accept_payment", False):
@@ -34,7 +34,7 @@ class PaymentWebForm(WebForm):
from decimal import Decimal from decimal import Decimal


if amount is None or Decimal(amount) <= 0: if amount is None or Decimal(amount) <= 0:
return frappe.utils.get_url(self.success_url or self.route)
return xhiveframework.utils.get_url(self.success_url or self.route)


payment_details = { payment_details = {
"amount": amount, "amount": amount,
@@ -42,43 +42,43 @@ class PaymentWebForm(WebForm):
"description": title, "description": title,
"reference_doctype": doc.doctype, "reference_doctype": doc.doctype,
"reference_docname": doc.name, "reference_docname": doc.name,
"payer_email": frappe.session.user,
"payer_name": frappe.utils.get_fullname(frappe.session.user),
"payer_email": xhiveframework.session.user,
"payer_name": xhiveframework.utils.get_fullname(xhiveframework.session.user),
"order_id": doc.name, "order_id": doc.name,
"currency": self.currency, "currency": self.currency,
"redirect_to": frappe.utils.get_url(self.success_url or self.route),
"redirect_to": xhiveframework.utils.get_url(self.success_url or self.route),
} }


# Redirect the user to this url # Redirect the user to this url
return controller.get_payment_url(**payment_details) return controller.get_payment_url(**payment_details)




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
@rate_limit(key="web_form", limit=5, seconds=60, methods=["POST"]) @rate_limit(key="web_form", limit=5, seconds=60, methods=["POST"])
def accept(web_form, data, docname=None, for_payment=False): def accept(web_form, data, docname=None, for_payment=False):
"""Save the web form""" """Save the web form"""
data = frappe._dict(json.loads(data))
for_payment = frappe.parse_json(for_payment)
data = xhiveframework._dict(json.loads(data))
for_payment = xhiveframework.parse_json(for_payment)


docname = docname or data.name docname = docname or data.name


files = [] files = []
files_to_delete = [] files_to_delete = []


web_form = frappe.get_doc("Web Form", web_form)
web_form = xhiveframework.get_doc("Web Form", web_form)


if docname and not web_form.allow_edit: if docname and not web_form.allow_edit:
frappe.throw(frappe._("You are not allowed to update this Web Form Document"))
xhiveframework.throw(xhiveframework._("You are not allowed to update this Web Form Document"))


frappe.flags.in_web_form = True
meta = frappe.get_meta(data.doctype)
xhiveframework.flags.in_web_form = True
meta = xhiveframework.get_meta(data.doctype)


if docname: if docname:
# update # update
doc = frappe.get_doc(data.doctype, docname)
doc = xhiveframework.get_doc(data.doctype, docname)
else: else:
# insert # insert
doc = frappe.new_doc(data.doctype)
doc = xhiveframework.new_doc(data.doctype)


# set values # set values
for field in web_form.web_form_fields: for field in web_form.web_form_fields:
@@ -111,8 +111,8 @@ def accept(web_form, data, docname=None, for_payment=False):


else: else:
# insert # insert
if web_form.login_required and frappe.session.user == "Guest":
frappe.throw(frappe._("You must login to submit this form"))
if web_form.login_required and xhiveframework.session.user == "Guest":
xhiveframework.throw(xhiveframework._("You must login to submit this form"))


ignore_mandatory = True if files else False ignore_mandatory = True if files else False


@@ -129,7 +129,7 @@ def accept(web_form, data, docname=None, for_payment=False):


# save new file # save new file
filename, dataurl = filedata.split(",", 1) filename, dataurl = filedata.split(",", 1)
_file = frappe.get_doc(
_file = xhiveframework.get_doc(
{ {
"doctype": "File", "doctype": "File",
"file_name": filename, "file_name": filename,
@@ -151,7 +151,7 @@ def accept(web_form, data, docname=None, for_payment=False):
if f: if f:
remove_file_by_url(f, doctype=doc.doctype, name=doc.name) remove_file_by_url(f, doctype=doc.doctype, name=doc.name)


frappe.flags.web_form_doc = doc
xhiveframework.flags.web_form_doc = doc


if for_payment: if for_payment:
# this is needed for Payments app # this is needed for Payments app


+ 2
- 2
payments/payment_gateways/doctype/braintree_settings/braintree_settings.js Visa fil

@@ -1,6 +1,6 @@
// Copyright (c) 2018, Frappe Technologies and contributors
// Copyright (c) 2018, Xhive LLC
// For license information, please see license.txt // For license information, please see license.txt


frappe.ui.form.on('Braintree Settings', {
xhiveframework.ui.form.on('Braintree Settings', {


}); });

+ 19
- 19
payments/payment_gateways/doctype/braintree_settings/braintree_settings.py Visa fil

@@ -1,14 +1,14 @@
# Copyright (c) 2018, Frappe Technologies and contributors
# Copyright (c) 2018, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE


from urllib.parse import urlencode from urllib.parse import urlencode


import braintree import braintree
import frappe
from frappe import _
from frappe.integrations.utils import create_request_log
from frappe.model.document import Document
from frappe.utils import call_hook_method, get_url
import xhiveframework
from xhiveframework import _
from xhiveframework.integrations.utils import create_request_log
from xhiveframework.model.document import Document
from xhiveframework.utils import call_hook_method, get_url


from payments.utils import create_payment_gateway from payments.utils import create_payment_gateway


@@ -179,7 +179,7 @@ class BraintreeSettings(Document):


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(
xhiveframework.throw(
_( _(
"Please select another payment method. Stripe does not support transactions in currency '{0}'" "Please select another payment method. Stripe does not support transactions in currency '{0}'"
).format(currency) ).format(currency)
@@ -189,16 +189,16 @@ class BraintreeSettings(Document):
return get_url(f"./braintree_checkout?{urlencode(kwargs)}") return get_url(f"./braintree_checkout?{urlencode(kwargs)}")


def create_payment_request(self, data): def create_payment_request(self, data):
self.data = frappe._dict(data)
self.data = xhiveframework._dict(data)


try: try:
self.integration_request = create_request_log(self.data, service_name="Braintree") self.integration_request = create_request_log(self.data, service_name="Braintree")
return self.create_charge_on_braintree() return self.create_charge_on_braintree()


except Exception: except Exception:
frappe.log_error(frappe.get_traceback())
xhiveframework.log_error(xhiveframework.get_traceback())
return { return {
"redirect_to": frappe.redirect_to_message(
"redirect_to": xhiveframework.redirect_to_message(
_("Server Error"), _("Server Error"),
_( _(
"There seems to be an issue with the server's braintree configuration. Don't worry, in case of failure, the amount will get refunded to your account." "There seems to be an issue with the server's braintree configuration. Don't worry, in case of failure, the amount will get refunded to your account."
@@ -230,7 +230,7 @@ class BraintreeSettings(Document):


elif result.transaction: elif result.transaction:
self.integration_request.db_set("status", "Failed", update_modified=False) self.integration_request.db_set("status", "Failed", update_modified=False)
error_log = frappe.log_error(
error_log = xhiveframework.log_error(
"code: " "code: "
+ str(result.transaction.processor_response_code) + str(result.transaction.processor_response_code)
+ " | text: " + " | text: "
@@ -241,7 +241,7 @@ class BraintreeSettings(Document):
else: else:
self.integration_request.db_set("status", "Failed", update_modified=False) self.integration_request.db_set("status", "Failed", update_modified=False)
for error in result.errors.deep_errors: for error in result.errors.deep_errors:
error_log = frappe.log_error(
error_log = xhiveframework.log_error(
"code: " + str(error.code) + " | message: " + str(error.message), "code: " + str(error.code) + " | message: " + str(error.message),
"Braintree Payment Error", "Braintree Payment Error",
) )
@@ -252,14 +252,14 @@ class BraintreeSettings(Document):
if self.data.reference_doctype and self.data.reference_docname: if self.data.reference_doctype and self.data.reference_docname:
custom_redirect_to = None custom_redirect_to = None
try: try:
custom_redirect_to = frappe.get_doc(
custom_redirect_to = xhiveframework.get_doc(
self.data.reference_doctype, self.data.reference_docname self.data.reference_doctype, self.data.reference_docname
).run_method("on_payment_authorized", self.flags.status_changed_to) ).run_method("on_payment_authorized", self.flags.status_changed_to)
braintree_success_page = frappe.get_hooks("braintree_success_page")
braintree_success_page = xhiveframework.get_hooks("braintree_success_page")
if braintree_success_page: if braintree_success_page:
custom_redirect_to = frappe.get_attr(braintree_success_page[-1])(self.data)
custom_redirect_to = xhiveframework.get_attr(braintree_success_page[-1])(self.data)
except Exception: except Exception:
frappe.log_error(frappe.get_traceback())
xhiveframework.log_error(xhiveframework.get_traceback())


if custom_redirect_to: if custom_redirect_to:
redirect_to = custom_redirect_to redirect_to = custom_redirect_to
@@ -278,8 +278,8 @@ class BraintreeSettings(Document):




def get_gateway_controller(doc): def get_gateway_controller(doc):
payment_request = frappe.get_doc("Payment Request", doc)
gateway_controller = frappe.db.get_value(
payment_request = xhiveframework.get_doc("Payment Request", doc)
gateway_controller = xhiveframework.db.get_value(
"Payment Gateway", payment_request.payment_gateway, "gateway_controller" "Payment Gateway", payment_request.payment_gateway, "gateway_controller"
) )
return gateway_controller return gateway_controller
@@ -287,7 +287,7 @@ def get_gateway_controller(doc):


def get_client_token(doc): def get_client_token(doc):
gateway_controller = get_gateway_controller(doc) gateway_controller = get_gateway_controller(doc)
settings = frappe.get_doc("Braintree Settings", gateway_controller)
settings = xhiveframework.get_doc("Braintree Settings", gateway_controller)
settings.configure_braintree() settings.configure_braintree()


return braintree.ClientToken.generate() return braintree.ClientToken.generate()

+ 1
- 1
payments/payment_gateways/doctype/braintree_settings/test_braintree_settings.py Visa fil

@@ -1,4 +1,4 @@
# Copyright (c) 2018, Frappe Technologies and Contributors
# Copyright (c) 2018, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE
import unittest import unittest




+ 2
- 2
payments/payment_gateways/doctype/paypal_settings/paypal_settings.js Visa fil

@@ -1,7 +1,7 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// Copyright (c) 2016, Xhive LLC
// For license information, please see license.txt // For license information, please see license.txt


frappe.ui.form.on('PayPal Settings', {
xhiveframework.ui.form.on('PayPal Settings', {
refresh: function(frm) { refresh: function(frm) {


} }


+ 49
- 49
payments/payment_gateways/doctype/paypal_settings/paypal_settings.py Visa fil

@@ -1,4 +1,4 @@
# Copyright (c) 2015, Frappe Technologies and contributors
# Copyright (c) 2015, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE


""" """
@@ -65,13 +65,13 @@ More Details:
import json import json
from urllib.parse import urlencode from urllib.parse import urlencode


import frappe
import xhiveframework
import pytz import pytz
from frappe import _
from frappe.integrations.utils import create_request_log, make_post_request
from frappe.model.document import Document
from frappe.utils import call_hook_method, cint, get_datetime, get_url
from frappe.utils.data import get_system_timezone
from xhiveframework import _
from xhiveframework.integrations.utils import create_request_log, make_post_request
from xhiveframework.model.document import Document
from xhiveframework.utils import call_hook_method, cint, get_datetime, get_url
from xhiveframework.utils.data import get_system_timezone


from payments.utils import create_payment_gateway from payments.utils import create_payment_gateway


@@ -113,8 +113,8 @@ class PayPalSettings(Document):
setattr(self, "use_sandbox", 0) setattr(self, "use_sandbox", 0)


def setup_sandbox_env(self, token): def setup_sandbox_env(self, token):
data = json.loads(frappe.db.get_value("Integration Request", token, "data"))
setattr(self, "use_sandbox", cint(frappe._dict(data).use_sandbox) or 0)
data = json.loads(xhiveframework.db.get_value("Integration Request", token, "data"))
setattr(self, "use_sandbox", cint(xhiveframework._dict(data).use_sandbox) or 0)


def validate(self): def validate(self):
create_payment_gateway("PayPal") create_payment_gateway("PayPal")
@@ -127,7 +127,7 @@ class PayPalSettings(Document):


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(
xhiveframework.throw(
_( _(
"Please select another payment method. PayPal does not support transactions in currency '{0}'" "Please select another payment method. PayPal does not support transactions in currency '{0}'"
).format(currency) ).format(currency)
@@ -145,9 +145,9 @@ class PayPalSettings(Document):
if hasattr(self, "use_sandbox") and self.use_sandbox: if hasattr(self, "use_sandbox") and self.use_sandbox:
params.update( params.update(
{ {
"USER": frappe.conf.sandbox_api_username,
"PWD": frappe.conf.sandbox_api_password,
"SIGNATURE": frappe.conf.sandbox_signature,
"USER": xhiveframework.conf.sandbox_api_username,
"PWD": xhiveframework.conf.sandbox_api_password,
"SIGNATURE": xhiveframework.conf.sandbox_signature,
} }
) )


@@ -170,7 +170,7 @@ class PayPalSettings(Document):
raise Exception raise Exception


except Exception: except Exception:
frappe.throw(_("Invalid payment gateway credentials"))
xhiveframework.throw(_("Invalid payment gateway credentials"))


def get_payment_url(self, **kwargs): def get_payment_url(self, **kwargs):
setattr(self, "use_sandbox", cint(kwargs.get("use_sandbox", 0))) setattr(self, "use_sandbox", cint(kwargs.get("use_sandbox", 0)))
@@ -216,7 +216,7 @@ class PayPalSettings(Document):
response = make_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(
xhiveframework.throw(
_("Looks like something is wrong with this site's Paypal configuration.") _("Looks like something is wrong with this site's Paypal configuration.")
) )


@@ -240,11 +240,11 @@ class PayPalSettings(Document):




def get_paypal_and_transaction_details(token): def get_paypal_and_transaction_details(token):
doc = frappe.get_doc("PayPal Settings")
doc = xhiveframework.get_doc("PayPal Settings")
doc.setup_sandbox_env(token) doc.setup_sandbox_env(token)
params, url = doc.get_paypal_params_and_url() params, url = doc.get_paypal_params_and_url()


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


return data, params, url return data, params, url
@@ -264,14 +264,14 @@ def setup_redirect(data, redirect_url, custom_redirect_to=None, redirect=True):


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




@frappe.whitelist(allow_guest=True, xss_safe=True)
@xhiveframework.whitelist(allow_guest=True, xss_safe=True)
def get_express_checkout_details(token): def get_express_checkout_details(token):
try: try:
doc = frappe.get_doc("PayPal Settings")
doc = xhiveframework.get_doc("PayPal Settings")
doc.setup_sandbox_env(token) doc.setup_sandbox_env(token)


params, url = doc.get_paypal_params_and_url() params, url = doc.get_paypal_params_and_url()
@@ -280,18 +280,18 @@ def get_express_checkout_details(token):
response = make_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(
xhiveframework.respond_as_web_page(
_("Something went wrong"), _("Something went wrong"),
_( _(
"Looks like something went wrong during the transaction. Since we haven't confirmed the payment, Paypal will automatically refund you this amount. If it doesn't, please send us an email and mention the Correlation ID: {0}." "Looks like something went wrong during the transaction. Since we haven't confirmed the payment, Paypal will automatically refund you this amount. If it doesn't, please send us an email and mention the Correlation ID: {0}."
).format(response.get("CORRELATIONID", [None])[0]), ).format(response.get("CORRELATIONID", [None])[0]),
indicator_color="red", indicator_color="red",
http_status_code=frappe.ValidationError.http_status_code,
http_status_code=xhiveframework.ValidationError.http_status_code,
) )


return return


doc = frappe.get_doc("Integration Request", token)
doc = xhiveframework.get_doc("Integration Request", token)
update_integration_request_status( update_integration_request_status(
token, token,
{"payerid": response.get("PAYERID")[0], "payer_email": response.get("EMAIL")[0]}, {"payerid": response.get("PAYERID")[0], "payer_email": response.get("EMAIL")[0]},
@@ -299,16 +299,16 @@ def get_express_checkout_details(token):
doc=doc, doc=doc,
) )


frappe.local.response["type"] = "redirect"
frappe.local.response["location"] = get_redirect_uri(
xhiveframework.local.response["type"] = "redirect"
xhiveframework.local.response["location"] = get_redirect_uri(
doc, token, response.get("PAYERID")[0] doc, token, response.get("PAYERID")[0]
) )


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




@frappe.whitelist(allow_guest=True, xss_safe=True)
@xhiveframework.whitelist(allow_guest=True, xss_safe=True)
def confirm_payment(token): def confirm_payment(token):
try: try:
custom_redirect_to = None custom_redirect_to = None
@@ -338,10 +338,10 @@ def confirm_payment(token):
) )


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


redirect_url = "payment-success?doctype={}&docname={}".format( redirect_url = "payment-success?doctype={}&docname={}".format(
data.get("reference_doctype"), data.get("reference_docname") data.get("reference_doctype"), data.get("reference_docname")
@@ -352,10 +352,10 @@ def confirm_payment(token):
setup_redirect(data, redirect_url, custom_redirect_to) setup_redirect(data, redirect_url, custom_redirect_to)


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




@frappe.whitelist(allow_guest=True, xss_safe=True)
@xhiveframework.whitelist(allow_guest=True, xss_safe=True)
def create_recurring_profile(token, payerid): def create_recurring_profile(token, payerid):
try: try:
custom_redirect_to = None custom_redirect_to = None
@@ -393,7 +393,7 @@ def create_recurring_profile(token, payerid):
) )


starts_at = ( starts_at = (
get_datetime(subscription_details.get("start_date")) or frappe.utils.now_datetime()
get_datetime(subscription_details.get("start_date")) or xhiveframework.utils.now_datetime()
) )
starts_at = starts_at.replace( starts_at = starts_at.replace(
tzinfo=pytz.timezone(get_system_timezone()) tzinfo=pytz.timezone(get_system_timezone())
@@ -416,11 +416,11 @@ def create_recurring_profile(token, payerid):
if data.get("reference_doctype") and data.get("reference_docname"): if data.get("reference_doctype") and data.get("reference_docname"):
data["subscription_id"] = response.get("PROFILEID")[0] data["subscription_id"] = response.get("PROFILEID")[0]


frappe.flags.data = data
custom_redirect_to = frappe.get_doc(
xhiveframework.flags.data = data
custom_redirect_to = xhiveframework.get_doc(
data.get("reference_doctype"), data.get("reference_docname") data.get("reference_doctype"), data.get("reference_docname")
).run_method("on_payment_authorized", status_changed_to) ).run_method("on_payment_authorized", status_changed_to)
frappe.db.commit()
xhiveframework.db.commit()


redirect_url = "payment-success?doctype={}&docname={}".format( redirect_url = "payment-success?doctype={}&docname={}".format(
data.get("reference_doctype"), data.get("reference_docname") data.get("reference_doctype"), data.get("reference_docname")
@@ -431,12 +431,12 @@ def create_recurring_profile(token, payerid):
setup_redirect(data, redirect_url, custom_redirect_to) setup_redirect(data, redirect_url, custom_redirect_to)


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




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


doc.update_status(data, status) doc.update_status(data, status)


@@ -468,30 +468,30 @@ def manage_recurring_payment_profile_status(profile_id, action, args, url):
if ( if (
response.get("ACK")[0] != "Success" and response.get("L_ERRORCODE0", [])[0] != "11556" response.get("ACK")[0] != "Success" and response.get("L_ERRORCODE0", [])[0] != "11556"
): ):
frappe.throw(_("Failed while amending subscription"))
xhiveframework.throw(_("Failed while amending subscription"))




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def ipn_handler(): def ipn_handler():
try: try:
data = frappe.local.form_dict
data = xhiveframework.local.form_dict


validate_ipn_request(data) validate_ipn_request(data)


data.update({"payment_gateway": "PayPal"}) data.update({"payment_gateway": "PayPal"})


doc = frappe.get_doc(
doc = xhiveframework.get_doc(
{ {
"data": json.dumps(frappe.local.form_dict),
"data": json.dumps(xhiveframework.local.form_dict),
"doctype": "Integration Request", "doctype": "Integration Request",
"request_description": "Subscription Notification", "request_description": "Subscription Notification",
"is_remote_request": 1, "is_remote_request": 1,
"status": "Queued", "status": "Queued",
} }
).insert(ignore_permissions=True) ).insert(ignore_permissions=True)
frappe.db.commit()
xhiveframework.db.commit()


frappe.enqueue(
xhiveframework.enqueue(
method="payments.payment_gateways.doctype.paypal_settings.paypal_settings.handle_subscription_notification", method="payments.payment_gateways.doctype.paypal_settings.paypal_settings.handle_subscription_notification",
queue="long", queue="long",
timeout=600, timeout=600,
@@ -499,20 +499,20 @@ def ipn_handler():
**{"doctype": "Integration Request", "docname": doc.name}, **{"doctype": "Integration Request", "docname": doc.name},
) )


except frappe.InvalidStatusError:
except xhiveframework.InvalidStatusError:
pass pass
except Exception as e: except Exception as e:
frappe.log(frappe.log_error(title=e))
xhiveframework.log(xhiveframework.log_error(title=e))




def validate_ipn_request(data): def validate_ipn_request(data):
def _throw(): def _throw():
frappe.throw(_("In Valid Request"), exc=frappe.InvalidStatusError)
xhiveframework.throw(_("In Valid Request"), exc=xhiveframework.InvalidStatusError)


if not data.get("recurring_payment_id"): if not data.get("recurring_payment_id"):
_throw() _throw()


doc = frappe.get_doc("PayPal Settings")
doc = xhiveframework.get_doc("PayPal Settings")
params, url = doc.get_paypal_params_and_url() params, url = doc.get_paypal_params_and_url()


params.update( params.update(


+ 3
- 3
payments/payment_gateways/doctype/paytm_settings/paytm_settings.js Visa fil

@@ -1,8 +1,8 @@
// Copyright (c) 2020, Frappe Technologies and contributors
// Copyright (c) 2020, Xhive LLC
// For license information, please see license.txt // For license information, please see license.txt


frappe.ui.form.on('Paytm Settings', {
xhiveframework.ui.form.on('Paytm Settings', {
refresh: function(frm) { refresh: function(frm) {
frm.dashboard.set_headline(__("For more information, {0}.", [`<a href='https://erpnext.com/docs/user/manual/en/erpnext_integration/paytm-integration'>${__('Click here')}</a>`]));
frm.dashboard.set_headline(__("For more information, {0}.", [`<a href='https://xhiveerp.com/docs/user/manual/en/xhiveerp_integration/paytm-integration'>${__('Click here')}</a>`]));
} }
}); });

+ 20
- 20
payments/payment_gateways/doctype/paytm_settings/paytm_settings.py Visa fil

@@ -1,15 +1,15 @@
# Copyright (c) 2020, Frappe Technologies and contributors
# Copyright (c) 2020, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE


import json import json
from urllib.parse import urlencode from urllib.parse import urlencode


import frappe
import xhiveframework
import requests import requests
from frappe import _
from frappe.integrations.utils import create_request_log
from frappe.model.document import Document
from frappe.utils import (
from xhiveframework import _
from xhiveframework.integrations.utils import create_request_log
from xhiveframework.model.document import Document
from xhiveframework.utils import (
call_hook_method, call_hook_method,
cint, cint,
cstr, cstr,
@@ -17,7 +17,7 @@ from frappe.utils import (
get_request_site_address, get_request_site_address,
get_url, get_url,
) )
from frappe.utils.password import get_decrypted_password
from xhiveframework.utils.password import get_decrypted_password
from paytmchecksum import generateSignature, verifySignature from paytmchecksum import generateSignature, verifySignature


from payments.utils import create_payment_gateway from payments.utils import create_payment_gateway
@@ -32,7 +32,7 @@ class PaytmSettings(Document):


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(
xhiveframework.throw(
_( _(
"Please select another payment method. Paytm does not support transactions in currency '{0}'" "Please select another payment method. Paytm does not support transactions in currency '{0}'"
).format(currency) ).format(currency)
@@ -50,7 +50,7 @@ class PaytmSettings(Document):
def get_paytm_config(): def get_paytm_config():
"""Returns paytm config""" """Returns paytm config"""


paytm_config = frappe.db.get_singles_dict("Paytm Settings")
paytm_config = xhiveframework.db.get_singles_dict("Paytm Settings")
paytm_config.update( paytm_config.update(
dict( dict(
merchant_key=get_decrypted_password( merchant_key=get_decrypted_password(
@@ -109,7 +109,7 @@ def get_paytm_params(payment_details, order_id, paytm_config):
return paytm_params return paytm_params




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def verify_transaction(**paytm_params): def verify_transaction(**paytm_params):
"""Verify checksum for received data in the callback and then verify the transaction""" """Verify checksum for received data in the callback and then verify the transaction"""
paytm_config = get_paytm_config() paytm_config = get_paytm_config()
@@ -127,13 +127,13 @@ def verify_transaction(**paytm_params):
if is_valid_checksum and paytm_params.get("RESPCODE") == "01": if is_valid_checksum and paytm_params.get("RESPCODE") == "01":
verify_transaction_status(paytm_config, paytm_params["ORDERID"]) verify_transaction_status(paytm_config, paytm_params["ORDERID"])
else: else:
frappe.respond_as_web_page(
xhiveframework.respond_as_web_page(
"Payment Failed", "Payment Failed",
"Transaction failed to complete. In case of any deductions, deducted amount will get refunded to your account.", "Transaction failed to complete. In case of any deductions, deducted amount will get refunded to your account.",
http_status_code=401, http_status_code=401,
indicator_color="red", indicator_color="red",
) )
frappe.log_error(
xhiveframework.log_error(
"Order unsuccessful. Failed Response:" + cstr(paytm_params), "Paytm Payment Failed" "Order unsuccessful. Failed Response:" + cstr(paytm_params), "Paytm Payment Failed"
) )


@@ -155,8 +155,8 @@ def verify_transaction_status(paytm_config, order_id):




def finalize_request(order_id, transaction_response): def finalize_request(order_id, transaction_response):
request = frappe.get_doc("Integration Request", order_id)
transaction_data = frappe._dict(json.loads(request.data))
request = xhiveframework.get_doc("Integration Request", order_id)
transaction_data = xhiveframework._dict(json.loads(request.data))
redirect_to = transaction_data.get("redirect_to") or None redirect_to = transaction_data.get("redirect_to") or None
redirect_message = transaction_data.get("redirect_message") or None redirect_message = transaction_data.get("redirect_message") or None


@@ -164,13 +164,13 @@ def finalize_request(order_id, transaction_response):
if transaction_data.reference_doctype and transaction_data.reference_docname: if transaction_data.reference_doctype and transaction_data.reference_docname:
custom_redirect_to = None custom_redirect_to = None
try: try:
custom_redirect_to = frappe.get_doc(
custom_redirect_to = xhiveframework.get_doc(
transaction_data.reference_doctype, transaction_data.reference_docname transaction_data.reference_doctype, transaction_data.reference_docname
).run_method("on_payment_authorized", "Completed") ).run_method("on_payment_authorized", "Completed")
request.db_set("status", "Completed") request.db_set("status", "Completed")
except Exception: except Exception:
request.db_set("status", "Failed") request.db_set("status", "Failed")
frappe.log_error(frappe.get_traceback())
xhiveframework.log_error(xhiveframework.get_traceback())


if custom_redirect_to: if custom_redirect_to:
redirect_to = custom_redirect_to redirect_to = custom_redirect_to
@@ -185,13 +185,13 @@ def finalize_request(order_id, transaction_response):
if redirect_message: if redirect_message:
redirect_url += "&" + urlencode({"redirect_message": redirect_message}) redirect_url += "&" + urlencode({"redirect_message": redirect_message})


frappe.local.response["type"] = "redirect"
frappe.local.response["location"] = redirect_url
xhiveframework.local.response["type"] = "redirect"
xhiveframework.local.response["location"] = redirect_url




def get_gateway_controller(doctype, docname): def get_gateway_controller(doctype, docname):
reference_doc = frappe.get_doc(doctype, docname)
gateway_controller = frappe.db.get_value(
reference_doc = xhiveframework.get_doc(doctype, docname)
gateway_controller = xhiveframework.db.get_value(
"Payment Gateway", reference_doc.payment_gateway, "gateway_controller" "Payment Gateway", reference_doc.payment_gateway, "gateway_controller"
) )
return gateway_controller return gateway_controller

+ 2
- 2
payments/payment_gateways/doctype/paytm_settings/test_paytm_settings.py Visa fil

@@ -1,6 +1,6 @@
# Copyright (c) 2020, Frappe Technologies and Contributors
# Copyright (c) 2020, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE
# import frappe
# import xhiveframework
import unittest import unittest






+ 3
- 3
payments/payment_gateways/doctype/razorpay_settings/razorpay_settings.js Visa fil

@@ -1,8 +1,8 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// Copyright (c) 2016, Xhive LLC
// For license information, please see license.txt // For license information, please see license.txt


frappe.ui.form.on('Razorpay Settings', {
xhiveframework.ui.form.on('Razorpay Settings', {
refresh: function(frm) { refresh: function(frm) {


} }
});
});

+ 63
- 63
payments/payment_gateways/doctype/razorpay_settings/razorpay_settings.py Visa fil

@@ -1,4 +1,4 @@
# Copyright (c) 2015, Frappe Technologies and contributors
# Copyright (c) 2015, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE


""" """
@@ -64,16 +64,16 @@ import hmac
import json import json
from urllib.parse import urlencode from urllib.parse import urlencode


import frappe
import xhiveframework
import razorpay import razorpay
from frappe import _
from frappe.integrations.utils import (
from xhiveframework import _
from xhiveframework.integrations.utils import (
create_request_log, create_request_log,
make_get_request, make_get_request,
make_post_request, make_post_request,
) )
from frappe.model.document import Document
from frappe.utils import call_hook_method, cint, get_timestamp, get_url
from xhiveframework.model.document import Document
from xhiveframework.utils import call_hook_method, cint, get_timestamp, get_url


from payments.utils import create_payment_gateway from payments.utils import create_payment_gateway


@@ -103,11 +103,11 @@ class RazorpaySettings(Document):
), ),
) )
except Exception: except Exception:
frappe.throw(_("Seems API Key or API Secret is wrong !!!"))
xhiveframework.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(
xhiveframework.throw(
_( _(
"Please select another payment method. Razorpay does not support transactions in currency '{0}'" "Please select another payment method. Razorpay does not support transactions in currency '{0}'"
).format(currency) ).format(currency)
@@ -131,7 +131,7 @@ class RazorpaySettings(Document):
) )


try: try:
if not frappe.conf.converted_rupee_to_paisa:
if not xhiveframework.conf.converted_rupee_to_paisa:
convert_rupee_to_paisa(**kwargs) convert_rupee_to_paisa(**kwargs)


for addon in kwargs.get("addons"): for addon in kwargs.get("addons"):
@@ -142,11 +142,11 @@ class RazorpaySettings(Document):
headers={"content-type": "application/json"}, headers={"content-type": "application/json"},
) )
if not resp.get("id"): if not resp.get("id"):
frappe.log_error(
xhiveframework.log_error(
message=str(resp), title="Razorpay Failed while creating subscription" message=str(resp), title="Razorpay Failed while creating subscription"
) )
except Exception: except Exception:
frappe.log_error()
xhiveframework.log_error()
# failed # failed
pass pass


@@ -180,21 +180,21 @@ class RazorpaySettings(Document):


if resp.get("status") == "created": if resp.get("status") == "created":
kwargs["subscription_id"] = resp.get("id") kwargs["subscription_id"] = resp.get("id")
frappe.flags.status = "created"
xhiveframework.flags.status = "created"
return kwargs return kwargs
else: else:
frappe.log_error(
xhiveframework.log_error(
message=str(resp), title="Razorpay Failed while creating subscription" message=str(resp), title="Razorpay Failed while creating subscription"
) )


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


def prepare_subscription_details(self, settings, **kwargs): def prepare_subscription_details(self, settings, **kwargs):
if not kwargs.get("subscription_id"): if not kwargs.get("subscription_id"):
kwargs = self.setup_subscription(settings, **kwargs) kwargs = self.setup_subscription(settings, **kwargs)


if frappe.flags.status != "created":
if xhiveframework.flags.status != "created":
kwargs["subscription_id"] = None kwargs["subscription_id"] = None


return kwargs return kwargs
@@ -232,21 +232,21 @@ class RazorpaySettings(Document):
order["integration_request"] = integration_request.name order["integration_request"] = integration_request.name
return order # Order returned to be consumed by razorpay.js return order # Order returned to be consumed by razorpay.js
except Exception: except Exception:
frappe.log(frappe.get_traceback())
frappe.throw(_("Could not create razorpay order"))
xhiveframework.log(xhiveframework.get_traceback())
xhiveframework.throw(_("Could not create razorpay order"))


def create_request(self, data): def create_request(self, data):
self.data = frappe._dict(data)
self.data = xhiveframework._dict(data)


try: try:
self.integration_request = frappe.get_doc("Integration Request", self.data.token)
self.integration_request = xhiveframework.get_doc("Integration Request", self.data.token)
self.integration_request.update_status(self.data, "Queued") self.integration_request.update_status(self.data, "Queued")
return self.authorize_payment() return self.authorize_payment()


except Exception: except Exception:
frappe.log_error(frappe.get_traceback())
xhiveframework.log_error(xhiveframework.get_traceback())
return { return {
"redirect_to": frappe.redirect_to_message(
"redirect_to": xhiveframework.redirect_to_message(
_("Server Error"), _("Server Error"),
_( _(
"Seems issue with server's razorpay config. Don't worry, in case of failure amount will get refunded to your account." "Seems issue with server's razorpay config. Don't worry, in case of failure amount will get refunded to your account."
@@ -288,12 +288,12 @@ class RazorpaySettings(Document):
self.flags.status_changed_to = "Verified" self.flags.status_changed_to = "Verified"


else: else:
frappe.log_error(message=str(resp), title="Razorpay Payment not authorized")
xhiveframework.log_error(message=str(resp), title="Razorpay Payment not authorized")


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


status = frappe.flags.integration_request.status_code
status = xhiveframework.flags.integration_request.status_code


redirect_to = data.get("redirect_to") or None redirect_to = data.get("redirect_to") or None
redirect_message = data.get("redirect_message") or None redirect_message = data.get("redirect_message") or None
@@ -301,13 +301,13 @@ class RazorpaySettings(Document):
if self.data.reference_doctype and self.data.reference_docname: if self.data.reference_doctype and self.data.reference_docname:
custom_redirect_to = None custom_redirect_to = None
try: try:
frappe.flags.data = data
custom_redirect_to = frappe.get_doc(
xhiveframework.flags.data = data
custom_redirect_to = xhiveframework.get_doc(
self.data.reference_doctype, self.data.reference_docname self.data.reference_doctype, self.data.reference_docname
).run_method("on_payment_authorized", self.flags.status_changed_to) ).run_method("on_payment_authorized", self.flags.status_changed_to)


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


if custom_redirect_to: if custom_redirect_to:
redirect_to = custom_redirect_to redirect_to = custom_redirect_to
@@ -326,7 +326,7 @@ class RazorpaySettings(Document):
return {"redirect_to": redirect_url, "status": status} return {"redirect_to": redirect_url, "status": status}


def get_settings(self, data): def get_settings(self, data):
settings = frappe._dict(
settings = xhiveframework._dict(
{ {
"api_key": self.api_key, "api_key": self.api_key,
"api_secret": self.get_password(fieldname="api_secret", raise_exception=False), "api_secret": self.get_password(fieldname="api_secret", raise_exception=False),
@@ -336,8 +336,8 @@ class RazorpaySettings(Document):
if cint(data.get("notes", {}).get("use_sandbox")) or data.get("use_sandbox"): if cint(data.get("notes", {}).get("use_sandbox")) or data.get("use_sandbox"):
settings.update( settings.update(
{ {
"api_key": frappe.conf.sandbox_api_key,
"api_secret": frappe.conf.sandbox_api_secret,
"api_key": xhiveframework.conf.sandbox_api_key,
"api_secret": xhiveframework.conf.sandbox_api_secret,
} }
) )


@@ -352,7 +352,7 @@ class RazorpaySettings(Document):
auth=(settings.api_key, settings.api_secret), auth=(settings.api_key, settings.api_secret),
) )
except Exception: except Exception:
frappe.log_error(frappe.get_traceback())
xhiveframework.log_error(xhiveframework.get_traceback())


def verify_signature(self, body, signature, key): def verify_signature(self, body, signature, key):
key = bytes(key, "utf-8") key = bytes(key, "utf-8")
@@ -364,7 +364,7 @@ class RazorpaySettings(Document):
result = hmac.compare_digest(generated_signature, signature) result = hmac.compare_digest(generated_signature, signature)


if not result: if not result:
frappe.throw(_("Razorpay Signature Verification Failed"), exc=frappe.PermissionError)
xhiveframework.throw(_("Razorpay Signature Verification Failed"), exc=xhiveframework.PermissionError)


return result return result


@@ -377,9 +377,9 @@ def capture_payment(is_sandbox=False, sanbox_response=None):


Note: Attempting to capture a payment whose status is not authorized will produce an error. Note: Attempting to capture a payment whose status is not authorized will produce an error.
""" """
controller = frappe.get_doc("Razorpay Settings")
controller = xhiveframework.get_doc("Razorpay Settings")


for doc in frappe.get_all(
for doc in xhiveframework.get_all(
"Integration Request", "Integration Request",
filters={"status": "Authorized", "integration_request_service": "Razorpay"}, filters={"status": "Authorized", "integration_request_service": "Razorpay"},
fields=["name", "data"], fields=["name", "data"],
@@ -407,37 +407,37 @@ def capture_payment(is_sandbox=False, sanbox_response=None):
) )


if resp.get("status") == "captured": if resp.get("status") == "captured":
frappe.db.set_value("Integration Request", doc.name, "status", "Completed")
xhiveframework.db.set_value("Integration Request", doc.name, "status", "Completed")


except Exception: except Exception:
doc = frappe.get_doc("Integration Request", doc.name)
doc = xhiveframework.get_doc("Integration Request", doc.name)
doc.status = "Failed" doc.status = "Failed"
doc.error = frappe.get_traceback()
doc.error = xhiveframework.get_traceback()
doc.save() doc.save()
frappe.log_error(doc.error, f"{doc.name} Failed")
xhiveframework.log_error(doc.error, f"{doc.name} Failed")




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def get_api_key(): def get_api_key():
controller = frappe.get_doc("Razorpay Settings")
controller = xhiveframework.get_doc("Razorpay Settings")
return controller.api_key return controller.api_key




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def get_order(doctype, docname): def get_order(doctype, docname):
# Order returned to be consumed by razorpay.js # Order returned to be consumed by razorpay.js
doc = frappe.get_doc(doctype, docname)
doc = xhiveframework.get_doc(doctype, docname)
try: try:
# Do not use run_method here as it fails silently # Do not use run_method here as it fails silently
return doc.get_razorpay_order() return doc.get_razorpay_order()
except AttributeError: except AttributeError:
frappe.log_error(
frappe.get_traceback(), _("Controller method get_razorpay_order missing")
xhiveframework.log_error(
xhiveframework.get_traceback(), _("Controller method get_razorpay_order missing")
) )
frappe.throw(_("Could not create Razorpay order. Please contact Administrator"))
xhiveframework.throw(_("Could not create Razorpay order. Please contact Administrator"))




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def order_payment_success(integration_request, params): def order_payment_success(integration_request, params):
"""Called by razorpay.js on order payment success, the params """Called by razorpay.js on order payment success, the params
contains razorpay_payment_id, razorpay_order_id, razorpay_signature contains razorpay_payment_id, razorpay_order_id, razorpay_signature
@@ -448,24 +448,24 @@ def order_payment_success(integration_request, params):
params (string): Params to be updated for integration request. params (string): Params to be updated for integration request.
""" """
params = json.loads(params) params = json.loads(params)
integration = frappe.get_doc("Integration Request", integration_request)
integration = xhiveframework.get_doc("Integration Request", integration_request)


# Update integration request # Update integration request
integration.update_status(params, integration.status) integration.update_status(params, integration.status)
integration.reload() integration.reload()


data = json.loads(integration.data) data = json.loads(integration.data)
controller = frappe.get_doc("Razorpay Settings")
controller = xhiveframework.get_doc("Razorpay Settings")


# Update payment and integration data for payment controller object # Update payment and integration data for payment controller object
controller.integration_request = integration controller.integration_request = integration
controller.data = frappe._dict(data)
controller.data = xhiveframework._dict(data)


# Authorize payment # Authorize payment
controller.authorize_payment() controller.authorize_payment()




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def order_payment_failure(integration_request, params): def order_payment_failure(integration_request, params):
"""Called by razorpay.js on failure """Called by razorpay.js on failure


@@ -473,9 +473,9 @@ def order_payment_failure(integration_request, params):
integration_request (TYPE): Description integration_request (TYPE): Description
params (TYPE): error data to be updated params (TYPE): error data to be updated
""" """
frappe.log_error(params, "Razorpay Payment Failure")
xhiveframework.log_error(params, "Razorpay Payment Failure")
params = json.loads(params) params = json.loads(params)
integration = frappe.get_doc("Integration Request", integration_request)
integration = xhiveframework.get_doc("Integration Request", integration_request)
integration.update_status(params, integration.status) integration.update_status(params, integration.status)




@@ -483,30 +483,30 @@ 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
xhiveframework.conf.converted_rupee_to_paisa = True




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def razorpay_subscription_callback(): def razorpay_subscription_callback():
try: try:
data = frappe.local.form_dict
data = xhiveframework.local.form_dict


validate_payment_callback(data) validate_payment_callback(data)


data.update({"payment_gateway": "Razorpay"}) data.update({"payment_gateway": "Razorpay"})


doc = frappe.get_doc(
doc = xhiveframework.get_doc(
{ {
"data": json.dumps(frappe.local.form_dict),
"data": json.dumps(xhiveframework.local.form_dict),
"doctype": "Integration Request", "doctype": "Integration Request",
"request_description": "Subscription Notification", "request_description": "Subscription Notification",
"is_remote_request": 1, "is_remote_request": 1,
"status": "Queued", "status": "Queued",
} }
).insert(ignore_permissions=True) ).insert(ignore_permissions=True)
frappe.db.commit()
xhiveframework.db.commit()


frappe.enqueue(
xhiveframework.enqueue(
method="payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.handle_subscription_notification", method="payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.handle_subscription_notification",
queue="long", queue="long",
timeout=600, timeout=600,
@@ -514,22 +514,22 @@ def razorpay_subscription_callback():
**{"doctype": "Integration Request", "docname": doc.name}, **{"doctype": "Integration Request", "docname": doc.name},
) )


except frappe.InvalidStatusError:
except xhiveframework.InvalidStatusError:
pass pass
except Exception as e: except Exception as e:
frappe.log(frappe.log_error(title=e))
xhiveframework.log(xhiveframework.log_error(title=e))




def validate_payment_callback(data): def validate_payment_callback(data):
def _throw(): def _throw():
frappe.throw(_("Invalid Subscription"), exc=frappe.InvalidStatusError)
xhiveframework.throw(_("Invalid Subscription"), exc=xhiveframework.InvalidStatusError)


subscription_id = data.get("payload").get("subscription").get("entity").get("id") subscription_id = data.get("payload").get("subscription").get("entity").get("id")


if not (subscription_id): if not (subscription_id):
_throw() _throw()


controller = frappe.get_doc("Razorpay Settings")
controller = xhiveframework.get_doc("Razorpay Settings")


settings = controller.get_settings(data) settings = controller.get_settings(data)




+ 2
- 2
payments/payment_gateways/doctype/stripe_settings/stripe_settings.js Visa fil

@@ -1,7 +1,7 @@
// Copyright (c) 2017, Frappe Technologies and contributors
// Copyright (c) 2017, Xhive LLC
// For license information, please see license.txt // For license information, please see license.txt


frappe.ui.form.on('Stripe Settings', {
xhiveframework.ui.form.on('Stripe Settings', {
refresh: function(frm) { refresh: function(frm) {


} }


+ 18
- 18
payments/payment_gateways/doctype/stripe_settings/stripe_settings.py Visa fil

@@ -1,13 +1,13 @@
# Copyright (c) 2017, Frappe Technologies and contributors
# Copyright (c) 2017, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE


from urllib.parse import urlencode from urllib.parse import urlencode


import frappe
from frappe import _
from frappe.integrations.utils import create_request_log, make_get_request
from frappe.model.document import Document
from frappe.utils import call_hook_method, cint, flt, get_url
import xhiveframework
from xhiveframework import _
from xhiveframework.integrations.utils import create_request_log, make_get_request
from xhiveframework.model.document import Document
from xhiveframework.utils import call_hook_method, cint, flt, get_url


from payments.utils import create_payment_gateway from payments.utils import create_payment_gateway


@@ -168,11 +168,11 @@ class StripeSettings(Document):
try: try:
make_get_request(url="https://api.stripe.com/v1/charges", headers=header) make_get_request(url="https://api.stripe.com/v1/charges", headers=header)
except Exception: except Exception:
frappe.throw(_("Seems Publishable Key or Secret Key is wrong !!!"))
xhiveframework.throw(_("Seems Publishable Key or Secret Key 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(
xhiveframework.throw(
_( _(
"Please select another payment method. Stripe does not support transactions in currency '{0}'" "Please select another payment method. Stripe does not support transactions in currency '{0}'"
).format(currency) ).format(currency)
@@ -181,7 +181,7 @@ class StripeSettings(Document):
def validate_minimum_transaction_amount(self, currency, amount): def validate_minimum_transaction_amount(self, currency, amount):
if currency in self.currency_wise_minimum_charge_amount: if currency in self.currency_wise_minimum_charge_amount:
if flt(amount) < self.currency_wise_minimum_charge_amount.get(currency, 0.0): if flt(amount) < self.currency_wise_minimum_charge_amount.get(currency, 0.0):
frappe.throw(
xhiveframework.throw(
_("For currency {0}, the minimum transaction amount should be {1}").format( _("For currency {0}, the minimum transaction amount should be {1}").format(
currency, self.currency_wise_minimum_charge_amount.get(currency, 0.0) currency, self.currency_wise_minimum_charge_amount.get(currency, 0.0)
) )
@@ -193,7 +193,7 @@ class StripeSettings(Document):
def create_request(self, data): def create_request(self, data):
import stripe import stripe


self.data = frappe._dict(data)
self.data = xhiveframework._dict(data)
stripe.api_key = self.get_password(fieldname="secret_key", raise_exception=False) stripe.api_key = self.get_password(fieldname="secret_key", raise_exception=False)
stripe.default_http_client = stripe.http_client.RequestsClient() stripe.default_http_client = stripe.http_client.RequestsClient()


@@ -202,9 +202,9 @@ class StripeSettings(Document):
return self.create_charge_on_stripe() return self.create_charge_on_stripe()


except Exception: except Exception:
frappe.log_error(frappe.get_traceback())
xhiveframework.log_error(xhiveframework.get_traceback())
return { return {
"redirect_to": frappe.redirect_to_message(
"redirect_to": xhiveframework.redirect_to_message(
_("Server Error"), _("Server Error"),
_( _(
"It seems that there is an issue with the server's stripe configuration. In case of failure, the amount will get refunded to your account." "It seems that there is an issue with the server's stripe configuration. In case of failure, the amount will get refunded to your account."
@@ -230,10 +230,10 @@ class StripeSettings(Document):
self.flags.status_changed_to = "Completed" self.flags.status_changed_to = "Completed"


else: else:
frappe.log_error(charge.failure_message, "Stripe Payment not completed")
xhiveframework.log_error(charge.failure_message, "Stripe Payment not completed")


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


return self.finalize_request() return self.finalize_request()


@@ -246,11 +246,11 @@ class StripeSettings(Document):
if self.data.reference_doctype and self.data.reference_docname: if self.data.reference_doctype and self.data.reference_docname:
custom_redirect_to = None custom_redirect_to = None
try: try:
custom_redirect_to = frappe.get_doc(
custom_redirect_to = xhiveframework.get_doc(
self.data.reference_doctype, self.data.reference_docname self.data.reference_doctype, self.data.reference_docname
).run_method("on_payment_authorized", self.flags.status_changed_to) ).run_method("on_payment_authorized", self.flags.status_changed_to)
except Exception: except Exception:
frappe.log_error(frappe.get_traceback())
xhiveframework.log_error(xhiveframework.get_traceback())


if custom_redirect_to: if custom_redirect_to:
redirect_to = custom_redirect_to redirect_to = custom_redirect_to
@@ -272,8 +272,8 @@ class StripeSettings(Document):




def get_gateway_controller(doctype, docname): def get_gateway_controller(doctype, docname):
reference_doc = frappe.get_doc(doctype, docname)
gateway_controller = frappe.db.get_value(
reference_doc = xhiveframework.get_doc(doctype, docname)
gateway_controller = xhiveframework.db.get_value(
"Payment Gateway", reference_doc.payment_gateway, "gateway_controller" "Payment Gateway", reference_doc.payment_gateway, "gateway_controller"
) )
return gateway_controller return gateway_controller

+ 1
- 1
payments/payment_gateways/doctype/stripe_settings/test_stripe_settings.py Visa fil

@@ -1,4 +1,4 @@
# Copyright (c) 2018, Frappe Technologies and Contributors
# Copyright (c) 2018, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE
import unittest import unittest




+ 2
- 2
payments/payments/doctype/payment_gateway/payment_gateway.js Visa fil

@@ -1,7 +1,7 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// Copyright (c) 2016, Xhive LLC Pvt. Ltd. and contributors
// For license information, please see license.txt // For license information, please see license.txt


frappe.ui.form.on('Payment Gateway', {
xhiveframework.ui.form.on('Payment Gateway', {
refresh: function(frm) { refresh: function(frm) {


} }


+ 2
- 2
payments/payments/doctype/payment_gateway/payment_gateway.py Visa fil

@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# Copyright (c) 2015, Xhive LLC Pvt. Ltd. and contributors
# License: MIT. See LICENSE # License: MIT. See LICENSE


from frappe.model.document import Document
from xhiveframework.model.document import Document




class PaymentGateway(Document): class PaymentGateway(Document):


+ 2
- 2
payments/payments/doctype/payment_gateway/test_payment_gateway.py Visa fil

@@ -1,8 +1,8 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2015, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE
import unittest import unittest


# test_records = frappe.get_test_records('Payment Gateway')
# test_records = xhiveframework.get_test_records('Payment Gateway')




class TestPaymentGateway(unittest.TestCase): class TestPaymentGateway(unittest.TestCase):


+ 9
- 9
payments/public/js/razorpay.js Visa fil

@@ -38,7 +38,7 @@ Razorpay Payment
"docname": "<REFERENCE DOCNAME" "docname": "<REFERENCE DOCNAME"
}; };


razorpay = new frappe.checkout.razorpay(options)
razorpay = new xhiveframework.checkout.razorpay(options)
razorpay.on_open = () => { razorpay.on_open = () => {
<SCRIPT TO RUN WHEN MODAL OPENS> <SCRIPT TO RUN WHEN MODAL OPENS>
} }
@@ -52,16 +52,16 @@ Razorpay Payment
} }
*/ */


frappe.provide("frappe.checkout");
xhiveframework.provide("xhiveframework.checkout");


frappe.require('https://checkout.razorpay.com/v1/checkout.js').then(() => {
frappe.checkout.razorpay = class RazorpayCheckout {
xhiveframework.require('https://checkout.razorpay.com/v1/checkout.js').then(() => {
xhiveframework.checkout.razorpay = class RazorpayCheckout {
constructor(opts) { constructor(opts) {
Object.assign(this, opts); Object.assign(this, opts);
} }


init() { init() {
frappe.run_serially([
xhiveframework.run_serially([
() => this.get_key(), () => this.get_key(),
() => this.make_order(), () => this.make_order(),
() => this.prepare_options(), () => this.prepare_options(),
@@ -80,7 +80,7 @@ frappe.require('https://checkout.razorpay.com/v1/checkout.js').then(() => {


get_key() { get_key() {
return new Promise(resolve => { return new Promise(resolve => {
frappe.call("payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.get_api_key").then(res => {
xhiveframework.call("payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.get_api_key").then(res => {
this.key = res.message; this.key = res.message;
resolve(true); resolve(true);
}) })
@@ -89,7 +89,7 @@ frappe.require('https://checkout.razorpay.com/v1/checkout.js').then(() => {


make_order() { make_order() {
return new Promise(resolve => { return new Promise(resolve => {
frappe.call("payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.get_order", {
xhiveframework.call("payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.get_order", {
doctype: this.doctype, doctype: this.doctype,
docname: this.docname docname: this.docname
}).then(res => { }).then(res => {
@@ -100,7 +100,7 @@ frappe.require('https://checkout.razorpay.com/v1/checkout.js').then(() => {
} }


order_success(response) { order_success(response) {
frappe.call("payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.order_payment_success", {
xhiveframework.call("payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.order_payment_success", {
integration_request: this.order.integration_request, integration_request: this.order.integration_request,
params: { params: {
razorpay_payment_id: response.razorpay_payment_id, razorpay_payment_id: response.razorpay_payment_id,
@@ -111,7 +111,7 @@ frappe.require('https://checkout.razorpay.com/v1/checkout.js').then(() => {
} }


order_fail(response) { order_fail(response) {
frappe.call( "payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.order_payment_failure", {
xhiveframework.call( "payments.payment_gateways.doctype.razorpay_settings.razorpay_settings.order_payment_failure", {
integration_request: this.order.integration_request, integration_request: this.order.integration_request,
params: response params: response
}) })


+ 2
- 2
payments/templates/includes/braintree_checkout.js Visa fil

@@ -2,7 +2,7 @@ $(document).ready(function() {


var button = document.querySelector('#submit-button'); var button = document.querySelector('#submit-button');
var form = document.querySelector('#payment-form'); var form = document.querySelector('#payment-form');
var data = {{ frappe.form_dict | json }};
var data = {{ xhiveframework.form_dict | json }};
var doctype = "{{ reference_doctype }}" var doctype = "{{ reference_doctype }}"
var docname = "{{ reference_docname }}" var docname = "{{ reference_docname }}"


@@ -20,7 +20,7 @@ $(document).ready(function() {
console.log('Error', err); console.log('Error', err);
return; return;
} }
frappe.call({
xhiveframework.call({
method: "payments.templates.pages.braintree_checkout.make_payment", method: "payments.templates.pages.braintree_checkout.make_payment",
freeze: true, freeze: true,
headers: { headers: {


+ 3
- 3
payments/templates/includes/razorpay_checkout.js Visa fil

@@ -15,7 +15,7 @@ $(document).ready(function(){
"email": "{{ payer_email }}", "email": "{{ payer_email }}",
"order_id": "{{ order_id }}" "order_id": "{{ order_id }}"
}, },
"notes": {{ frappe.form_dict|json }}
"notes": {{ xhiveframework.form_dict|json }}
}; };


var rzp = new Razorpay(options); var rzp = new Razorpay(options);
@@ -24,13 +24,13 @@ $(document).ready(function(){
})(); })();
}) })


frappe.provide('razorpay');
xhiveframework.provide('razorpay');


razorpay.make_payment_log = function(response, options, doctype, docname, token){ razorpay.make_payment_log = function(response, options, doctype, docname, token){
$('.razorpay-loading').addClass('hidden'); $('.razorpay-loading').addClass('hidden');
$('.razorpay-confirming').removeClass('hidden'); $('.razorpay-confirming').removeClass('hidden');


frappe.call({
xhiveframework.call({
method:"payments.templates.pages.razorpay_checkout.make_payment", method:"payments.templates.pages.razorpay_checkout.make_payment",
freeze:true, freeze:true,
headers: {"X-Requested-With": "XMLHttpRequest"}, headers: {"X-Requested-With": "XMLHttpRequest"},


+ 3
- 3
payments/templates/includes/stripe_checkout.js Visa fil

@@ -31,13 +31,13 @@ function setOutcome(result) {
if (result.token) { if (result.token) {
$('#submit').prop('disabled', true) $('#submit').prop('disabled', true)
$('#submit').html(__('Processing...')) $('#submit').html(__('Processing...'))
frappe.call({
xhiveframework.call({
method:"payments.templates.pages.stripe_checkout.make_payment", method:"payments.templates.pages.stripe_checkout.make_payment",
freeze:true, freeze:true,
headers: {"X-Requested-With": "XMLHttpRequest"}, headers: {"X-Requested-With": "XMLHttpRequest"},
args: { args: {
"stripe_token_id": result.token.id, "stripe_token_id": result.token.id,
"data": JSON.stringify({{ frappe.form_dict|json }}),
"data": JSON.stringify({{ xhiveframework.form_dict|json }}),
"reference_doctype": "{{ reference_doctype }}", "reference_doctype": "{{ reference_doctype }}",
"reference_docname": "{{ reference_docname }}" "reference_docname": "{{ reference_docname }}"
}, },
@@ -73,7 +73,7 @@ card.on('change', function(event) {
} }
}); });


frappe.ready(function() {
xhiveframework.ready(function() {
$('#submit').off("click").on("click", function(e) { $('#submit').off("click").on("click", function(e) {
e.preventDefault(); e.preventDefault();
var extraDetails = { var extraDetails = {


+ 13
- 13
payments/templates/pages/braintree_checkout.py Visa fil

@@ -1,11 +1,11 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2021, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE


import json import json


import frappe
from frappe import _
from frappe.utils import flt
import xhiveframework
from xhiveframework import _
from xhiveframework.utils import flt


from payments.payment_gateways.doctype.braintree_settings.braintree_settings import ( from payments.payment_gateways.doctype.braintree_settings.braintree_settings import (
get_client_token, get_client_token,
@@ -31,39 +31,39 @@ def get_context(context):
context.no_cache = 1 context.no_cache = 1


# all these keys exist in form_dict # all these keys exist in form_dict
if not (set(expected_keys) - set(list(frappe.form_dict))):
if not (set(expected_keys) - set(list(xhiveframework.form_dict))):
for key in expected_keys: for key in expected_keys:
context[key] = frappe.form_dict[key]
context[key] = xhiveframework.form_dict[key]


context.client_token = get_client_token(context.reference_docname) context.client_token = get_client_token(context.reference_docname)


context["amount"] = flt(context["amount"]) context["amount"] = flt(context["amount"])


gateway_controller = get_gateway_controller(context.reference_docname) gateway_controller = get_gateway_controller(context.reference_docname)
context["header_img"] = frappe.db.get_value(
context["header_img"] = xhiveframework.db.get_value(
"Braintree Settings", gateway_controller, "header_img" "Braintree Settings", gateway_controller, "header_img"
) )


else: else:
frappe.redirect_to_message(
xhiveframework.redirect_to_message(
_("Some information is missing"), _("Some information is missing"),
_( _(
"Looks like someone sent you to an incomplete URL. Please ask them to look into it." "Looks like someone sent you to an incomplete URL. Please ask them to look into it."
), ),
) )
frappe.local.flags.redirect_location = frappe.local.response.location
raise frappe.Redirect
xhiveframework.local.flags.redirect_location = xhiveframework.local.response.location
raise xhiveframework.Redirect




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def make_payment(payload_nonce, data, reference_doctype, reference_docname): def make_payment(payload_nonce, data, reference_doctype, reference_docname):
data = json.loads(data) data = json.loads(data)


data.update({"payload_nonce": payload_nonce}) data.update({"payload_nonce": payload_nonce})


gateway_controller = get_gateway_controller(reference_docname) gateway_controller = get_gateway_controller(reference_docname)
data = frappe.get_doc("Braintree Settings", gateway_controller).create_payment_request(
data = xhiveframework.get_doc("Braintree Settings", gateway_controller).create_payment_request(
data data
) )
frappe.db.commit()
xhiveframework.db.commit()
return data return data

+ 1
- 1
payments/templates/pages/payment-cancel.html Visa fil

@@ -9,7 +9,7 @@
{{ _("Payment Cancelled") }}</span> {{ _("Payment Cancelled") }}</span>
</div> </div>
<p>{{ _("Your payment is cancelled.") }}</p> <p>{{ _("Your payment is cancelled.") }}</p>
<div><a href='{{ frappe.form_dict.redirect_to or "/" }}' class='btn btn-primary btn-sm'>
<div><a href='{{ xhiveframework.form_dict.redirect_to or "/" }}' class='btn btn-primary btn-sm'>
{{ _("Continue") }}</a></div> {{ _("Continue") }}</a></div>
</div> </div>
<style> <style>


+ 1
- 1
payments/templates/pages/payment-failed.html Visa fil

@@ -9,7 +9,7 @@
{{ _("Payment Failed") }}</span> {{ _("Payment Failed") }}</span>
</div> </div>
<p>{{ _("Your payment has failed.") }}</p> <p>{{ _("Your payment has failed.") }}</p>
<div><a href='{{ frappe.form_dict.redirect_to or "/" }}' class='btn btn-primary btn-sm'>
<div><a href='{{ xhiveframework.form_dict.redirect_to or "/" }}' class='btn btn-primary btn-sm'>
{{ _("Continue") }}</a></div> {{ _("Continue") }}</a></div>
</div> </div>
<style> <style>


+ 4
- 4
payments/templates/pages/payment-success.html Visa fil

@@ -12,7 +12,7 @@
{% if not payment_message %} {% if not payment_message %}
<div> <div>
<a <a
href='{{ frappe.form_dict.redirect_to or "/" }}'
href='{{ xhiveframework.form_dict.redirect_to or "/" }}'
class='btn btn-primary btn-sm'> class='btn btn-primary btn-sm'>
{{ _("Continue") }} {{ _("Continue") }}
</a> </a>
@@ -23,10 +23,10 @@
{% include "templates/styles/card_style.css" %} {% include "templates/styles/card_style.css" %}
</style> </style>
<script> <script>
frappe.ready(function() {
if('{{ frappe.form_dict.redirect_to or "" }}'){
xhiveframework.ready(function() {
if('{{ xhiveframework.form_dict.redirect_to or "" }}'){
setTimeout(function(){ setTimeout(function(){
window.location.href = '{{ frappe.form_dict.redirect_to }}';
window.location.href = '{{ xhiveframework.form_dict.redirect_to }}';
}, 4000); }, 4000);
} }
}) })


+ 5
- 5
payments/templates/pages/payment_cancel.py Visa fil

@@ -1,12 +1,12 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2015, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE


import frappe
import xhiveframework




def get_context(context): def get_context(context):
token = frappe.local.form_dict.token
token = xhiveframework.local.form_dict.token


if token: if token:
frappe.db.set_value("Integration Request", token, "status", "Cancelled")
frappe.db.commit()
xhiveframework.db.set_value("Integration Request", token, "status", "Cancelled")
xhiveframework.db.commit()

+ 4
- 4
payments/templates/pages/payment_success.py Visa fil

@@ -1,14 +1,14 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2015, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE


import frappe
import xhiveframework


no_cache = True no_cache = True




def get_context(context): def get_context(context):
token = frappe.local.form_dict.token
doc = frappe.get_doc(frappe.local.form_dict.doctype, frappe.local.form_dict.docname)
token = xhiveframework.local.form_dict.token
doc = xhiveframework.get_doc(xhiveframework.local.form_dict.doctype, xhiveframework.local.form_dict.docname)


context.payment_message = "" context.payment_message = ""
if hasattr(doc, "get_payment_success_message"): if hasattr(doc, "get_payment_success_message"):


+ 8
- 8
payments/templates/pages/paytm_checkout.py Visa fil

@@ -1,9 +1,9 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2021, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE
import json import json


import frappe
from frappe import _
import xhiveframework
from xhiveframework import _


from payments.payment_gateways.doctype.paytm_settings.paytm_settings import ( from payments.payment_gateways.doctype.paytm_settings.paytm_settings import (
get_paytm_config, get_paytm_config,
@@ -16,7 +16,7 @@ def get_context(context):
paytm_config = get_paytm_config() paytm_config = get_paytm_config()


try: try:
doc = frappe.get_doc("Integration Request", frappe.form_dict["order_id"])
doc = xhiveframework.get_doc("Integration Request", xhiveframework.form_dict["order_id"])


context.payment_details = get_paytm_params( context.payment_details = get_paytm_params(
json.loads(doc.data), doc.name, paytm_config json.loads(doc.data), doc.name, paytm_config
@@ -25,13 +25,13 @@ def get_context(context):
context.url = paytm_config.url context.url = paytm_config.url


except Exception: except Exception:
frappe.log_error()
frappe.redirect_to_message(
xhiveframework.log_error()
xhiveframework.redirect_to_message(
_("Invalid Token"), _("Invalid Token"),
_("Seems token you are using is invalid!"), _("Seems token you are using is invalid!"),
http_status_code=400, http_status_code=400,
indicator_color="red", indicator_color="red",
) )


frappe.local.flags.redirect_location = frappe.local.response.location
raise frappe.Redirect
xhiveframework.local.flags.redirect_location = xhiveframework.local.response.location
raise xhiveframework.Redirect

+ 15
- 15
payments/templates/pages/razorpay_checkout.py Visa fil

@@ -1,10 +1,10 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2021, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE
import json import json


import frappe
from frappe import _
from frappe.utils import cint, flt
import xhiveframework
from xhiveframework import _
from xhiveframework.utils import cint, flt


no_cache = 1 no_cache = 1


@@ -26,39 +26,39 @@ def get_context(context):
context.api_key = get_api_key() context.api_key = get_api_key()


try: try:
doc = frappe.get_doc("Integration Request", frappe.form_dict["token"])
doc = xhiveframework.get_doc("Integration Request", xhiveframework.form_dict["token"])
payment_details = json.loads(doc.data) payment_details = json.loads(doc.data)


for key in expected_keys: for key in expected_keys:
context[key] = payment_details[key] context[key] = payment_details[key]


context["token"] = frappe.form_dict["token"]
context["token"] = xhiveframework.form_dict["token"]
context["amount"] = flt(context["amount"]) context["amount"] = flt(context["amount"])
context["subscription_id"] = ( context["subscription_id"] = (
payment_details["subscription_id"] if payment_details.get("subscription_id") else "" payment_details["subscription_id"] if payment_details.get("subscription_id") else ""
) )


except Exception as e: except Exception as e:
frappe.redirect_to_message(
xhiveframework.redirect_to_message(
_("Invalid Token"), _("Invalid Token"),
_("Seems token you are using is invalid!"), _("Seems token you are using is invalid!"),
http_status_code=400, http_status_code=400,
indicator_color="red", indicator_color="red",
) )


frappe.local.flags.redirect_location = frappe.local.response.location
raise frappe.Redirect
xhiveframework.local.flags.redirect_location = xhiveframework.local.response.location
raise xhiveframework.Redirect




def get_api_key(): def get_api_key():
api_key = frappe.db.get_single_value("Razorpay Settings", "api_key")
if cint(frappe.form_dict.get("use_sandbox")):
api_key = frappe.conf.sandbox_api_key
api_key = xhiveframework.db.get_single_value("Razorpay Settings", "api_key")
if cint(xhiveframework.form_dict.get("use_sandbox")):
api_key = xhiveframework.conf.sandbox_api_key


return api_key return api_key




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def make_payment( def make_payment(
razorpay_payment_id, options, reference_doctype, reference_docname, token razorpay_payment_id, options, reference_doctype, reference_docname, token
): ):
@@ -76,6 +76,6 @@ def make_payment(
} }
) )


data = frappe.get_doc("Razorpay Settings").create_request(data)
frappe.db.commit()
data = xhiveframework.get_doc("Razorpay Settings").create_request(data)
xhiveframework.db.commit()
return data return data

+ 21
- 21
payments/templates/pages/stripe_checkout.py Visa fil

@@ -1,10 +1,10 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2021, Xhive LLC
# License: MIT. See LICENSE # License: MIT. See LICENSE
import json import json


import frappe
from frappe import _
from frappe.utils import cint, fmt_money
import xhiveframework
from xhiveframework import _
from xhiveframework.utils import cint, fmt_money


from payments.payment_gateways.doctype.stripe_settings.stripe_settings import ( from payments.payment_gateways.doctype.stripe_settings.stripe_settings import (
get_gateway_controller, get_gateway_controller,
@@ -29,9 +29,9 @@ def get_context(context):
context.no_cache = 1 context.no_cache = 1


# all these keys exist in form_dict # all these keys exist in form_dict
if not (set(expected_keys) - set(list(frappe.form_dict))):
if not (set(expected_keys) - set(list(xhiveframework.form_dict))):
for key in expected_keys: for key in expected_keys:
context[key] = frappe.form_dict[key]
context[key] = xhiveframework.form_dict[key]


gateway_controller = get_gateway_controller( gateway_controller = get_gateway_controller(
context.reference_doctype, context.reference_docname context.reference_doctype, context.reference_docname
@@ -42,41 +42,41 @@ def get_context(context):
context["amount"] = fmt_money(amount=context["amount"], currency=context["currency"]) context["amount"] = fmt_money(amount=context["amount"], currency=context["currency"])


if is_a_subscription(context.reference_doctype, context.reference_docname): if is_a_subscription(context.reference_doctype, context.reference_docname):
payment_plan = frappe.db.get_value(
payment_plan = xhiveframework.db.get_value(
context.reference_doctype, context.reference_docname, "payment_plan" context.reference_doctype, context.reference_docname, "payment_plan"
) )
recurrence = frappe.db.get_value("Payment Plan", payment_plan, "recurrence")
recurrence = xhiveframework.db.get_value("Payment Plan", payment_plan, "recurrence")


context["amount"] = context["amount"] + " " + _(recurrence) context["amount"] = context["amount"] + " " + _(recurrence)


else: else:
frappe.redirect_to_message(
xhiveframework.redirect_to_message(
_("Some information is missing"), _("Some information is missing"),
_( _(
"Looks like someone sent you to an incomplete URL. Please ask them to look into it." "Looks like someone sent you to an incomplete URL. Please ask them to look into it."
), ),
) )
frappe.local.flags.redirect_location = frappe.local.response.location
raise frappe.Redirect
xhiveframework.local.flags.redirect_location = xhiveframework.local.response.location
raise xhiveframework.Redirect




def get_api_key(doc, gateway_controller): def get_api_key(doc, gateway_controller):
publishable_key = frappe.db.get_value(
publishable_key = xhiveframework.db.get_value(
"Stripe Settings", gateway_controller, "publishable_key" "Stripe Settings", gateway_controller, "publishable_key"
) )
if cint(frappe.form_dict.get("use_sandbox")):
publishable_key = frappe.conf.sandbox_publishable_key
if cint(xhiveframework.form_dict.get("use_sandbox")):
publishable_key = xhiveframework.conf.sandbox_publishable_key


return publishable_key return publishable_key




def get_header_image(doc, gateway_controller): def get_header_image(doc, gateway_controller):
header_image = frappe.db.get_value("Stripe Settings", gateway_controller, "header_img")
header_image = xhiveframework.db.get_value("Stripe Settings", gateway_controller, "header_img")


return header_image return header_image




@frappe.whitelist(allow_guest=True)
@xhiveframework.whitelist(allow_guest=True)
def make_payment(stripe_token_id, data, reference_doctype=None, reference_docname=None): def make_payment(stripe_token_id, data, reference_doctype=None, reference_docname=None):
data = json.loads(data) data = json.loads(data)


@@ -85,16 +85,16 @@ def make_payment(stripe_token_id, data, reference_doctype=None, reference_docnam
gateway_controller = get_gateway_controller(reference_doctype, reference_docname) gateway_controller = get_gateway_controller(reference_doctype, reference_docname)


if is_a_subscription(reference_doctype, reference_docname): if is_a_subscription(reference_doctype, reference_docname):
reference = frappe.get_doc(reference_doctype, reference_docname)
reference = xhiveframework.get_doc(reference_doctype, reference_docname)
data = reference.create_subscription("stripe", gateway_controller, data) data = reference.create_subscription("stripe", gateway_controller, data)
else: else:
data = frappe.get_doc("Stripe Settings", gateway_controller).create_request(data)
data = xhiveframework.get_doc("Stripe Settings", gateway_controller).create_request(data)


frappe.db.commit()
xhiveframework.db.commit()
return data return data




def is_a_subscription(reference_doctype, reference_docname): def is_a_subscription(reference_doctype, reference_docname):
if not frappe.get_meta(reference_doctype).has_field("is_a_subscription"):
if not xhiveframework.get_meta(reference_doctype).has_field("is_a_subscription"):
return False return False
return frappe.db.get_value(reference_doctype, reference_docname, "is_a_subscription")
return xhiveframework.db.get_value(reference_doctype, reference_docname, "is_a_subscription")

+ 22
- 22
payments/utils/utils.py Visa fil

@@ -1,47 +1,47 @@
import click import click
import frappe
from frappe import _
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
import xhiveframework
from xhiveframework import _
from xhiveframework.custom.doctype.custom_field.custom_field import create_custom_fields




def get_payment_gateway_controller(payment_gateway): def get_payment_gateway_controller(payment_gateway):
"""Return payment gateway controller""" """Return payment gateway controller"""
gateway = frappe.get_doc("Payment Gateway", payment_gateway)
gateway = xhiveframework.get_doc("Payment Gateway", payment_gateway)
if gateway.gateway_controller is None: if gateway.gateway_controller is None:
try: try:
return frappe.get_doc(f"{payment_gateway} Settings")
return xhiveframework.get_doc(f"{payment_gateway} Settings")
except Exception: except Exception:
frappe.throw(_("{0} Settings not found").format(payment_gateway))
xhiveframework.throw(_("{0} Settings not found").format(payment_gateway))
else: else:
try: try:
return frappe.get_doc(gateway.gateway_settings, gateway.gateway_controller)
return xhiveframework.get_doc(gateway.gateway_settings, gateway.gateway_controller)
except Exception: except Exception:
frappe.throw(_("{0} Settings not found").format(payment_gateway))
xhiveframework.throw(_("{0} Settings not found").format(payment_gateway))




@frappe.whitelist(allow_guest=True, xss_safe=True)
@xhiveframework.whitelist(allow_guest=True, xss_safe=True)
def get_checkout_url(**kwargs): def get_checkout_url(**kwargs):
try: try:
if kwargs.get("payment_gateway"): if kwargs.get("payment_gateway"):
doc = frappe.get_doc("{} Settings".format(kwargs.get("payment_gateway")))
doc = xhiveframework.get_doc("{} Settings".format(kwargs.get("payment_gateway")))
return doc.get_payment_url(**kwargs) return doc.get_payment_url(**kwargs)
else: else:
raise Exception raise Exception
except Exception: except Exception:
frappe.respond_as_web_page(
xhiveframework.respond_as_web_page(
_("Something went wrong"), _("Something went wrong"),
_( _(
"Looks like something is wrong with this site's payment gateway configuration. No payment has been made." "Looks like something is wrong with this site's payment gateway configuration. No payment has been made."
), ),
indicator_color="red", indicator_color="red",
http_status_code=frappe.ValidationError.http_status_code,
http_status_code=xhiveframework.ValidationError.http_status_code,
) )




def create_payment_gateway(gateway, settings=None, controller=None): def create_payment_gateway(gateway, settings=None, controller=None):
# NOTE: we don't translate Payment Gateway name because it is an internal doctype # NOTE: we don't translate Payment Gateway name because it is an internal doctype
if not frappe.db.exists("Payment Gateway", gateway):
payment_gateway = frappe.get_doc(
if not xhiveframework.db.exists("Payment Gateway", gateway):
payment_gateway = xhiveframework.get_doc(
{ {
"doctype": "Payment Gateway", "doctype": "Payment Gateway",
"gateway": gateway, "gateway": gateway,
@@ -53,7 +53,7 @@ def create_payment_gateway(gateway, settings=None, controller=None):




def make_custom_fields(): def make_custom_fields():
if not frappe.get_meta("Web Form").has_field("payments_tab"):
if not xhiveframework.get_meta("Web Form").has_field("payments_tab"):
click.secho("* Installing Payment Custom Fields in Web Form") click.secho("* Installing Payment Custom Fields in Web Form")


create_custom_fields( create_custom_fields(
@@ -134,11 +134,11 @@ def make_custom_fields():
} }
) )


frappe.clear_cache(doctype="Web Form")
xhiveframework.clear_cache(doctype="Web Form")




def delete_custom_fields(): def delete_custom_fields():
if frappe.get_meta("Web Form").has_field("payments_tab"):
if xhiveframework.get_meta("Web Form").has_field("payments_tab"):
click.secho("* Uninstalling Payment Custom Fields from Web Form") click.secho("* Uninstalling Payment Custom Fields from Web Form")


fieldnames = ( fieldnames = (
@@ -155,19 +155,19 @@ def delete_custom_fields():
) )


for fieldname in fieldnames: for fieldname in fieldnames:
frappe.db.delete("Custom Field", {"name": "Web Form-" + fieldname})
xhiveframework.db.delete("Custom Field", {"name": "Web Form-" + fieldname})


frappe.clear_cache(doctype="Web Form")
xhiveframework.clear_cache(doctype="Web Form")




def before_install(): def before_install():
# TODO: remove this # TODO: remove this
# This is done for erpnext CI patch test
# This is done for xhiveerp CI patch test
# #
# Since we follow a flow like install v14 -> restore v10 site # Since we follow a flow like install v14 -> restore v10 site
# -> migrate to v12, v13 and then v14 again # -> migrate to v12, v13 and then v14 again
# #
# This app fails installing when the site is restored to v10 as # This app fails installing when the site is restored to v10 as
# a lot of apis don;t exist in v10 and this is a (at the moment) required app for erpnext.
if not frappe.get_meta("Module Def").has_field("custom"):
# a lot of apis don;t exist in v10 and this is a (at the moment) required app for xhiveerp.
if not xhiveframework.get_meta("Module Def").has_field("custom"):
return False return False

+ 1
- 1
requirements.txt Visa fil

@@ -1,4 +1,4 @@
# frappe -- https://github.com/frappe/frappe is installed via 'bench init'
# xhiveframework -- https://github.com/xhiveframework/xhiveframework is installed via 'bench init'
paytmchecksum~=1.7.0 paytmchecksum~=1.7.0
razorpay~=1.2.0 razorpay~=1.2.0
stripe~=2.56.0 stripe~=2.56.0


+ 3
- 3
setup.py Visa fil

@@ -9,9 +9,9 @@ from payments import __version__ as version
setup( setup(
name="payments", name="payments",
version=version, version=version,
description="Payments app for frappe",
author="Frappe Technologies",
author_email="hello@frappe.io",
description="Payments app for xhiveframework",
author="Xhive LLC",
author_email="hello@xhiveframework.com",
packages=find_packages(), packages=find_packages(),
zip_safe=False, zip_safe=False,
include_package_data=True, include_package_data=True,


Laddar…
Avbryt
Spara