From e0912a4c60ee25f820389481dce39c20d815c50d Mon Sep 17 00:00:00 2001 From: Ty Reynolds Date: Fri, 24 Apr 2026 11:45:00 -0400 Subject: [PATCH 1/2] added missed import. --- ns_app/api/payments.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ns_app/api/payments.py b/ns_app/api/payments.py index b61a6b8..1c68b26 100644 --- a/ns_app/api/payments.py +++ b/ns_app/api/payments.py @@ -2,6 +2,7 @@ import frappe import requests import urllib.parse from frappe.utils import nowdate +from frappe.utils import cint @frappe.whitelist() -- 2.39.5 From 4cc7a2aa28a5616a81c354edf95f82578abee33a Mon Sep 17 00:00:00 2001 From: Ty Reynolds Date: Mon, 27 Apr 2026 10:22:58 -0400 Subject: [PATCH 2/2] Read me. --- README.md | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..8bfdcdb --- /dev/null +++ b/README.md @@ -0,0 +1,173 @@ +NS App – ERPNext Custom Integrations + +Overview + +NS App is a custom ERPNext application that: + +Adding a manual payment form using Collect.js +Processing secure card payments through NMI +Optionally saving payment methods to the NMI Customer Vault +Storing the returned vault ID on the ERPNext Customer for future autopay use + +This part of the app is designed to integrate directly into the Sales Invoice workflow. + +Features +Secure card entry using NMI Collect.js (tokenization) +Manual payment dialog inside ERPNext +Optional “Subscribe to Autopay” checkbox +Conditional vault creation in NMI +Storage of customer_vault_id in ERPNext Customer +Configurable enable/disable of autopay via site_config.json + +Requirements +ERPNext / Frappe Bench environment +NMI gateway account +Collect.js enabled in NMI +Access to modify site_config.json + +Installation +1. Get the app +cd ~/frappe-bench +bench get-app git@git.nsinnovations.net:nsinnovations/ns_erpnext_app.git --skip-assets +2. Install on site +bench --site "site name" install-app ns_app +3. Build and restart +bench build +bench restart + +Configuration + +Edit site configuration: +nano ~/frappe-bench/sites/site-name/site_config.json + +Add: + +{ + "nmi_security_key": "your_nmi_security_key", + "enable_autopay_signup": 0 +} +Notes +nmi_security_key is required for all payment and vault operations +enable_autopay_signup controls whether the checkbox actually triggers vault creation +Frontend Behavior + +The payment dialog includes: + +Cardholder Name +Billing ZIP +Secure card fields via Collect.js +“Subscribe to Autopay” checkbox + +If the checkbox is selected and autopay is enabled in config, the backend will attempt to create a vault entry. + +Backend Flow: +Payment +Collect.js generates a payment token +Token is sent to backend API +Backend sends transaction to NMI +Payment is processed +Autopay (Optional) + +If enabled and selected: + +Backend sends customer_vault=add_customer request to NMI +Uses the same payment token +Parses response for customer_vault_id +Saves ID to ERPNext Customer +Example Vault Request +vault_data = { + "security_key": frappe.conf.get("nmi_security_key"), + "customer_vault": "add_customer", + "payment_token": token, + "first_name": first_name, + "last_name": last_name, + "zip": billing_zip +} +Error Handling + +Vault creation is wrapped in a try/except block to prevent payment failures: + +try: + if int(save_autopay or 0): + # vault logic + pass +except Exception: + frappe.log_error(frappe.get_traceback(), "Autopay Vault Error") +Testing Strategy + +Before enabling in production: + +Set in site_config.json: + +"enable_autopay_signup": 0 +Verify: +Payments process correctly +No vault entries are created + +Enable autopay: + +"enable_autopay_signup": 1 +Test: +Checkbox unchecked → no vault +Checkbox checked → vault created and saved +Deployment Notes +Do not expose autopay functionality until fully tested +Keep enable_autopay_signup disabled in production until ready +Always run: +bench build +bench restart + + +Troubleshooting: +1. App not found + +Ensure app is in apps.txt: + +nano ~/frappe-bench/sites/apps.txt + +Add: + +ns_app + +2. ModuleNotFoundError + +Ensure app is installed in environment: + +./env/bin/pip install -e apps/ns_app +Asset build errors + +Skip during install: + +bench get-app --skip-assets + +Then fix frontend paths before running bench build. + +Vault not saving + +Check logs: + +frappe.log_error(response.text, "Vault Response") + +Verify: + +customer_vault_id is returned +Security key is correct +File Structure +apps/ns_app/ +├── ns_app/ +│ ├── api/ +│ │ └── payments.py +│ ├── public/ +│ │ └── js/ +│ └── hooks.py +├── setup.py +├── pyproject.toml +└── MANIFEST.in + +Security Notes: +Never store raw card data +Always use Collect.js tokenization +Keep nmi_security_key private +Use HTTPS for all requests + + -- 2.39.5