@@ -68,7 +68,13 @@ class PayPalSettings(IntegrationService):
supported_currencies = ["AUD", "BRL", "CAD", "CZK", "DKK", "EUR", "HKD", "HUF", "ILS", "JPY", "MYR", "MXN",
"TWD", "NZD", "NOK", "PHP", "PLN", "GBP", "RUB", "SGD", "SEK", "CHF", "THB", "TRY", "USD"]
def __setup__(self):
setattr(self, "use_sandbox", 0)
if hasattr(self, "token"):
data = json.loads(frappe.db.get_value("Integration Request", self.token, "data"))
setattr(self, "use_sandbox", frappe._dict(data).use_sandbox or 0)
def validate(self):
if not self.flags.ignore_mandatory:
self.validate_paypal_credentails()
@@ -94,7 +100,14 @@ class PayPalSettings(IntegrationService):
"METHOD": "GetPalDetails"
}
api_url = "https://api-3t.sandbox.paypal.com/nvp" if self.paypal_sandbox else "https://api-3t.paypal.com/nvp"
if hasattr(self, "use_sandbox") and self.use_sandbox:
params.update({
"USER": frappe.conf.sandbox_api_username,
"PWD": frappe.conf.sandbox_api_password,
"SIGNATURE": frappe.conf.sandbox_signature
})
api_url = "https://api-3t.sandbox.paypal.com/nvp" if (self.paypal_sandbox or self.use_sandbox) else "https://api-3t.paypal.com/nvp"
return params, api_url
@@ -112,9 +125,11 @@ class PayPalSettings(IntegrationService):
frappe.throw(_("Invalid payment gateway credentials"))
def get_payment_url(self, **kwargs):
setattr(self, "use_sandbox", kwargs.get("use_sandbox", 0))
response = self.execute_set_express_checkout(kwargs["amount"], kwargs["currency"])
if self.paypal_sandbox:
if self.paypal_sandbox or self.use_sandbox :
return_url = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={0}"
else:
return_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={0}"
@@ -186,78 +201,87 @@ def get_service_details():
@frappe.whitelist(allow_guest=True, xss_safe=True)
def get_express_checkout_details(token):
doc = frappe.get_doc("PayPal Settings")
params, url = doc.get_paypal_params_and_url()
params.update({
"METHOD": "GetExpressCheckoutDetails",
"TOKEN": token
})
try:
doc = frappe.get_doc({"doctype": "PayPal Settings", "token": token})
params, url = doc.get_paypal_params_and_url()
params.update({
"METHOD": "GetExpressCheckoutDetails",
"TOKEN": token
})
response = doc.post_request(url, data=params)
response = doc.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]),
success=False,
http_status_code=frappe.ValidationError.http_status_code)
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]),
success=False,
http_status_code=frappe.ValidationError.http_status_code)
return
return
update_integration_request_status(token, {
"payerid": response.get("PAYERID")[0],
"payer_email": response.get("EMAIL")[0]
}, "Authorized")
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))
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())
@frappe.whitelist(allow_guest=True, xss_safe=True)
def confirm_payment(token):
redirect = True
status_changed_to, redirect_to = None, None
doc = frappe.get_doc("PayPal Settings")
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 = doc.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")
try:
redirect = True
status_changed_to, redirect_to = None, None
doc = frappe.get_doc({"doctype": "PayPal Settings", "token": token})
integration_request = frappe.get_doc("Integration Request", token)
data = json.loads(integration_request.data)
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")
redirect_to = data.get('redirect_to') or None
redirect_message = data.get('redirect_message') or None
if not redirect_url:
redirect_url = '/integrations/payment-success'
else:
redirect_url = "/integrations/payment-failed"
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()
})
if redirect_to:
redirect_url += '?' + urllib.urlencode({'redirect_to': redirect_to})
if redirect_message:
redirect_url += '&' + urllib.urlencode({'redirect_message': redirect_message})
response = doc.post_request(url, data=params)
# 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_to)
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 update_integration_request_status(token, data, status, error=False):
frappe.get_doc("Integration Request", token).update_status(data, status)