add additional commits #6
173
README.md
Normal file
173
README.md
Normal 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
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import frappe
|
||||
import requests
|
||||
import urllib.parse
|
||||
from frappe.utils import nowdate
|
||||
from frappe.utils import cint
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
||||
Reference in New Issue
Block a user