CloudFFL FFL Finder¶
Overview¶
The CloudFFL FFL Finder module integrates CloudFFL as an FFL dealer locator for your Odoo 18 eCommerce checkout. When a customer's cart contains firearms, ammunition, or other compliance-regulated products, the module presents an FFL dealer search interface on the payment page so the customer can select a licensed dealer to receive their shipment.
All FFL data is sourced in real time from the CloudFFL API, which maintains an always-current nationwide database of ATF-licensed dealers. There is no need to import or maintain local FFL lists.
Key Features¶
- Real-Time FFL Search -- Search by ZIP code proximity, business name, or city/state using the CloudFFL API
- Product-Level Compliance -- Flag individual products as requiring FFL dealer shipment
- Category-Level Compliance -- Flag entire website categories (with automatic inheritance to subcategories)
- State-Based FFL Rules -- Require FFL selection only in specific states for specific categories (e.g., ammunition in California)
- Interactive Map -- Leaflet-powered map with markers for search results
- Payment Gate -- Disables the Pay button until the customer selects an FFL or explicitly defers
- Deferred Selection -- Customers can choose to provide FFL information after checkout
- Age Verification Gate -- Configurable age gate overlay with multiple display styles and date-of-birth validation
- Backend Search Wizard -- Staff can search for FFL dealers directly from the Odoo backend
- Sale Order Integration -- FFL number, dealer data, and compliance badges displayed on orders
- ATF EZ Check Links -- Direct links to ATF's FFL verification tool for each search result
Installation & Dependencies¶
Requirements¶
| Requirement | Details |
|---|---|
| Odoo Version | 18.0 Community or Enterprise |
| Odoo Modules | website, website_sale, sale |
| Python Packages | requests |
| External Account | CloudFFL API key (cloudffl.com) |
Installation¶
- Place the
cloudffl_ffl_findermodule folder in your Odoo addons path - Update the module list: Apps > Update Apps List
- Search for "CloudFFL FFL Finder" and click Install
- The
requestsPython package is required -- it is included in most Odoo installations by default
Note
After installation, the module adds a top-level FFL Finder menu item in the backend for staff use, and a new CloudFFL FFL Finder section in Settings.
Configuration¶
Step 1: Obtain Your CloudFFL API Key¶
- Visit cloudffl.com and create an account
- Subscribe to an API plan
- Copy your API key from the CloudFFL dashboard
Step 2: Configure the Module in Odoo¶
- Go to Settings > CloudFFL FFL Finder
- Enter your CloudFFL API Key
- Click Test Connection to verify the key is valid
- Review the default settings:
| Setting | Default | Description |
|---|---|---|
| API Base URL | https://api.cloudffl.com/api/v1 |
Change only if using a custom endpoint |
| Default Search Radius | 25 miles | Radius used for proximity searches |
| Maximum Results Per Search | 100 | Results returned per API call (max 200) |
Test Connection Button
The Test Connection button performs a sample search against the CloudFFL API to confirm your key is valid and the service is reachable. A success notification includes the number of test results returned.
Step 3: Configure Age Verification (Optional)¶
The age gate settings are found below the API settings on the same configuration page:
| Setting | Options | Description |
|---|---|---|
| Enable Age Gate | On / Off | Show age verification popup on the website |
| Minimum Age | Any integer (default 21) | Required age to access the site |
| Display Style | Centered Modal, Fullscreen Overlay, Top Banner | How the verification prompt appears |
| Theme | Light, Dark | Color scheme of the age gate |
| Remember Verification | Session only, 1 week, 30 days, 90 days | How long the verification cookie lasts |
| Require Date of Birth | On / Off | When off, shows simple confirm/decline buttons; when on, requires month/day/year entry |
Note
The age gate appears on all public-facing website pages. It automatically excludes backend (/web), portal (/my), and login pages. Verification state is shared across browser tabs.
Step 4: Configure State-Based FFL Requirements (Optional)¶
For products that only require FFL shipment in certain states (e.g., ammunition in California):
- In Settings > CloudFFL FFL Finder, scroll to State-Based FFL Requirements
- Click Configure State-Based FFL Requirements
- Select the Product Categories that are subject to state-based rules (e.g., "Ammunition")
- Select the US States where those categories require FFL dealer selection (e.g., "California", "Illinois")
- Save
How State-Based Rules Interact with Other Compliance Flags
Products flagged directly as "Requires FFL Compliance" (at the product or category level) always require FFL selection in every state. State-based rules apply only to the categories and states you configure -- they do not override product-level or category-level flags.
Product & Category FFL Requirements¶
The module provides three layers of compliance control. If any layer triggers for a given order, the FFL finder is displayed at checkout.
Layer 1: Product-Level Compliance¶
Flag individual products that always require FFL shipment (e.g., firearms):
- Open a product template: Products > Products > [Product]
- On the General Information tab, enable Requires FFL Compliance
- Save
The flag is tracked with Odoo's change tracking and appears as a toggleable column in the product list view. You can also filter and group products by their FFL compliance status using the FFL Required filter and FFL Compliance group-by option.
Layer 2: Category-Level Compliance¶
Flag an entire website product category so all products within it (and its subcategories) require FFL:
- Go to Website > eCommerce > Product Categories
- Open a category and enable Requires FFL Compliance
- Save
Compliance is inherited automatically. If you enable it on a parent category (e.g., "Firearms"), all child categories (e.g., "Handguns", "Rifles") inherit the requirement. An FFL Required (Inherited) read-only field shows whether the requirement comes from a parent.
Layer 3: State-Based Category Rules¶
This layer activates FFL requirements only when the customer's shipping state matches a configured rule. See Step 4 above for setup instructions.
The evaluation logic at checkout checks:
- Is the customer's shipping state in the configured state list?
- Does the cart contain any products in the configured categories (including child categories)?
- If both are true, FFL selection is required
eCommerce Checkout Flow¶
When FFL Is Required¶
When a customer reaches the Payment page and their cart triggers FFL requirements, the following happens:
- An alert banner appears explaining why FFL selection is required:
- "Your order contains a firearm..." (product-level)
- "Your order contains items..." (category-level)
- "Your order contains ammunition that requires shipment to a licensed FFL dealer in [State]..." (state-based)
- The Pay Now button is disabled until the customer selects an FFL or defers
- A tabbed search interface is displayed with three search methods
Search Methods¶
Enter a ZIP code and select a radius (10, 25, 50, or 100 miles). Results are sorted by distance from the ZIP code.
Enter a business name (minimum 2 characters) and optionally filter by state. Results match against both business names and license holder names.
Enter a city name and select a state. State selection is required for this search method.
Search Results¶
Search results appear as a scrollable list with the following details for each dealer:
- Business name and FFL number
- Full premise address
- Phone number (clickable to call)
- Select button to choose the dealer
- Map button to highlight the dealer on the interactive map
A Filter results text box allows narrowing results client-side. The results count updates as you type.
Interactive Map¶
An interactive Leaflet map is displayed automatically when search results include coordinate data. Features:
- Markers for each dealer location
- Click a marker to see a popup with dealer details and a Select This Dealer button
- Click Map on any list item to zoom to that dealer on the map
- Toggle map visibility with the Show Map / Hide Map button
Selecting a Dealer¶
When a customer clicks Select on a dealer:
- The dealer's premise address is created as a delivery address in Odoo (or updated if the FFL number already exists)
- The sale order's shipping address is set to the FFL dealer
- The FFL number and full dealer data are stored on the order
- The page reloads showing the selected dealer in a success banner
- The Pay Now button becomes enabled
Changing or Clearing an FFL¶
If a dealer is already selected, the search interface remains available below the selected dealer card. Customers can search for and select a different dealer at any time. The previous selection is replaced.
Deferring FFL Selection¶
Customers can click "I'll provide FFL information later" to proceed without selecting an FFL:
- A confirmation dialog appears
- If confirmed, the order is flagged as "FFL Selection Deferred"
- A note is added to the order
- The Pay Now button is enabled
- Staff will see a prominent alert on the order in the backend
Age Verification¶
The age gate is a frontend overlay that appears before any page content loads on public website pages. It is entirely client-side and uses cookies for persistence.
Display Styles¶
| Style | Description |
|---|---|
| Centered Modal | A dialog box centered on the page with a semi-transparent backdrop |
| Fullscreen Overlay | A full-screen takeover with large text and buttons |
| Top Banner | A dismissable banner at the top of the page with a dimmed backdrop |
Verification Modes¶
- Simple Confirmation (default): Two buttons -- "I am [age] or older" and "I am under [age]"
- Date of Birth Entry: Month, day, and year dropdowns. The module calculates the customer's age and validates it against the minimum
Behavior¶
- Declining redirects the visitor to Google
- Verification is stored in a cookie and shared across tabs via
sessionStorage - The year dropdown is populated dynamically (current year minus 100 years)
- Backend, portal, and sitemap pages are excluded from the age gate
Backend Search Wizard¶
Staff can search for FFL dealers from two locations in the backend:
Standalone FFL Search¶
- Go to FFL Finder > Search FFLs
- Select a search type: ZIP Code Radius, Business/License Name, FFL Number, or City/State
- Enter search parameters and click Search
- Results appear in a list with columns for FFL number, name, city, state, ZIP, phone, and distance
- Click Map on any result to open the location in Google Maps
- Click a result to view full details including ATF EZ Check verification link
Sale Order FFL Selection¶
When viewing a sale order that requires FFL compliance:
- A Select FFL button appears in the order's button box (or Update FFL if one is already selected)
- Click it to open the search wizard
- Search for and select a dealer
- The wizard updates the order's shipping address, FFL number, and associated delivery orders
Deferred FFL Alert
If a customer deferred FFL selection during checkout, a red alert banner appears at the top of the sale order form: "FFL Selection Required! Customer deferred FFL selection during checkout. Please contact customer to obtain FFL dealer information before shipping this order."
Order Line FFL Badges¶
Each sale order line has an FFL column (toggleable badge) that indicates whether that specific product requires FFL compliance. This is computed automatically from the product's compliance flag and its category inheritance.
Troubleshooting¶
Common Issues¶
FFL Finder Not Appearing at Checkout
Symptom: The FFL search interface does not appear on the payment page even though the cart contains regulated products.
Solution:
- Verify the CloudFFL API key is configured in Settings > CloudFFL FFL Finder
- Check that the product has Requires FFL Compliance enabled, or that its website category has the flag enabled
- For state-based rules, verify both the category and the customer's shipping state are configured
- Clear the browser cache and reload the page
API Authentication Failed
Symptom: Searches return an authentication error.
Solution:
- Go to Settings > CloudFFL FFL Finder and re-enter your API key
- Click Test Connection to verify
- Ensure your CloudFFL subscription is active at cloudffl.com
No Results Found
Symptom: Searches return zero results.
Solution:
- Try expanding the search radius for ZIP code searches
- For business name searches, try shorter or partial names (minimum 2 characters)
- Verify the ZIP code or city/state is valid
- Check the Odoo server log for API error details
Pay Button Still Disabled
Symptom: The customer selected an FFL dealer but the Pay button remains disabled.
Solution:
- Reload the page -- the payment validation widget checks the
ffl_numberhidden field on load - Verify the FFL selection saved by checking the order in the backend
- Check the browser console for JavaScript errors
Map Not Displaying
Symptom: The map area is empty or the toggle button does not appear.
Solution:
- The Leaflet JS library is loaded from
unpkg.com-- ensure your server and client can reach this CDN - Check the browser console for JavaScript errors related to Leaflet
- The map only appears when search results include latitude/longitude coordinates
Age Gate Not Showing
Symptom: The age verification overlay does not appear on the website.
Solution:
- Verify Enable Age Gate is turned on in Settings > CloudFFL FFL Finder
- Clear cookies -- if you previously verified, the cookie may still be set
- Age gate is excluded on
/web,/odoo,/my, and/sitemappaths by design - Check the page source for the
cloudffl_age_gateelement
Related Modules¶
- FastBound -- Complete firearms compliance suite for A&D book management, acquisitions, and dispositions