瀏覽代碼

[fix] paypal sandboxing to test dummy payments (#2281)

* [fix] paypal sandboxing to test dummy payments

* [fix] sandbox testing for razorpay
pull/2/head
Saurabh 8 年之前
committed by Rushabh Mehta
父節點
當前提交
a388c2597d
共有 3 個檔案被更改,包括 111 行新增69 行删除
  1. +87
    -63
      payments/payment_gateways/doctype/paypal_settings/paypal_settings.py
  2. +15
    -5
      payments/payment_gateways/doctype/razorpay_settings/razorpay_settings.py
  3. +9
    -1
      payments/templates/pages/razorpay_checkout.py

+ 87
- 63
payments/payment_gateways/doctype/paypal_settings/paypal_settings.py 查看文件

@@ -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)


+ 15
- 5
payments/payment_gateways/doctype/razorpay_settings/razorpay_settings.py 查看文件

@@ -117,8 +117,9 @@ class RazorpaySettings(IntegrationService):
The money is deducted from the customer’s account, but will not be transferred to the merchant’s account
until it is explicitly captured by merchant.
"""
settings = self.get_settings()
data = json.loads(self.integration_request.data)

settings = self.get_settings(data)
redirect_to = data.get('notes', {}).get('redirect_to') or None
redirect_message = data.get('notes', {}).get('redirect_message') or None

@@ -167,12 +168,20 @@ class RazorpaySettings(IntegrationService):
"status": status
}

def get_settings(self):
return frappe._dict({
def get_settings(self, data):
settings = frappe._dict({
"api_key": self.api_key,
"api_secret": self.get_password(fieldname="api_secret", raise_exception=False)
})

if data.get('notes', {}).get('use_sandbox'):
settings.update({
"api_key": frappe.conf.sandbox_api_key,
"api_secret": frappe.conf.sandbox_api_secret,
})

return settings

def capture_payment(is_sandbox=False, sanbox_response=None):
"""
Verifies the purchase as complete by the merchant.
@@ -190,8 +199,10 @@ def capture_payment(is_sandbox=False, sanbox_response=None):
resp = sanbox_response
else:
data = json.loads(doc.data)
settings = controller.get_settings(data)

resp = controller.post_request("https://api.razorpay.com/v1/payments/{0}/capture".format(data.get("razorpay_payment_id")),
auth=(controller.api_key, controller.get_password("api_secret")), data={"amount": data.get("amount")})
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")
@@ -212,7 +223,6 @@ def get_checkout_url(**kwargs):
success=False,
http_status_code=frappe.ValidationError.http_status_code)


@frappe.whitelist()
def get_service_details():
return """


+ 9
- 1
payments/templates/pages/razorpay_checkout.py 查看文件

@@ -14,7 +14,7 @@ expected_keys = ('amount', 'title', 'description', 'reference_doctype', 'referen

def get_context(context):
context.no_cache = 1
context.api_key = frappe.db.get_value("Razorpay Settings", None, "api_key")
context.api_key = get_api_key()

# all these keys exist in form_dict
if not (set(expected_keys) - set(frappe.form_dict.keys())):
@@ -28,6 +28,14 @@ def get_context(context):
frappe.local.flags.redirect_location = frappe.local.response.location
raise frappe.Redirect

def get_api_key():
api_key = frappe.db.get_value("Razorpay Settings", None, "api_key")

if frappe.form_dict.get("use_sandbox"):
api_key = frappe.conf.sandbox_api_key

return api_key

@frappe.whitelist(allow_guest=True)
def make_payment(razorpay_payment_id, options, reference_doctype, reference_docname):
data = {}


Loading…
取消
儲存