コード例 #1
0
def get_express_checkout_details(token):
	try:
		doc = frappe.get_doc("PayPal Settings")
		doc.setup_sandbox_env(token)

		params, url = doc.get_paypal_params_and_url()
		params.update({
			"METHOD": "GetExpressCheckoutDetails",
			"TOKEN": token
		})

		response = make_post_request(url, data=params)

		if response.get("ACK")[0] != "Success":
			frappe.respond_as_web_page(_("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}.").format(response.get("CORRELATIONID", [None])[0]),
				indicator_color='red',
				http_status_code=frappe.ValidationError.http_status_code)

			return

		update_integration_request_status(token, {
				"payerid": response.get("PAYERID")[0],
				"payer_email": response.get("EMAIL")[0]
			}, "Authorized")

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

	except Exception:
		frappe.log_error(frappe.get_traceback())
コード例 #2
0
	def create_order(self, **kwargs):
		# Creating Orders https://midtrans.com/docs/api/orders/

		# convert rupees to paisa
		kwargs['amount'] *= 100

		# Create integration log
		integration_request = create_request_log(kwargs, "Host", "midtrans")

		# Setup payment options
		payment_options = {
			"amount": kwargs.get('amount'),
			"currency": kwargs.get('currency', 'INR'),
			"receipt": kwargs.get('receipt'),
			"payment_capture": kwargs.get('payment_capture')
		}
		controller = frappe.get_doc("midtrans Settings")
		for doc in frappe.get_all("Integration Request", filters={"status": "Authorized", "integration_request_service": "midtrans"}, fields=["name", "data"]):
			data = json.loads(doc.data)
			settings = controller.get_settings(data)

			if self.client_key and self.server_key:
				try:
					order = make_post_request(settings.base_url + "/transactions",
						auth=(self.client_key, self.get_password(fieldname="server_key", raise_exception=False)),
						data=payment_options)
					order['integration_request'] = integration_request.name
					return order # Order returned to be consumed by midtrans.js
				except Exception:
					frappe.log(frappe.get_traceback())
					frappe.throw(_("Could not create midtrans order"))
コード例 #3
0
    def setup_addon(self, settings, **kwargs):
        """
			Addon template:
			{
				"item": {
					"name": row.upgrade_type,
					"amount": row.amount,
					"currency": currency,
					"description": "add-on description"
				},
				"quantity": 1 (The total amount is calculated as item.amount * quantity)
			}
		"""
        url = "https://api.razorpay.com/v1/subscriptions/{0}/addons".format(
            kwargs.get('subscription_id'))

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

            for addon in kwargs.get("addons"):
                resp = make_post_request(
                    url,
                    auth=(settings.api_key, settings.api_secret),
                    data=json.dumps(addon),
                    headers={"content-type": "application/json"})
                if not resp.get('id'):
                    frappe.log_error(
                        str(resp),
                        'Razorpay Failed while creating subscription')
        except:
            frappe.log_error(frappe.get_traceback())
            # failed
            pass
コード例 #4
0
def capture_payment(is_sandbox=False, sanbox_response=None):
	"""
		Verifies the purchase as complete by the merchant.
		After capture, the amount is transferred to the merchant within T+3 days
		where T is the day on which payment is captured.

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

	for doc in frappe.get_all("Integration Request", filters={"status": "Authorized",
		"integration_request_service": "Razorpay"}, fields=["name", "data"]):
		try:
			if is_sandbox:
				resp = sanbox_response
			else:
				data = json.loads(doc.data)
				settings = controller.get_settings(data)

				resp = make_post_request("https://api.razorpay.com/v1/payments/{0}/capture".format(data.get("razorpay_payment_id")),
					auth=(settings.api_key, settings.api_secret), data={"amount": data.get("amount")})

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

		except Exception:
			doc = frappe.get_doc("Integration Request", doc.name)
			doc.status = "Failed"
			doc.error = frappe.get_traceback()
			frappe.log_error(doc.error, '{0} Failed'.format(doc.name))
コード例 #5
0
    def create_order(self, **kwargs):
        # Creating Orders https://razorpay.com/docs/api/orders/

        # convert rupees to paisa
        kwargs['amount'] *= 100

        # Create integration log
        integration_request = create_request_log(kwargs, "Host", "Razorpay")

        # Setup payment options
        payment_options = {
            "amount": kwargs.get('amount'),
            "currency": kwargs.get('currency', 'INR'),
            "receipt": kwargs.get('receipt'),
            "payment_capture": kwargs.get('payment_capture')
        }
        if self.api_key and self.api_secret:
            try:
                order = make_post_request("https://api.razorpay.com/v1/orders",
                                          auth=(self.api_key,
                                                self.get_password(
                                                    fieldname="api_secret",
                                                    raise_exception=False)),
                                          data=payment_options)
                order['integration_request'] = integration_request.name
                return order  # Order returned to be consumed by razorpay.js
            except Exception:
                frappe.log(frappe.get_traceback())
                frappe.throw(_("Could not create razorpay order"))
コード例 #6
0
    def execute_set_express_checkout(self, amount, currency):
        params, url = self.get_paypal_params_and_url()
        params.update({
            "METHOD":
            "SetExpressCheckout",
            "PAYMENTREQUEST_0_PAYMENTACTION":
            "SALE",
            "PAYMENTREQUEST_0_AMT":
            amount,
            "PAYMENTREQUEST_0_CURRENCYCODE":
            currency.upper(),
            "returnUrl":
            get_url(
                "/api/method/frappe.integrations.doctype.paypal_settings.paypal_settings.get_express_checkout_details"
            ),
            "cancelUrl":
            get_url("/payment-cancel")
        })

        params = urlencode(params)

        response = make_post_request(url, data=params.encode("utf-8"))
        if response.get("ACK")[0] != "Success":
            frappe.throw(
                _("Looks like something is wrong with this site's Paypal configuration."
                  ))

        return response
コード例 #7
0
def confirm_payment(token):
	try:
		custom_redirect_to = None
		data, params, url = get_paypal_and_transaction_details(token)

		params.update({
			"METHOD": "DoExpressCheckoutPayment",
			"PAYERID": data.get("payerid"),
			"TOKEN": token,
			"PAYMENTREQUEST_0_PAYMENTACTION": "SALE",
			"PAYMENTREQUEST_0_AMT": data.get("amount"),
			"PAYMENTREQUEST_0_CURRENCYCODE": data.get("currency").upper()
		})

		response = make_post_request(url, data=params)

		if response.get("ACK")[0] == "Success":
			update_integration_request_status(token, {
				"transaction_id": response.get("PAYMENTINFO_0_TRANSACTIONID")[0],
				"correlation_id": response.get("CORRELATIONID")[0]
			}, "Completed")

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

			redirect_url = '/integrations/payment-success?doctype={0}&docname={1}'.format(data.get("reference_doctype"), data.get("reference_docname"))
		else:
			redirect_url = "/integrations/payment-failed"

		setup_redirect(data, redirect_url, custom_redirect_to)

	except Exception:
		frappe.log_error(frappe.get_traceback())
コード例 #8
0
ファイル: razorpay_settings.py プロジェクト: ESS-LLP/frappe
	def setup_addon(self, settings, **kwargs):
		"""
			Addon template:
			{
				"item": {
					"name": row.upgrade_type,
					"amount": row.amount,
					"currency": currency,
					"description": "add-on description"
				},
				"quantity": 1 (The total amount is calculated as item.amount * quantity)
			}
		"""
		url = "https://api.razorpay.com/v1/subscriptions/{0}/addons".format(kwargs.get('subscription_id'))

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

			for addon in kwargs.get("addons"):
				resp = make_post_request(
					url,
					auth=(settings.api_key, settings.api_secret),
					data=json.dumps(addon),
					headers={
						"content-type": "application/json"
					}
				)
				if not resp.get('id'):
					frappe.log_error(str(resp), 'Razorpay Failed while creating subscription')
		except:
			frappe.log_error(frappe.get_traceback())
			# failed
			pass
コード例 #9
0
def get_express_checkout_details(token):
    try:
        doc = frappe.get_doc("PayPal Settings")
        doc.setup_sandbox_env(token)

        params, url = doc.get_paypal_params_and_url()
        params.update({"METHOD": "GetExpressCheckoutDetails", "TOKEN": token})

        response = make_post_request(url, data=params)

        if response.get("ACK")[0] != "Success":
            frappe.respond_as_web_page(
                _("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}."
                  ).format(response.get("CORRELATIONID", [None])[0]),
                indicator_color='red',
                http_status_code=frappe.ValidationError.http_status_code)

            return

        update_integration_request_status(
            token, {
                "payerid": response.get("PAYERID")[0],
                "payer_email": response.get("EMAIL")[0]
            }, "Authorized")

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

    except Exception:
        frappe.log_error(frappe.get_traceback())
コード例 #10
0
def capture_payment(is_sandbox=False, sanbox_response=None):
	"""
		Verifies the purchase as complete by the merchant.
		After capture, the amount is transferred to the merchant within T+3 days
		where T is the day on which payment is captured.

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

	for doc in frappe.get_all("Integration Request", filters={"status": "Authorized",
		"integration_request_service": "midtrans"}, fields=["name", "data"]):
		try:
			if is_sandbox:
				resp = sanbox_response
			else:
				data = json.loads(doc.data)
				settings = controller.get_settings(data)

				resp = make_get_request(settings.base_url +"/transactions/{0}".format(data.get("midtrans_settings_id")),
					auth=(settings.client_key, settings.server_key), data={"amount": data.get("amount")})

				if resp.get('status') == "authorized":
					resp = make_post_request(settings.base_url +"/transactions/{0}/capture".format(data.get("midtrans_settings_id")),
						auth=(settings.client_key, settings.server_key), data={"amount": data.get("amount")})

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

		except Exception:
			doc = frappe.get_doc("Integration Request", doc.name)
			doc.status = "Failed"
			doc.error = frappe.get_traceback()
			frappe.log_error(doc.error, '{0} Failed'.format(doc.name))
コード例 #11
0
def confirm_payment(token):
    try:
        redirect = True
        status_changed_to, redirect_to = None, None

        doc = frappe.get_doc("Paynow Settings")

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

        response = make_post_request(url, data=params)

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

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

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

    def update_integration_request_status(token, data, status, error=False):
        frappe.get_doc("Integration Request",
                       token).update_status(data, status)

    '''
コード例 #12
0
ファイル: paypal_settings.py プロジェクト: ESS-LLP/frappe
def confirm_payment(token):
	try:
		custom_redirect_to = None
		data, params, url = get_paypal_and_transaction_details(token)

		params.update({
			"METHOD": "DoExpressCheckoutPayment",
			"PAYERID": data.get("payerid"),
			"TOKEN": token,
			"PAYMENTREQUEST_0_PAYMENTACTION": "SALE",
			"PAYMENTREQUEST_0_AMT": data.get("amount"),
			"PAYMENTREQUEST_0_CURRENCYCODE": data.get("currency").upper()
		})

		response = make_post_request(url, data=params)

		if response.get("ACK")[0] == "Success":
			update_integration_request_status(token, {
				"transaction_id": response.get("PAYMENTINFO_0_TRANSACTIONID")[0],
				"correlation_id": response.get("CORRELATIONID")[0]
			}, "Completed")

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

			redirect_url = '/integrations/payment-success?doctype={0}&docname={1}'.format(data.get("reference_doctype"), data.get("reference_docname"))
		else:
			redirect_url = "/integrations/payment-failed"

		setup_redirect(data, redirect_url, custom_redirect_to)

	except Exception:
		frappe.log_error(frappe.get_traceback())
コード例 #13
0
ファイル: paypal_settings.py プロジェクト: Anju-P/moms-bench
    def execute_set_express_checkout(self, **kwargs):
        params, url = self.get_paypal_params_and_url()

        params.update({
            "METHOD":
            "SetExpressCheckout",
            "returnUrl":
            get_url("{0}.get_express_checkout_details".format(api_path)),
            "cancelUrl":
            get_url("/payment-cancel"),
            "PAYMENTREQUEST_0_PAYMENTACTION":
            "SALE",
            "PAYMENTREQUEST_0_AMT":
            kwargs['amount'],
            "PAYMENTREQUEST_0_CURRENCYCODE":
            kwargs['currency'].upper()
        })

        if kwargs.get('subscription_details'):
            self.configure_recurring_payments(params, kwargs)

        params = urlencode(params)
        response = make_post_request(url, data=params.encode("utf-8"))

        if response.get("ACK")[0] != "Success":
            frappe.throw(
                _("Looks like something is wrong with this site's Paypal configuration."
                  ))

        return response
コード例 #14
0
ファイル: daily.py プロジェクト: ruchamahabal/iff
	def trigger_payment_for_member(self, member):
		"""Trigger Razorpay payment and return payment ID

		Args:
			member (object): Member doctype object

		Returns:
			string: Razorpay payment ID
		"""
		# https://razorpay.com/docs/api/recurring-payments/emandate/subsequent-payments/
		amount = self.plans[member.membership_type] * 100 # convert rupee to paise

		order = self.client.order.create(data = {
			"amount": amount,
			"currency": "INR",
			"payment_capture": 1
		})

		order_id = order.get("id")
		if not order_id:
			frappe.throw("Could not create order")

		if not member.contact:
			frappe.throw("Member contact details missing")

		if not member.customer_id:
			frappe.throw("Member customer is missing")

		if not member.razorpay_token:
			frappe.throw("Razorpay token is missing")

		# Razorpay python does not have recurrig payments yet
		# use razorpay client to make requests
		url = "{}/payments/create/recurring".format(URL.BASE_URL)

		data = {
			"email": member.email_id or member.email,
			"contact": member.contact,
			"amount": amount,
			"currency": "INR",
			"order_id": order_id,
			"customer_id": member.customer_id,
			"token": member.get_password(fieldname="razorpay_token"),
			"recurring": 1,
			"notes": {
				"erpnext-name": member.name
			}
		}

		payment = make_post_request(
			url,
			auth=(self.controller.api_key, self.controller.get_password(fieldname="api_secret", raise_exception=False)),
			data=json.dumps(data),
			headers={
				"content-type": "application/json"
			}
		)

		return payment.get("razorpay_payment_id")
コード例 #15
0
def create_recurring_profile(token, payerid):
	try:
		custom_redirect_to = None
		updating = False
		data, params, url = get_paypal_and_transaction_details(token)

		addons = data.get("addons")
		subscription_details = data.get("subscription_details")

		if data.get('subscription_id'):
			if addons:
				updating = True
			manage_recurring_payment_profile_status(data['subscription_id'], 'Cancel', params, url)

		params.update({
			"METHOD": "CreateRecurringPaymentsProfile",
			"PAYERID": payerid,
			"TOKEN": token,
			"DESC": data.get("description"),
			"BILLINGPERIOD": subscription_details.get("billing_period"),
			"BILLINGFREQUENCY": subscription_details.get("billing_frequency"),
			"AMT": data.get("amount") if data.get("subscription_amount") == data.get("amount") else data.get("subscription_amount"),
			"CURRENCYCODE": data.get("currency").upper(),
			"INITAMT": data.get("upfront_amount")
		})

		status_changed_to = 'Completed' if data.get("starting_immediately") or updating else 'Verified'

		starts_at = get_datetime(subscription_details.get("start_date")) or frappe.utils.now_datetime()
		starts_at = starts_at.replace(tzinfo=pytz.timezone(frappe.utils.get_time_zone())).astimezone(pytz.utc)

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

		response = make_post_request(url, data=params)

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

			if data.get("reference_doctype") and data.get("reference_docname"):
				data['subscription_id'] = response.get("PROFILEID")[0]

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

			redirect_url = '/integrations/payment-success?doctype={0}&docname={1}'.format(data.get("reference_doctype"), data.get("reference_docname"))
		else:
			redirect_url = "/integrations/payment-failed"

		setup_redirect(data, redirect_url, custom_redirect_to)

	except Exception:
		frappe.log_error(frappe.get_traceback())
コード例 #16
0
    def make_request(self, request_type, url, headers=None, data=None):
        if request_type == 'post':
            res = make_post_request(url, headers=headers, data=data)
        else:
            res = make_get_request(url, headers=headers, data=data)

        self.log_request(url, headers, data, res)
        return res
コード例 #17
0
ファイル: paypal_settings.py プロジェクト: ESS-LLP/frappe
def create_recurring_profile(token, payerid):
	try:
		custom_redirect_to = None
		updating = False
		data, params, url = get_paypal_and_transaction_details(token)

		addons = data.get("addons")
		subscription_details = data.get("subscription_details")

		if data.get('subscription_id') and addons:
			updating = True
			manage_recurring_payment_profile_status(data['subscription_id'], 'Cancel', params, url)

		params.update({
			"METHOD": "CreateRecurringPaymentsProfile",
			"PAYERID": payerid,
			"TOKEN": token,
			"DESC": data.get("description"),
			"BILLINGPERIOD": subscription_details.get("billing_period"),
			"BILLINGFREQUENCY": subscription_details.get("billing_frequency"),
			"AMT": data.get("amount") if data.get("subscription_amount") == data.get("amount") else data.get("subscription_amount"),
			"CURRENCYCODE": data.get("currency").upper(),
			"INITAMT": data.get("upfront_amount")
		})

		status_changed_to = 'Completed' if data.get("starting_immediately") or updating else 'Verified'

		starts_at = get_datetime(subscription_details.get("start_date")) or frappe.utils.now_datetime()
		starts_at = starts_at.replace(tzinfo=pytz.timezone(frappe.utils.get_time_zone())).astimezone(pytz.utc)

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

		response = make_post_request(url, data=params)

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

			if data.get("reference_doctype") and data.get("reference_docname"):
				data['subscription_id'] = response.get("PROFILEID")[0]

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

			redirect_url = '/integrations/payment-success?doctype={0}&docname={1}'.format(data.get("reference_doctype"), data.get("reference_docname"))
		else:
			redirect_url = "/integrations/payment-failed"

		setup_redirect(data, redirect_url, custom_redirect_to)

	except Exception:
		frappe.log_error(frappe.get_traceback())
コード例 #18
0
ファイル: razorpay_settings.py プロジェクト: ESS-LLP/frappe
	def cancel_subscription(self, subscription_id):
		settings = self.get_settings({})

		try:
			resp = make_post_request("https://api.razorpay.com/v1/subscriptions/{0}/cancel"
				.format(subscription_id), auth=(settings.api_key,
					settings.api_secret))
		except Exception:
			frappe.log_error(frappe.get_traceback())
コード例 #19
0
	def cancel_subscription(self, subscription_id):
		settings = self.get_settings({})

		try:
			resp = make_post_request(settings.base_url + "/subscriptions/{0}/cancel"
				.format(subscription_id), auth=(settings.client_key,
					settings.server_key))
		except Exception:
			frappe.log_error(frappe.get_traceback())
コード例 #20
0
def confirm_payment(token):
	try:
		redirect = True
		status_changed_to, redirect_to = None, None

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

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

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

		params, url = doc.get_paypal_params_and_url()
		params.update({
			"METHOD": "DoExpressCheckoutPayment",
			"PAYERID": data.get("payerid"),
			"TOKEN": token,
			"PAYMENTREQUEST_0_PAYMENTACTION": "SALE",
			"PAYMENTREQUEST_0_AMT": data.get("amount"),
			"PAYMENTREQUEST_0_CURRENCYCODE": data.get("currency").upper()
		})

		response = make_post_request(url, data=params)

		if response.get("ACK")[0] == "Success":
			update_integration_request_status(token, {
				"transaction_id": response.get("PAYMENTINFO_0_TRANSACTIONID")[0],
				"correlation_id": response.get("CORRELATIONID")[0]
			}, "Completed")

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

				if custom_redirect_to:
					redirect_to = custom_redirect_to

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

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

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

	except Exception:
		frappe.log_error(frappe.get_traceback())
コード例 #21
0
ファイル: stripe_settings.py プロジェクト: britlog/frappe
	def create_charge_on_stripe(self):
		headers = {"Authorization":
			"Bearer {0}".format(self.get_password(fieldname="secret_key", raise_exception=False))}
		
		data = {
			"amount": cint(flt(self.data.amount)*100),
			"currency": self.data.currency,
			"source": self.data.stripe_token_id,
			"description": self.data.description
		}
		
		redirect_to = self.data.get('redirect_to') or None
		redirect_message = self.data.get('redirect_message') or None

		try:
			resp = make_post_request(url="https://api.stripe.com/v1/charges", headers=headers, data=data)
			
			if resp.get("captured") == True:
				self.integration_request.db_set('status', 'Completed', update_modified=False)
				self.flags.status_changed_to = "Completed"

			else:
				frappe.log_error(str(resp), 'Stripe Payment not completed')

		except:
			frappe.log_error(frappe.get_traceback())
			# failed
			pass

		status = frappe.flags.integration_request.status_code

		if self.flags.status_changed_to == "Completed":
			if self.data.reference_doctype and self.data.reference_docname:
				custom_redirect_to = None
				try:
					custom_redirect_to = frappe.get_doc(self.data.reference_doctype,
						self.data.reference_docname).run_method("on_payment_authorized", self.flags.status_changed_to)
				except Exception:
					frappe.log_error(frappe.get_traceback())

				if custom_redirect_to:
					redirect_to = custom_redirect_to

			redirect_url = 'payment-success'
		else:
			redirect_url = 'payment-failed'

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

		return {
			"redirect_to": redirect_url,
			"status": status
		}
コード例 #22
0
    def cancel_subscription(self, subscription_id):
        settings = self.get_settings({})

        try:
            resp = make_post_request(
                "https://api.razorpay.com/v1/subscriptions/{0}/cancel".format(
                    subscription_id),
                auth=(settings.api_key, settings.api_secret))
        except Exception:
            frappe.log_error(frappe.get_traceback())
コード例 #23
0
ファイル: paypal_settings.py プロジェクト: ESS-LLP/frappe
def manage_recurring_payment_profile_status(profile_id, action, args, url):
	args.update({
		"METHOD": "ManageRecurringPaymentsProfileStatus",
		"PROFILEID": profile_id,
		"ACTION": action
	})

	response = make_post_request(url, data=args)

	if response.get("ACK")[0] != "Success":
		frappe.throw(_("Failed while amending subscription"))
コード例 #24
0
def manage_recurring_payment_profile_status(profile_id, action, args, url):
    args.update({
        "METHOD": "ManageRecurringPaymentsProfileStatus",
        "PROFILEID": profile_id,
        "ACTION": action
    })

    response = make_post_request(url, data=args)

    if response.get("ACK")[0] != "Success":
        frappe.throw(_("Failed while amending subscription"))
コード例 #25
0
    def validate_paypal_credentails(self):
        params, url = self.get_paypal_params_and_url()
        params = urlencode(params)

        try:
            res = make_post_request(url=url, data=params.encode("utf-8"))

            if res["ACK"][0] == "Failure":
                raise Exception

        except Exception:
            frappe.throw(_("Invalid payment gateway credentials"))
コード例 #26
0
def confirm_payment(token):
	try:
		redirect = True
		status_changed_to, redirect_to = None, None

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

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

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

		params, url = doc.get_paypal_params_and_url()
		params.update({
			"METHOD": "DoExpressCheckoutPayment",
			"PAYERID": data.get("payerid"),
			"TOKEN": token,
			"PAYMENTREQUEST_0_PAYMENTACTION": "SALE",
			"PAYMENTREQUEST_0_AMT": data.get("amount"),
			"PAYMENTREQUEST_0_CURRENCYCODE": data.get("currency").upper()
		})

		response = make_post_request(url, data=params)

		if response.get("ACK")[0] == "Success":
			update_integration_request_status(token, {
				"transaction_id": response.get("PAYMENTINFO_0_TRANSACTIONID")[0],
				"correlation_id": response.get("CORRELATIONID")[0]
			}, "Completed")

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

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

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

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

	except Exception:
		frappe.log_error(frappe.get_traceback())
コード例 #27
0
	def validate_paypal_credentails(self):
		params, url = self.get_paypal_params_and_url()
		params = urlencode(params)

		try:
			res = make_post_request(url=url, data=params.encode("utf-8"))

			if res["ACK"][0] == "Failure":
				raise Exception

		except Exception:
			frappe.throw(_("Invalid payment gateway credentials"))
コード例 #28
0
def generate_oauth2_access_token_from_oauth1_token(dropbox_settings=None):
	if not dropbox_settings.get("access_key") or not dropbox_settings.get("access_secret"):
		return {}

	url = "https://api.dropboxapi.com/2/auth/token/from_oauth1"
	headers = {"Content-Type": "application/json"}
	auth = (dropbox_settings["app_key"], dropbox_settings["app_secret"])
	data = {
		"oauth1_token": dropbox_settings["access_key"],
		"oauth1_token_secret": dropbox_settings["access_secret"]
	}

	return make_post_request(url, auth=auth, headers=headers, data=json.dumps(data))
コード例 #29
0
def get_redirect_url():
	url = "{0}/api/method/dropbox_erpnext_broker.www.setup_dropbox.get_authotize_url".format(frappe.conf.dropbox_broker_site)

	try:
		response = make_post_request(url, data={"site": get_url()})
		if response.get("message"):
			return response["message"]

	except Exception as e:
		frappe.log_error()
		frappe.throw(
			_("Something went wrong while generating dropbox access token. Please check error log for more details.")
		)
コード例 #30
0
ファイル: dropbox_settings.py プロジェクト: triptisha/frappe
def generate_oauth2_access_token_from_oauth1_token(dropbox_settings=None):
	if not dropbox_settings.get("access_key") or not dropbox_settings.get("access_secret"):
		return {}

	url = "https://api.dropboxapi.com/2/auth/token/from_oauth1"
	headers = {"Content-Type": "application/json"}
	auth = (dropbox_settings["app_key"], dropbox_settings["app_secret"])
	data = {
		"oauth1_token": dropbox_settings["access_key"],
		"oauth1_token_secret": dropbox_settings["access_secret"]
	}

	return make_post_request(url, auth=auth, headers=headers, data=json.dumps(data))
コード例 #31
0
ファイル: dropbox_settings.py プロジェクト: triptisha/frappe
def get_redirect_url():
	url = "{0}/api/method/dropbox_erpnext_broker.www.setup_dropbox.get_authotize_url".format(frappe.conf.dropbox_broker_site)

	try:
		response = make_post_request(url, data={"site": get_url()})
		if response.get("message"):
			return response["message"]

	except Exception:
		frappe.log_error()
		frappe.throw(
			_("Something went wrong while generating dropbox access token. Please check error log for more details.")
		)
コード例 #32
0
def manage_recurring_payment_profile_status(profile_id, action, args, url):
	args.update({
		"METHOD": "ManageRecurringPaymentsProfileStatus",
		"PROFILEID": profile_id,
		"ACTION": action
	})

	response = make_post_request(url, data=args)

	# error code 11556 indicates profile is not in active state(or already cancelled)
	# thus could not cancel the subscription.
	# thus raise an exception only if the error code is not equal to 11556

	if response.get("ACK")[0] != "Success" and response.get("L_ERRORCODE0", [])[0] != '11556':
		frappe.throw(_("Failed while amending subscription"))
コード例 #33
0
	def onload(self):
		if self.contributed_translation_doctype_name:
			data = {"data": json.dumps({
				"doc_name": self.contributed_translation_doctype_name
			})}
			try:
				response = make_post_request(url=frappe.get_hooks("translation_contribution_status")[0], data=data)
			except Exception:
				frappe.msgprint("Something went wrong. Please check error log for more details")
			if response.get("message").get("message") == "Contributed Translation has been deleted":
				self.status = "Deleted"
				self.contributed_translation_doctype_name = ""
				self.save()
			else:
				self.status = response.get("message").get("status")
				self.save()
コード例 #34
0
def update_access_token_to_site(access_token, state):
	close = '<p class="text-muted">' + _('Please close this window') + '</p>'
	token_details = frappe.get_doc("Site Dropbox Token", state)
	
	url = "{0}/api/method/frappe.integrations.doctype.dropbox_settings.dropbox_settings.set_dropbox_access_token".format(token_details.site_name)

	try:
		res = make_post_request(url, data={"access_token": access_token})
	except Exception as e:
		frappe.respond_as_web_page(_("Dropbox Setup"),
			_("Something went wrong while creating dropbox access token. Please try again!!") + close,
			indicator_color='red')

	frappe.respond_as_web_page(_("Dropbox Setup"),
		_("Dropbox access is approved!") + close,
		indicator_color='green')
コード例 #35
0
def contribute_translation(language, contributor, source_name, target_name, doc_name):
	data = {"data": json.dumps({
		"language": language,
		"contributor": contributor,
		"source_name": source_name,
		"target_name": target_name,
		"posting_date": frappe.utils.nowdate()
	})}
	try:
		response = make_post_request(url=frappe.get_hooks("translation_contribution_url")[0], data=data)
	except Exception:
		frappe.msgprint("Something went wrong while contributing translation. Please check error log for more details")
	if response.get("message").get("message") == "Already exists":
		frappe.msgprint("Translation already exists")
	elif response.get("message").get("message") == "Added to contribution list":
		frappe.set_value("Translation", doc_name, "contributed_translation_doctype_name", response.get("message").get("doc_name"))
		frappe.msgprint("Translation successfully contributed")
コード例 #36
0
	def execute_set_express_checkout(self, amount, currency):
		params, url = self.get_paypal_params_and_url()
		params.update({
			"METHOD": "SetExpressCheckout",
			"PAYMENTREQUEST_0_PAYMENTACTION": "SALE",
			"PAYMENTREQUEST_0_AMT": amount,
			"PAYMENTREQUEST_0_CURRENCYCODE": currency.upper(),
			"returnUrl": get_url("/api/method/frappe.integrations.doctype.paypal_settings.paypal_settings.get_express_checkout_details"),
			"cancelUrl": get_url("/payment-cancel")
		})

		params = urlencode(params)

		response = make_post_request(url, data=params.encode("utf-8"))
		if response.get("ACK")[0] != "Success":
			frappe.throw(_("Looks like something is wrong with this site's Paypal configuration."))

		return response
コード例 #37
0
ファイル: hpk.py プロジェクト: nabilshuja/renovation_core
def get_huawei_auth_token(config):
    if not config or not config.get('app_id') or not config.get(
            'client_id') or not config.get('client_secret'):
        frappe.log_error(title="Huawei Push Kit Error",
                         message="Message: {}".format(
                             frappe._("Missing secret keys in config")))
        return
    cache_auth_token = check_redis_cache_for_huawei_auth_token()
    if cache_auth_token:
        return cache_auth_token
    url = "https://oauth-login.cloud.huawei.com/oauth2/v3/token"
    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "Accept": "application/json"
    }
    payload = {
        "grant_type": "client_credentials",
        "client_id": config.get("client_id"),
        "client_secret": config.get("client_secret")
    }
    access_token = ''
    try:
        response = make_post_request(url, data=payload, headers=headers)
        access_token = "{} {}".format(response.get('token_type'),
                                      response.get('access_token'))
        set_redis_cache_huawei_auth_token(access_token,
                                          response.get('expires_in'))
    except Exception as exc:
        status_code = frappe.flags.integration_request.status_code
        error = frappe.parse_json(frappe.flags.integration_request.json())
        huawei_error_code = error.get('error')
        sub_error = error.get('sub_error')
        error_description = error.get('error_description')
        print(
            "{}\nStatus Code: {}\nHuawei Error: {}\nSub Error: {}\nError Description: {}"
            .format(str(exc), status_code, huawei_error_code, sub_error,
                    error_description))
        frappe.log_error(
            title="Huawei Push Kit Error",
            message=
            "{}\n{}\nStatus Code: {}\nHuawei Error: {}\nSub Error: {}\nError Description: {}"
            .format("Get Authorization token error.", str(exc), status_code,
                    huawei_error_code, sub_error, error_description))
    return access_token
コード例 #38
0
    def setup_subscription(self, settings, **kwargs):
        start_date = (get_timestamp(
            kwargs.get("subscription_details").get("start_date"))
                      if kwargs.get("subscription_details").get("start_date")
                      else None)

        subscription_details = {
            "plan_id":
            kwargs.get("subscription_details").get("plan_id"),
            "total_count":
            kwargs.get("subscription_details").get("billing_frequency"),
            "customer_notify":
            kwargs.get("subscription_details").get("customer_notify"),
        }

        if start_date:
            subscription_details["start_at"] = cint(start_date)

        if kwargs.get("addons"):
            convert_rupee_to_paisa(**kwargs)
            subscription_details.update({"addons": kwargs.get("addons")})

        try:
            resp = make_post_request(
                "https://api.razorpay.com/v1/subscriptions",
                auth=(settings.api_key, settings.api_secret),
                data=json.dumps(subscription_details),
                headers={"content-type": "application/json"},
            )

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

        except:
            frappe.log_error(frappe.get_traceback())
            # failed
            pass
コード例 #39
0
ファイル: paypal_settings.py プロジェクト: ESS-LLP/frappe
def validate_ipn_request(data):
	def _throw():
		frappe.throw(_("In Valid Request"), exc=frappe.InvalidStatusError)

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

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

	params.update({
		"METHOD": "GetRecurringPaymentsProfileDetails",
		"PROFILEID": data.get("recurring_payment_id")
	})

	params = urlencode(params)
	res = make_post_request(url=url, data=params.encode("utf-8"))

	if res['ACK'][0] != 'Success':
		_throw()
コード例 #40
0
def validate_ipn_request(data):
	def _throw():
		frappe.throw(_("In Valid Request"), exc=frappe.InvalidStatusError)

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

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

	params.update({
		"METHOD": "GetRecurringPaymentsProfileDetails",
		"PROFILEID": data.get("recurring_payment_id")
	})

	params = urlencode(params)
	res = make_post_request(url=url, data=params.encode("utf-8"))

	if res['ACK'][0] != 'Success':
		_throw()
コード例 #41
0
	def setup_subscription(self, settings, **kwargs):
		start_date = get_timestamp(kwargs.get('subscription_details').get("start_date")) \
			if kwargs.get('subscription_details').get("start_date") else None

		subscription_details = {
			"plan_id": kwargs.get('subscription_details').get("plan_id"),
			"total_count": kwargs.get('subscription_details').get("billing_frequency"),
			"customer_notify": kwargs.get('subscription_details').get("customer_notify")
		}

		if start_date:
			subscription_details['start_at'] = cint(start_date)

		if kwargs.get('addons'):
			convert_rupee_to_paisa(**kwargs)
			subscription_details.update({
				"addons": kwargs.get('addons')
			})

		try:
			resp = make_post_request(
				"https://api.midtrans.com/v1/subscriptions",
				auth=(settings.client_key, settings.server_key),
				data=json.dumps(subscription_details),
				headers={
					"content-type": "application/json"
				}
			)

			if resp.get('status') == 'created':
				kwargs['subscription_id'] = resp.get('id')
				frappe.flags.status = 'created'
				return kwargs
			else:
				frappe.log_error(str(resp), 'midtrans Failed while creating subscription')

		except:
			frappe.log_error(frappe.get_traceback())
			# failed
			pass
コード例 #42
0
ファイル: paypal_settings.py プロジェクト: ESS-LLP/frappe
	def execute_set_express_checkout(self, **kwargs):
		params, url = self.get_paypal_params_and_url()

		params.update({
			"METHOD": "SetExpressCheckout",
			"returnUrl": get_url("{0}.get_express_checkout_details".format(api_path)),
			"cancelUrl": get_url("/payment-cancel"),
			"PAYMENTREQUEST_0_PAYMENTACTION": "SALE",
			"PAYMENTREQUEST_0_AMT": kwargs['amount'],
			"PAYMENTREQUEST_0_CURRENCYCODE": kwargs['currency'].upper()
		})

		if kwargs.get('subscription_details'):
			self.configure_recurring_payments(params, kwargs)

		params = urlencode(params)
		response = make_post_request(url, data=params.encode("utf-8"))

		if response.get("ACK")[0] != "Success":
			frappe.throw(_("Looks like something is wrong with this site's Paypal configuration."))

		return response
コード例 #43
0
ファイル: razorpay_settings.py プロジェクト: ESS-LLP/frappe
	def setup_subscription(self, settings, **kwargs):
		start_date = get_timestamp(kwargs.get('subscription_details').get("start_date")) \
			if kwargs.get('subscription_details').get("start_date") else None

		subscription_details = {
			"plan_id": kwargs.get('subscription_details').get("plan_id"),
			"start_at": cint(start_date),
			"total_count": kwargs.get('subscription_details').get("billing_frequency"),
			"customer_notify": kwargs.get('subscription_details').get("customer_notify")
		}

		if kwargs.get('addons'):
			convert_rupee_to_paisa(**kwargs)
			subscription_details.update({
				"addons": kwargs.get('addons')
			})

		try:
			resp = make_post_request(
				"https://api.razorpay.com/v1/subscriptions",
				auth=(settings.api_key, settings.api_secret),
				data=json.dumps(subscription_details),
				headers={
					"content-type": "application/json"
				}
			)

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

		except:
			frappe.log_error(frappe.get_traceback())
			# failed
			pass
コード例 #44
0
def make_checkout(data):

    data = json.loads(data)

    #get Moka Setting
    moka = frappe.get_doc("Moka Settings")

    dealercode = moka.moka_dealercode
    username = moka.moka_username
    password = moka.get_password(fieldname="moka_password",
                                 raise_exception=False)

    if moka.moka_sandbox == 1:
        moka_url = "https://service.testmoka.com"
    else:
        moka_url = "https://service.moka.com"

    if moka.moka_tdmode == 1:
        moka_url = moka_url + "/PaymentDealer/DoDirectPaymentThreeD"
    else:
        moka_url = moka_url + "/PaymentDealer/DoDirectPayment"

    #Convert Curreny ERPNext to MOKA
    if data["currency"] == 'TRY':
        currency = "TL"
    else:
        currency = data['currency']

    token = data['token']
    name = data['name']
    cvc = data['cvc']
    amount = data['amount']
    number = replaceSpace(data['number'])

    expiry = data['expiry']
    expiry = expiry.split('/')
    expiryMM = replaceSpace(expiry[0])
    expiryYY = replaceSpace(expiry[1])

    InstallmentNumber = 0
    OtherTrxCode = data['OtherTrxCode'] + "-" + str(cint(time.time()))
    SubMerchantName = ""
    RedirectUrl = get_url( \
      "/api/method/moka_integration.moka_integration.doctype.moka_settings.moka_settings.confirm_payment?token={0}".format(token))
    checkkey = hashlib.sha256(
        dealercode.encode("utf-8") + b"MK" + username.encode("utf-8") + b"PD" +
        password.encode("utf-8")).hexdigest()
    ClientIP = frappe.local.request_ip or '127.0.0.1'

    veri = {
        "PaymentDealerAuthentication": {
            "DealerCode": dealercode,
            "Username": username,
            "Password": password,
            "CheckKey": checkkey
        },
        "PaymentDealerRequest": {
            'CardHolderFullName': name,
            'CardNumber': number,
            'ExpMonth': expiryMM,
            'ExpYear': '20' + expiryYY,
            'CvcNumber': cvc,
            'Amount': amount,
            'Currency': currency,
            'InstallmentNumber': InstallmentNumber,
            'ClientIP': ClientIP,
            'RedirectUrl': RedirectUrl,
            "RedirectType": 0,
            'OtherTrxCode': OtherTrxCode,
            'SubMerchantName': SubMerchantName
        }
    }

    headers = {"Content-Type": "application/json"}

    try:
        response = make_post_request(moka_url,
                                     headers=headers,
                                     data=json.dumps(veri))
        return response

    except Exception:
        frappe.log_error()
コード例 #45
0
    def create_charge_on_stripe(self):
        headers = {
            "Authorization":
            "Bearer {0}".format(
                self.get_password(fieldname="secret_key",
                                  raise_exception=False))
        }

        data = {
            "amount": cint(self.data.amount) * 100,
            "currency": self.data.currency,
            "source": self.data.stripe_token_id,
            "description": self.data.description
        }

        redirect_to = self.data.get('redirect_to') or None
        redirect_message = self.data.get('redirect_message') or None

        try:
            resp = make_post_request(url="https://api.stripe.com/v1/charges",
                                     headers=headers,
                                     data=data)

            if resp.get("captured") == True:
                self.integration_request.db_set('status',
                                                'Completed',
                                                update_modified=False)
                self.flags.status_changed_to = "Completed"

            else:
                frappe.log_error(str(resp), 'Stripe Payment not completed')

        except:
            frappe.log_error(frappe.get_traceback())
            # failed
            pass

        status = frappe.flags.integration_request.status_code

        if self.flags.status_changed_to == "Completed":
            if self.data.reference_doctype and self.data.reference_docname:
                custom_redirect_to = None
                try:
                    custom_redirect_to = frappe.get_doc(
                        self.data.reference_doctype,
                        self.data.reference_docname).run_method(
                            "on_payment_authorized",
                            self.flags.status_changed_to)
                except Exception:
                    frappe.log_error(frappe.get_traceback())

                if custom_redirect_to:
                    redirect_to = custom_redirect_to

            redirect_url = 'payment-success'
        else:
            redirect_url = 'payment-failed'

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

        return {"redirect_to": redirect_url, "status": status}
コード例 #46
0
ファイル: hpk.py プロジェクト: nabilshuja/renovation_core
def send_huawei_notifications(tokens=None,
                              topic=None,
                              title=None,
                              body=None,
                              data=None,
                              custom_android_configuration=None):
    config = frappe.get_site_config().get("huawei_push_kit_config")
    if not config or not config.get('app_id') or not config.get(
            'client_id') or not config.get('client_secret'):
        frappe.log_error(title="Huawei Push Kit Error",
                         message="Message: {}".format(
                             frappe._("Missing secret keys in config")))
        return
    authorization_token = get_huawei_auth_token(config)
    if not authorization_token:
        frappe.log_error(title="Huawei Push Kit Error",
                         message="Message: {}".format(
                             frappe._("Authorization token missing.")))
        return
    url = "https://push-api.cloud.huawei.com/v1/{}/messages:send".format(
        config.get('app_id'))
    # message format
    # {
    # data:str ,
    # notification: { 'title' , 'body' , 'image' },
    # android: check docs..,
    # apns: check docs..,
    # webpush: check docs..,
    # token: [] ,
    # topic: [] ,
    # condition : '' check docs...
    # }
    message = {
        "data": frappe.as_json(data) if data else {},
        "notification": {
            "title": title,
            "body": body
        },
        "android": {
            "notification": {
                "click_action": {
                    "type": 3
                }
            }
        }
    }
    if custom_android_configuration and isinstance(
            custom_android_configuration, dict):
        message['android'].update(custom_android_configuration)
    response = None
    headers = {
        "Content-Type": "application/json",
        "Authorization": authorization_token
    }
    if tokens and len(tokens):
        message.update({"token": tokens})
        try:
            payload = frappe._dict(validate_only=False, message=message)
            response = make_post_request(url,
                                         data=frappe.as_json(payload),
                                         headers=headers)
            huawei_push_kit_error_handler(tokens=tokens,
                                          topic=topic,
                                          title=title,
                                          body=body,
                                          data=data,
                                          recipient_count=len(tokens),
                                          request_params=message)
        except Exception as exc:
            huawei_push_kit_error_handler(tokens=tokens,
                                          topic=topic,
                                          title=title,
                                          body=body,
                                          data=data,
                                          exc=exc,
                                          recipient_count=len(tokens),
                                          request_params=message)
        print("Sending to tokens: {}".format(tokens))
    elif topic:
        message.update({"topic": topic})
        try:
            payload = frappe._dict(validate_only=False, message=message)
            response = make_post_request(url,
                                         data=frappe.as_json(payload),
                                         headers=headers)
            huawei_push_kit_error_handler(tokens=tokens,
                                          topic=topic,
                                          title=title,
                                          body=body,
                                          data=data,
                                          request_params=message)
        except Exception as exc:
            huawei_push_kit_error_handler(tokens=tokens,
                                          topic=topic,
                                          title=title,
                                          body=body,
                                          data=data,
                                          exc=exc,
                                          request_params=message)
        print("Sent TOPIC {} Msg: {}".format(topic, response))
    return response