add additional commits #6

Merged
norman merged 2 commits from main into production 2026-04-28 13:37:17 +00:00
2 changed files with 174 additions and 0 deletions

173
README.md Normal file
View File

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

View File

@@ -2,6 +2,7 @@ import frappe
import requests
import urllib.parse
from frappe.utils import nowdate
from frappe.utils import cint
@frappe.whitelist()