Payment Provider: NMI¶
Overview¶
The Payment Provider: NMI module integrates NMI (Network Merchants) as a payment gateway in Odoo 18. It enables your eCommerce store and Invoicing workflows to accept credit card payments through NMI's Direct Post API with PCI-compliant card tokenization powered by Collect.js.
Customers see a seamless inline card form at checkout. Card data is tokenized in the browser and never touches your Odoo server. The module also supports NMI's Customer Vault for saving cards for future purchases.
Key Features¶
- Collect.js Inline Form -- Secure, PCI-compliant card entry rendered as iFrame fields directly on your checkout page
- Customer Vault Tokenization -- Save customer cards securely in NMI's vault for one-click future payments
- Manual Capture -- Authorize payments and capture later from the Odoo backend
- Partial Refunds -- Issue full or partial refunds on settled transactions
- Void -- Cancel unsettled transactions before they settle
- Zero-Dollar Validation -- Validate cards without charging (used for saving cards)
- Test Credentials Button -- Verify your API key is valid directly from the provider form
Supported Card Brands¶
| Brand | Supported |
|---|---|
| Visa | Yes |
| Mastercard | Yes |
| American Express | Yes |
| Discover | Yes |
Installation & Dependencies¶
Requirements¶
| Requirement | Details |
|---|---|
| Odoo Version | 18.0 Community or Enterprise |
| Dependencies | payment (Odoo core module) |
| NMI Account | Active NMI merchant account with API access |
Installation¶
- Place the
payment_nmimodule folder in your Odoo addons path - Update the module list: Apps > Update Apps List
- Search for "Payment Provider: NMI" and click Install
Note
After installation, the NMI payment provider record is created automatically. You will find it under Invoicing / Accounting > Configuration > Payment Providers.
Configuration¶
Step 1: Obtain Your NMI API Keys¶
This module requires two keys from your NMI Merchant Portal. NMI offers four key types total -- you need one specific private key and one specific public key.
This is the API-type private key used for server-side transaction processing.
- Log in to the NMI Merchant Portal
- Go to Settings > Security Keys
- Click Add a Security Key
- Select permission type: API
- Click Save
- Copy the generated key value
This is the Tokenization-type public key used by Collect.js in the browser.
- In the NMI Merchant Portal, go to Settings > Security Keys
- Click Add a Security Key
- Select permission type: Tokenization
- Click Save
- Copy the generated key value
Use the Correct Key Types
NMI has four key types: API, Cart, Tokenization, and Checkout. This module uses only API (for the Security Key field) and Tokenization (for the Tokenization Key field). Using the wrong key type will cause authentication failures.
The table below summarizes all NMI key types and which ones this module uses:
Private Keys (server-side only):
| NMI Key Type | Permission | Used by This Module? |
|---|---|---|
| API | Direct Post API, Query API, Customer Vault | Yes -- this is your Security Key |
| Cart | QuickClick hosted cart only | No |
Public Keys (safe to expose client-side):
| NMI Key Type | Permission | Used by This Module? |
|---|---|---|
| Tokenization | Collect.js card tokenization only | Yes -- this is your Tokenization Key |
| Checkout | Checkout.js hosted payment page only | No |
Step 2: Configure the Provider in Odoo¶
- Go to Invoicing / Accounting > Configuration > Payment Providers
- Find NMI in the list and click to open it
- Enter your Security Key (the API-type private key)
- Enter your Tokenization Key (the Tokenization-type public key)
- Click Test Credentials to verify the Security Key is valid
- Set the provider state:
- Test Mode -- for sandbox/testing (uses NMI test environment)
- Enabled -- for live production transactions
- Click Save
Test Credentials Button
The Test Credentials button sends a minimal request to NMI to verify your Security Key is valid. If the key is incorrect, you will see an "Authentication Failed" error. A successful test confirms your API key has the right permissions.
Step 3: Configure Payment Options¶
On the NMI provider form, review the following tabs:
- Configuration tab -- Enable or disable Manual Capture (authorize now, capture later)
- Tokenization tab -- Enable Allow Saving Payment Methods if you want customers to save their cards via Customer Vault
How It Works¶
Payment Flow¶
The module uses NMI's Collect.js inline form variant for PCI-compliant card entry:
Customer Browser Odoo Server NMI API
| | |
| 1. Fills card form | |
| (Collect.js iFrame) | |
| | |
| 2. Collect.js tokenizes -------> | |
| card client-side | |
| Returns one-time token | |
| | |
| 3. Token sent to server -------> | |
| (card data never | |
| touches your server) | 4. POST to transact.php --> |
| | with token + |
| | security_key |
| | |
| | 5. Response <-------------- |
| 6. Redirect to status <--------- | (approved/declined) |
| | |
- Customer selects NMI as the payment method on checkout
- Collect.js renders secure iFrame fields for card number, expiration, and CVV
- On submit, Collect.js tokenizes the card data client-side and returns a single-use
payment_token - The token is sent to the Odoo server -- card data never touches your server
- Odoo server calls NMI's Direct Post API with the token and your Security Key
- NMI processes the transaction and returns an approval or decline
- The transaction status is updated in Odoo and the customer is redirected
Saved Cards (Customer Vault)¶
When a customer checks "Save my payment details" during checkout:
- The module includes
customer_vault=add_customerin the NMI API request - NMI stores the card securely in the Customer Vault and returns a
customer_vault_id - Odoo creates a Payment Token linked to the customer with the vault ID
- Future payments use the vault ID instead of collecting card details again
Note
Saved card tokens display the last 4 digits of the card. Customers can manage their saved payment methods from their account portal.
Manual Capture¶
When Manual Capture is enabled on the provider:
- The initial transaction is an authorization (hold on funds, no charge)
- The transaction appears in Odoo with status Authorized
- An administrator can then Capture the payment from the transaction form to finalize the charge
- Alternatively, the transaction can be Voided to release the hold
Refunds¶
Refunds can be issued from the Odoo backend on any completed (settled) transaction:
- Partial refunds are supported -- specify any amount up to the original transaction total
- The refund is processed immediately through NMI
- A refund transaction record is created in Odoo for tracking
Void¶
Unsettled transactions (typically same-day, before the batch closes) can be voided instead of refunded. A void cancels the transaction entirely without any funds being transferred.
Supported Features Summary¶
| Feature | Support |
|---|---|
| Direct payment (Collect.js inline form) | Yes |
| Customer Vault tokenization (saved cards) | Yes |
| Token-based recurring/saved card payments | Yes |
| Manual capture (authorize, then capture) | Full amount only |
| Partial refunds | Yes |
| Transaction void | Yes |
| Zero-dollar card validation | Yes |
| Webhook/async notifications | No (synchronous flow) |
| ACH/eCheck payments | No |
| Apple Pay / Google Pay | No |
| Partial manual capture | No |
Testing¶
Setting Up Test Mode¶
- Go to Invoicing / Accounting > Configuration > Payment Providers
- Open the NMI provider
- Set the state to Test Mode
- Enter your NMI sandbox credentials (Security Key and Tokenization Key from your NMI test account)
- Click Save
Test Card Numbers¶
Use these card numbers in test mode:
| Card | Number | Expiry | CVV |
|---|---|---|---|
| Visa | 4111111111111111 |
Any future date | Any 3 digits |
| MasterCard | 5431111111111111 |
Any future date | Any 3 digits |
| Amex | 341111111111111 |
Any future date | Any 4 digits |
| Discover | 6011601160116611 |
Any future date | Any 3 digits |
Triggering Specific Responses¶
NMI's test mode uses amount-based response simulation. Use these amounts to trigger different outcomes:
| Amount | Result |
|---|---|
$1.00 |
Approved |
$0.00 |
Validation (zero-dollar auth) |
$2.00 |
Declined |
$3.00 |
Error |
Testing the Full Flow
To test a complete flow including tokenization, use a $1.00 order with the "Save my payment details" checkbox enabled. This will create both a successful transaction and a saved payment token in Customer Vault.
Troubleshooting¶
Common Issues¶
Authentication Failed
Symptom: Transactions fail with "Authentication Failed" error.
Solution:
- Verify the Security Key on the NMI provider form is correct
- Ensure you created a key with API permission type (not Cart, Tokenization, or Checkout)
- Use the Test Credentials button to verify the key
- If using test mode, ensure you are using sandbox credentials
Collect.js Form Not Appearing
Symptom: The card entry fields (card number, expiration, CVV) do not render on the checkout page.
Solution:
- Verify the Tokenization Key is set on the NMI provider
- Ensure the key is a Tokenization type key (not API, Cart, or Checkout)
- Check the browser console for JavaScript errors
- Ensure no ad blockers or browser extensions are blocking
secure.nmi.com
Transaction Declined
Symptom: Transaction returns "Declined" status.
Solution:
- In test mode, check the transaction amount --
$2.00always declines - In production, contact NMI or the card issuer for decline reason details
- Review the transaction's
responsetextin Odoo's log for specific decline codes
Tokenization / Save Card Not Working
Symptom: Customer checks "Save my payment details" but no token is created.
Solution:
- Ensure Allow Saving Payment Methods is enabled on the NMI provider (Tokenization tab)
- Verify your NMI account has Customer Vault enabled
- Check Odoo server logs for any
customer_vault_iderrors
NMI Response Codes¶
| Response Code | Meaning |
|---|---|
1 |
Approved |
2 |
Declined |
3 |
Error |
Related Modules¶
- POS NMI -- Extends NMI payment processing to the Point of Sale with physical terminal and key-in support