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

  1. 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

Description
No description provided
Readme 138 KiB
Languages
JavaScript 38.6%
HTML 32.8%
Python 28.6%