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())
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"))
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
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))
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"))
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
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())
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
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())
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))
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) '''
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())
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
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")
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())
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
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())
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())
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())
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())
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 }
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())
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"))
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"))
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"))
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())
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"))
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))
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.") )
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))
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.") )
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"))
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()
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')
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")
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
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
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
def validate_ipn_request(data): def _throw(): frappe.throw(_("In Valid Request"), exc=frappe.InvalidStatusError) if not data.get("recurring_payment_id"): _throw() doc = frappe.get_doc("PayPal Settings") params, url = doc.get_paypal_params_and_url() params.update({ "METHOD": "GetRecurringPaymentsProfileDetails", "PROFILEID": data.get("recurring_payment_id") }) params = urlencode(params) res = make_post_request(url=url, data=params.encode("utf-8")) if res['ACK'][0] != 'Success': _throw()
def validate_ipn_request(data): def _throw(): frappe.throw(_("In Valid Request"), exc=frappe.InvalidStatusError) if not data.get("recurring_payment_id"): _throw() doc = frappe.get_doc("PayPal Settings") params, url = doc.get_paypal_params_and_url() params.update({ "METHOD": "GetRecurringPaymentsProfileDetails", "PROFILEID": data.get("recurring_payment_id") }) params = urlencode(params) res = make_post_request(url=url, data=params.encode("utf-8")) if res['ACK'][0] != 'Success': _throw()
def 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
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
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
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()
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}
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