Changed the opt in for auto pay to be a check box on thecustom form. Improves work flow and is more professional. Added this as checkbox under the zip code entry field. Did no testing on the logic yet.
This commit is contained in:
@@ -118,8 +118,10 @@ def call_payment_api(payload):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def run_token_payment(invoice, token, cardholder_name=None, billing_zip=None):
|
||||
def run_token_payment(invoice, token, cardholder_name=None, billing_zip=None, save_autopay=0):
|
||||
|
||||
inv = frappe.get_doc("Sales Invoice", invoice)
|
||||
customer = frappe.get_doc("Customer", inv.customer)
|
||||
|
||||
url = "https://secure.nmi.com/api/transact.php"
|
||||
|
||||
@@ -138,12 +140,13 @@ def run_token_payment(invoice, token, cardholder_name=None, billing_zip=None):
|
||||
or ""
|
||||
)
|
||||
|
||||
# Name Split
|
||||
# Name split
|
||||
parts = customer_name.strip().split(" ", 1)
|
||||
first_name = parts[0]
|
||||
last_name = parts[1] if len(parts) > 1 else "."
|
||||
|
||||
data = {
|
||||
|
||||
sale_data = {
|
||||
"security_key": frappe.conf.get("nmi_security_key"),
|
||||
"type": "sale",
|
||||
"payment_token": token,
|
||||
@@ -153,72 +156,110 @@ def run_token_payment(invoice, token, cardholder_name=None, billing_zip=None):
|
||||
"first_name": first_name,
|
||||
"last_name": last_name,
|
||||
"email": inv.contact_email or "",
|
||||
|
||||
"zip": billing_zip,
|
||||
}
|
||||
|
||||
response = requests.post(url, data=data)
|
||||
result = urllib.parse.parse_qs(response.text)
|
||||
sale_response = requests.post(url, data=sale_data)
|
||||
sale_result = urllib.parse.parse_qs(sale_response.text)
|
||||
|
||||
frappe.logger("payments").info(f"NMI RESPONSE: {response.text}")
|
||||
frappe.logger("payments").info(f"NMI SALE RESPONSE: {sale_response.text}")
|
||||
|
||||
success = result.get("response", ["0"])[0]
|
||||
transaction_id = result.get("transactionid", [""])[0]
|
||||
success = sale_result.get("response", ["0"])[0]
|
||||
transaction_id = sale_result.get("transactionid", [""])[0]
|
||||
|
||||
if success == "1":
|
||||
create_payment_entry(
|
||||
invoice=invoice,
|
||||
amount=inv.outstanding_amount,
|
||||
transaction_id=transaction_id,
|
||||
mode_of_payment="Credit Card"
|
||||
)
|
||||
if success != "1":
|
||||
return {
|
||||
"success": False,
|
||||
"error": sale_result.get("responsetext", ["Error"])[0]
|
||||
}
|
||||
|
||||
return {"success": True}
|
||||
# Create payment entry
|
||||
create_payment_entry(
|
||||
invoice=invoice,
|
||||
amount=inv.outstanding_amount,
|
||||
transaction_id=transaction_id,
|
||||
mode_of_payment="Credit Card"
|
||||
)
|
||||
|
||||
vault_id = None
|
||||
|
||||
# Vault (if checked)
|
||||
if cint(save_autopay):
|
||||
vault_data = {
|
||||
"security_key": frappe.conf.get("nmi_security_key"),
|
||||
"type": "add_customer",
|
||||
"payment_token": token,
|
||||
|
||||
"first_name": first_name,
|
||||
"last_name": last_name,
|
||||
"zip": billing_zip,
|
||||
|
||||
"customer_vault": "add_customer"
|
||||
}
|
||||
|
||||
try:
|
||||
vault_response = requests.post(url, data=vault_data, timeout=30)
|
||||
vault_result = urllib.parse.parse_qs(vault_response.text)
|
||||
|
||||
frappe.logger("payments").info(f"NMI VAULT RESPONSE: {vault_response.text}")
|
||||
|
||||
vault_success = vault_result.get("response", ["0"])[0]
|
||||
vault_id = vault_result.get("customer_vault_id", [""])[0]
|
||||
|
||||
if vault_success == "1" and vault_id:
|
||||
customer.custom_auto_pay_id = vault_id
|
||||
customer.custom_auto_pay_status = 1
|
||||
customer.save(ignore_permissions=True)
|
||||
|
||||
except Exception:
|
||||
frappe.log_error(frappe.get_traceback(), "Vault Creation Failed")
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"error": result.get("responsetext", ["Error"])[0]
|
||||
"success": True,
|
||||
"vault_id": vault_id
|
||||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
def save_to_autopay(customer, token, cardholder_name=None, billing_zip=None):
|
||||
import requests
|
||||
import urllib.parse
|
||||
|
||||
inv_customer = frappe.get_doc("Customer", customer)
|
||||
cust = frappe.get_doc("Customer", customer)
|
||||
|
||||
# Fallback logic
|
||||
customer_name = (
|
||||
# Priority: Form input → Customer record → fallback
|
||||
final_name = (
|
||||
cardholder_name
|
||||
or inv_customer.customer_name
|
||||
or cust.customer_name
|
||||
or cust.name
|
||||
or "Customer"
|
||||
).strip()
|
||||
|
||||
billing_zip = (
|
||||
# ZIP fallback chain
|
||||
final_zip = (
|
||||
billing_zip
|
||||
or inv_customer.get("billing_zip")
|
||||
or inv_customer.get("pincode")
|
||||
or cust.get("billing_zip")
|
||||
or cust.get("pincode")
|
||||
or ""
|
||||
)
|
||||
|
||||
# name split
|
||||
if " " in customer_name:
|
||||
first_name, last_name = customer_name.split(" ", 1)
|
||||
else:
|
||||
first_name = customer_name
|
||||
last_name = "."
|
||||
# Optional but recommended fields
|
||||
email = cust.get("email_id") or ""
|
||||
|
||||
# Safe name split
|
||||
parts = final_name.split(" ", 1)
|
||||
first_name = parts[0]
|
||||
last_name = parts[1] if len(parts) > 1 else "."
|
||||
|
||||
data = {
|
||||
"security_key": frappe.conf.get("nmi_security_key"),
|
||||
"type": "add_customer",
|
||||
|
||||
"payment_token": token,
|
||||
"customer_vault": "add_customer",
|
||||
|
||||
"first_name": first_name,
|
||||
"last_name": last_name,
|
||||
"email": email,
|
||||
|
||||
"zip": billing_zip,
|
||||
|
||||
"customer_vault": "add_customer"
|
||||
"zip": final_zip,
|
||||
}
|
||||
|
||||
try:
|
||||
@@ -230,7 +271,10 @@ def save_to_autopay(customer, token, cardholder_name=None, billing_zip=None):
|
||||
|
||||
result = urllib.parse.parse_qs(response.text)
|
||||
|
||||
frappe.logger("payments").info(f"NMI VAULT RESPONSE: {response.text}")
|
||||
frappe.logger("payments").info({
|
||||
"vault_request": data,
|
||||
"vault_response": response.text
|
||||
})
|
||||
|
||||
success = result.get("response", ["0"])[0]
|
||||
vault_id = result.get("customer_vault_id", [""])[0]
|
||||
@@ -241,14 +285,25 @@ def save_to_autopay(customer, token, cardholder_name=None, billing_zip=None):
|
||||
return {"success": False, "error": "Vault request failed"}
|
||||
|
||||
if success == "1" and vault_id:
|
||||
# Save to customer
|
||||
inv_customer.custom_auto_pay_id = vault_id
|
||||
inv_customer.custom_auto_pay_status = 1
|
||||
inv_customer.save(ignore_permissions=True)
|
||||
|
||||
return {"success": True}
|
||||
# Save vault ID to ERP Customer
|
||||
cust.custom_auto_pay_id = vault_id
|
||||
cust.custom_auto_pay_status = 1
|
||||
|
||||
return {"success": False, "error": message}
|
||||
cust.custom_auto_pay_name = final_name
|
||||
cust.custom_auto_pay_zip = final_zip
|
||||
|
||||
cust.save(ignore_permissions=True)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"vault_id": vault_id
|
||||
}
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"error": message
|
||||
}
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
|
||||
Reference in New Issue
Block a user