<div class="njdtc-wrap" aria-label="NJ Dispensary Tax Calculator Widget">
<div class="njdtc-card">
<h2 class="njdtc-title">NJ Out-the-Door Dispensary Tax Calculator</h2>
<p class="njdtc-subtitle">Estimate your total with NJ 6.625% sales tax (as applicable), municipal transfer tax (0–2%), and an optional SEEF pass-through ($2.50/oz).</p>
<div class="njdtc-infobox" role="note" aria-label="Important assumptions">
<div class="njdtc-infobox-title">Assumptions & notes</div>
<ul class="njdtc-infobox-list">
<li><strong>Adult-use:</strong> applies NJ state sales tax (6.625%). <strong>Medical:</strong> sets state sales tax to 0%.</li>
<li><strong>Municipal transfer tax</strong> is applied here as a percent of the item subtotal.</li>
<li><strong>SEEF pass-through</strong> is estimated at <strong>$2.50 per ounce</strong> based on the weight you enter (1 oz = 28.3495 g).</li>
<li><strong>280E</strong> is a <em>business</em> tax rule—shown as an informational line item only (not added to your total).</li>
</ul>
</div>
<form class="njdtc-form" aria-label="Tax calculator form">
<div class="njdtc-group">
<label class="njdtc-label">Purchase type</label>
<div class="njdtc-radioRow" role="radiogroup" aria-label="Purchase type">
<label class="njdtc-radio"><input type="radio" name="njdtc-saleType" value="adult" checked aria-label="Adult-use" /> Adult-use</label>
<label class="njdtc-radio"><input type="radio" name="njdtc-saleType" value="medical" aria-label="Medical" /> Medical</label>
</div>
</div>
<div class="njdtc-group">
<label class="njdtc-label">How do you want to enter your items?</label>
<div class="njdtc-radioRow" role="radiogroup" aria-label="Entry method">
<label class="njdtc-radio"><input type="radio" name="njdtc-entryMode" value="subtotal" checked aria-label="Enter subtotal" /> Enter subtotal</label>
<label class="njdtc-radio"><input type="radio" name="njdtc-entryMode" value="lines" aria-label="Enter line items" /> Enter line items</label>
</div>
</div>
<div class="njdtc-group" id="njdtc-subtotalGroup">
<label class="njdtc-label" for="njdtc-subtotal">Item subtotal (before taxes/fees)</label>
<input class="njdtc-input" id="njdtc-subtotal" type="text" inputmode="decimal" placeholder="e.g., 75.00" aria-label="Item subtotal" />
<div class="njdtc-help">Tip: You can type <strong>75</strong> or <strong>$75.00</strong>.</div>
</div>
<div class="njdtc-group njdtc-hidden" id="njdtc-linesGroup">
<label class="njdtc-label" for="njdtc-lines">Line items (optional)</label>
<textarea class="njdtc-textarea" id="njdtc-lines" rows="5" placeholder="Examples:
Flower (1/8) - 45
Gummies - 30.00
Pre-roll 12" aria-label="Line items"></textarea>
<div class="njdtc-help">We’ll add up the last number on each line as the price.</div>
</div>
<div class="njdtc-group">
<label class="njdtc-label" for="njdtc-muni">Municipal transfer tax rate</label>
<select class="njdtc-select" id="njdtc-muni" aria-label="Municipal transfer tax rate">
<option value="0">0%</option>
<option value="0.01">1%</option>
<option value="0.02">2%</option>
</select>
</div>
<div class="njdtc-group">
<label class="njdtc-label">Weight (for SEEF pass-through)</label>
<div class="njdtc-inline">
<input class="njdtc-input" id="njdtc-weight" type="number" inputmode="decimal" min="0" step="0.01" placeholder="e.g., 3.5" aria-label="Weight amount" />
<select class="njdtc-select" id="njdtc-unit" aria-label="Weight unit">
<option value="g" selected>grams (g)</option>
<option value="oz">ounces (oz)</option>
</select>
</div>
<label class="njdtc-check" for="njdtc-includeSeef">
<input type="checkbox" id="njdtc-includeSeef" checked aria-label="Include SEEF pass-through" />
Include SEEF pass-through ($2.50/oz)
</label>
</div>
<button class="njdtc-btn" type="button" id="njdtc-calcBtn" aria-label="Calculate out-the-door total">Calculate total</button>
<div class="njdtc-error njdtc-hidden" id="njdtc-error" role="alert" aria-label="Error message"></div>
</form>
<div class="njdtc-leadGate njdtc-hidden" id="njdtc-leadGate" aria-label="Lead form">
<div class="njdtc-leadHeading">Your estimate is ready</div>
<div class="njdtc-leadDesc">Enter your details to view the itemized receipt.</div>
<div class="njdtc-group">
<label class="njdtc-label" for="njdtc-leadCompany">Company name</label>
<input class="njdtc-input" id="njdtc-leadCompany" type="text" placeholder="e.g., Garden State Dispensary" />
</div>
<div class="njdtc-group">
<label class="njdtc-label" for="njdtc-leadEmail">Business email</label>
<input class="njdtc-input" id="njdtc-leadEmail" type="email" placeholder="you@company.com" />
</div>
<div class="njdtc-group">
<label class="njdtc-label" for="njdtc-leadRole">Which best describes you?</label>
<select class="njdtc-select" id="njdtc-leadRole">
<option value="">— Select —</option>
<option value="dispensary">Dispensary / Retailer</option>
<option value="brand">Brand / Manufacturer</option>
<option value="distributor">Distributor</option>
<option value="consultant">Consultant / Advisor</option>
<option value="other">Other</option>
</select>
</div>
<button class="njdtc-btn" type="button" id="njdtc-showResultsBtn">Show my estimate</button>
<div class="njdtc-error njdtc-hidden" id="njdtc-leadError" role="alert"></div>
</div>
<div class="njdtc-results njdtc-hidden" id="njdtc-results" aria-label="Results">
<div class="njdtc-resultsInner">
<h3 class="njdtc-resultsTitle">Estimated receipt</h3>
<div class="njdtc-receipt" aria-label="Itemized receipt">
<div class="njdtc-row"><div class="njdtc-left">Item subtotal</div><div class="njdtc-right" id="njdtc-out-subtotal">—</div></div>
<div class="njdtc-row"><div class="njdtc-left">Municipal transfer tax (<span id="njdtc-out-muniRate">—</span>)</div><div class="njdtc-right" id="njdtc-out-muni">—</div></div>
<div class="njdtc-row"><div class="njdtc-left">NJ state sales tax (<span id="njdtc-out-salesRate">—</span>)</div><div class="njdtc-right" id="njdtc-out-sales">—</div></div>
<div class="njdtc-row"><div class="njdtc-left">SEEF pass-through</div><div class="njdtc-right" id="njdtc-out-seef">—</div></div>
<div class="njdtc-row njdtc-rowMuted"><div class="njdtc-left">280E (business tax; not charged at checkout)</div><div class="njdtc-right">N/A</div></div>
<div class="njdtc-divider"></div>
<div class="njdtc-row njdtc-rowTotal"><div class="njdtc-left">Out-the-door total</div><div class="njdtc-right" id="njdtc-out-total">—</div></div>
</div>
<div class="njdtc-share" aria-label="Shareable link">
<label class="njdtc-label" for="njdtc-shareLink">Shareable link</label>
<input class="njdtc-input" id="njdtc-shareLink" type="text" readonly aria-label="Shareable link input" />
<button class="njdtc-btnSecondary" type="button" id="njdtc-copyBtn" aria-label="Copy shareable link">Copy link</button>
<div class="njdtc-help" id="njdtc-copyStatus" aria-live="polite"></div>
</div>
</div>
</div>
<div class="njdtc-footnote">This tool is for estimation/education only. Check your receipt and local rules for the final amount.</div>
</div>
</div>
<style>
.njdtc-wrap{max-width:760px;margin:24px auto;padding:0 16px;font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,"Apple Color Emoji","Segoe UI Emoji";color:#111827;}
.njdtc-card{background:#fff;border-radius:12px;padding:40px;box-shadow:0 10px 30px rgba(17,24,39,.08);border:1px solid rgba(17,24,39,.06);}
.njdtc-title{font-size:32px;line-height:1.15;margin:0 0 10px;text-align:center;font-weight:800;letter-spacing:-0.02em;}
.njdtc-subtitle{margin:0 0 22px;text-align:center;color:#4b5563;font-size:16px;line-height:1.5;}
.njdtc-infobox{border-left:4px solid #2563eb;background:#f8fafc;border-radius:10px;padding:14px 14px 14px 14px;margin:0 0 22px;}
.njdtc-infobox-title{font-weight:700;margin:0 0 8px;font-size:14px;color:#111827;}
.njdtc-infobox-list{margin:0;padding-left:18px;color:#374151;font-size:14px;line-height:1.45;}
.njdtc-infobox-list li{margin:6px 0;}
.njdtc-form{margin-top:6px;}
.njdtc-group{margin:16px 0;}
.njdtc-label{display:block;font-weight:700;font-size:14px;margin:0 0 8px;color:#111827;}
.njdtc-help{margin-top:8px;color:#6b7280;font-size:13px;line-height:1.35;}
.njdtc-input,.njdtc-select,.njdtc-textarea{width:100%;box-sizing:border-box;border:1px solid rgba(17,24,39,.14);border-radius:10px;padding:12px 12px;font-size:15px;outline:none;background:#fff;}
.njdtc-input:focus,.njdtc-select:focus,.njdtc-textarea:focus{border-color:#2563eb;box-shadow:0 0 0 3px rgba(37,99,235,.12);}
.njdtc-textarea{resize:vertical;min-height:110px;}
.njdtc-inline{display:flex;gap:10px;align-items:center;}
.njdtc-inline .njdtc-input{flex:1;}
.njdtc-inline .njdtc-select{width:180px;}
.njdtc-radioRow{display:flex;gap:14px;flex-wrap:wrap;}
.njdtc-radio{display:flex;align-items:center;gap:8px;font-size:14px;color:#111827;}
.njdtc-check{display:flex;align-items:center;gap:10px;margin-top:10px;font-size:14px;color:#111827;}
.njdtc-btn{width:100%;background:#2563eb;color:#fff;border:none;border-radius:12px;padding:14px 16px;font-size:16px;font-weight:800;cursor:pointer;margin-top:10px;}
.njdtc-btn:hover{background:#1d4ed8;}
.njdtc-btn:active{transform:translateY(1px);}
.njdtc-btnSecondary{width:100%;margin-top:10px;background:#fff;color:#1f2937;border:1px solid rgba(17,24,39,.18);border-radius:12px;padding:12px 14px;font-size:15px;font-weight:700;cursor:pointer;}
.njdtc-btnSecondary:hover{border-color:rgba(37,99,235,.45);box-shadow:0 0 0 3px rgba(37,99,235,.10);}
.njdtc-error{margin-top:14px;background:#fef2f2;border:1px solid rgba(239,68,68,.25);color:#991b1b;border-radius:10px;padding:10px 12px;font-size:14px;line-height:1.35;}
.njdtc-leadGate{margin-top:22px;border:1px solid rgba(37,99,235,.18);background:#f8fafc;border-radius:12px;padding:20px;}
.njdtc-leadHeading{font-size:18px;font-weight:800;margin-bottom:6px;color:#111827;}
.njdtc-leadDesc{font-size:14px;color:#4b5563;margin-bottom:14px;}
.njdtc-results{margin-top:22px;border-top:1px solid rgba(17,24,39,.10);padding-top:22px;}
.njdtc-resultsTitle{margin:0 0 14px;font-size:18px;font-weight:800;}
.njdtc-receipt{border:1px solid rgba(17,24,39,.10);border-radius:12px;padding:14px;background:#fff;}
.njdtc-row{display:flex;justify-content:space-between;gap:12px;padding:10px 6px;font-size:15px;}
.njdtc-left{color:#111827;}
.njdtc-right{color:#111827;font-variant-numeric:tabular-nums;white-space:nowrap;}
.njdtc-rowMuted .njdtc-left,.njdtc-rowMuted .njdtc-right{color:#6b7280;font-size:14px;}
.njdtc-divider{height:1px;background:rgba(17,24,39,.10);margin:8px 0;}
.njdtc-rowTotal .njdtc-left,.njdtc-rowTotal .njdtc-right{font-weight:900;font-size:16px;}
.njdtc-share{margin-top:16px;}
.njdtc-footnote{margin-top:16px;color:#6b7280;font-size:13px;line-height:1.4;text-align:center;}
.njdtc-hidden{display:none !important;}
@media (max-width:640px){
.njdtc-card{padding:22px;}
.njdtc-title{font-size:26px;}
.njdtc-inline{flex-direction:column;align-items:stretch;}
.njdtc-inline .njdtc-select{width:100%;}
}
</style>
<script>
(function(){
var STATE_SALES_TAX_RATE = 0.06625;
var SEEF_PER_OZ = 2.50;
var GRAMS_PER_OZ = 28.3495;
var LEAD_CONFIG = {
API_URL: 'https://cannabiz-leads.vercel.app/api/lead',
SHARED_SECRET: 'cannabiz_lead_2025_Xk9mP7nQ2vR8wL4jT6hY3sF9dA1bC5eG0iN',
DOMAIN_LABEL: 'cannabizcredit.com',
PAGE_ID: 'nj-dispensary-tax-calculator'
};
var el = function(id){ return document.getElementById(id); };
var entryModeRadios = document.querySelectorAll('input[name="njdtc-entryMode"]');
var saleTypeRadios = document.querySelectorAll('input[name="njdtc-saleType"]');
var subtotalGroup = el('njdtc-subtotalGroup');
var linesGroup = el('njdtc-linesGroup');
var subtotalInput = el('njdtc-subtotal');
var linesInput = el('njdtc-lines');
var muniSelect = el('njdtc-muni');
var weightInput = el('njdtc-weight');
var unitSelect = el('njdtc-unit');
var includeSeef = el('njdtc-includeSeef');
var calcBtn = el('njdtc-calcBtn');
var results = el('njdtc-results');
var errorBox = el('njdtc-error');
var outSubtotal = el('njdtc-out-subtotal');
var outMuni = el('njdtc-out-muni');
var outSales = el('njdtc-out-sales');
var outSeef = el('njdtc-out-seef');
var outTotal = el('njdtc-out-total');
var outMuniRate = el('njdtc-out-muniRate');
var outSalesRate = el('njdtc-out-salesRate');
var shareLink = el('njdtc-shareLink');
var copyBtn = el('njdtc-copyBtn');
var copyStatus = el('njdtc-copyStatus');
var leadGate = el('njdtc-leadGate');
var leadCompany = el('njdtc-leadCompany');
var leadEmail = el('njdtc-leadEmail');
var leadRole = el('njdtc-leadRole');
var showResultsBtn = el('njdtc-showResultsBtn');
var leadError = el('njdtc-leadError');
var pendingLeadContext = null;
var leadSubmitted = false;
function getCheckedValue(nodeList){
for (var i=0;i<nodeList.length;i++) if (nodeList[i].checked) return nodeList[i].value;
return null;
}
function showError(msg){
errorBox.textContent = msg;
errorBox.classList.remove('njdtc-hidden');
}
function clearError(){
errorBox.textContent = '';
errorBox.classList.add('njdtc-hidden');
}
function toCents(n){
return Math.round((n + Number.EPSILON) * 100);
}
function fromCents(c){
return c / 100;
}
function formatMoney(n){
try {
return new Intl.NumberFormat('en-US',{style:'currency',currency:'USD'}).format(n);
} catch(e){
return '$' + (Math.round(n*100)/100).toFixed(2);
}
}
function formatPercent(r){
return (r*100).toFixed(3).replace(/0+$/,'').replace(/\.$/,'') + '%';
}
function parseMoney(str){
if (!str) return NaN;
var cleaned = String(str).replace(/[^0-9.\-]/g,'');
if (cleaned.trim() === '' || cleaned === '-' || cleaned === '.') return NaN;
var n = Number(cleaned);
return isFinite(n) ? n : NaN;
}
function parseLineItems(text){
var lines = String(text || '').split(/\r?\n/);
var sum = 0;
var foundAny = false;
for (var i=0;i<lines.length;i++){
var line = lines[i].trim();
if (!line) continue;
// Grab the last number-like token on the line
var matches = line.match(/-?\$?\s*\d+(?:\.\d+)?(?!.*\d)/);
if (!matches) continue;
var n = parseMoney(matches[0]);
if (isFinite(n)){
sum += n;
foundAny = true;
}
}
return { sum: sum, foundAny: foundAny };
}
function ouncesFromWeight(weight, unit){
if (!isFinite(weight) || weight < 0) return NaN;
if (unit === 'oz') return weight;
// grams
return weight / GRAMS_PER_OZ;
}
function setEntryModeUI(){
var mode = getCheckedValue(entryModeRadios);
if (mode === 'lines'){
linesGroup.classList.remove('njdtc-hidden');
subtotalGroup.classList.add('njdtc-hidden');
} else {
subtotalGroup.classList.remove('njdtc-hidden');
linesGroup.classList.add('njdtc-hidden');
}
}
function buildShareUrl(state){
var base = window.location.href.split('#')[0].split('?')[0];
var params = new URLSearchParams();
params.set('sale', state.saleType);
params.set('mode', state.entryMode);
if (state.entryMode === 'lines'){
if (state.linesRaw) params.set('lines', state.linesRaw);
} else {
params.set('sub', String(state.subtotal));
}
params.set('muni', String(state.muniRate));
params.set('w', String(state.weight));
params.set('u', state.unit);
params.set('seef', state.includeSeef ? '1' : '0');
return base + '?' + params.toString();
}
function applyStateFromUrl(){
var qs = new URLSearchParams(window.location.search || '');
if (!qs || Array.from(qs.keys()).length === 0) return;
var sale = qs.get('sale');
if (sale === 'adult' || sale === 'medical'){
for (var i=0;i<saleTypeRadios.length;i++) saleTypeRadios[i].checked = (saleTypeRadios[i].value === sale);
}
var mode = qs.get('mode');
if (mode === 'subtotal' || mode === 'lines'){
for (var j=0;j<entryModeRadios.length;j++) entryModeRadios[j].checked = (entryModeRadios[j].value === mode);
}
setEntryModeUI();
var sub = qs.get('sub');
if (sub != null) subtotalInput.value = sub;
var lines = qs.get('lines');
if (lines != null) linesInput.value = lines;
var muni = qs.get('muni');
if (muni != null && (muni === '0' || muni === '0.01' || muni === '0.02')) muniSelect.value = muni;
var w = qs.get('w');
if (w != null) weightInput.value = w;
var u = qs.get('u');
if (u === 'g' || u === 'oz') unitSelect.value = u;
var seef = qs.get('seef');
if (seef === '0' || seef === '1') includeSeef.checked = (seef === '1');
}
function calculate(){
clearError();
copyStatus.textContent = '';
var saleType = getCheckedValue(saleTypeRadios) || 'adult';
var entryMode = getCheckedValue(entryModeRadios) || 'subtotal';
var subtotal = NaN;
var linesRaw = '';
if (entryMode === 'lines'){
linesRaw = String(linesInput.value || '');
var parsed = parseLineItems(linesRaw);
if (!parsed.foundAny){
showError('Please enter at least one line with a price (e.g., “Gummies - 30”). Or switch to “Enter subtotal”.');
results.classList.add('njdtc-hidden');
return;
}
subtotal = parsed.sum;
} else {
subtotal = parseMoney(subtotalInput.value);
if (!isFinite(subtotal) || subtotal < 0){
showError('Please enter a valid item subtotal (e.g., 75.00).');
results.classList.add('njdtc-hidden');
return;
}
}
var muniRate = Number(muniSelect.value);
if (!(muniRate === 0 || muniRate === 0.01 || muniRate === 0.02)) muniRate = 0;
var weight = Number(weightInput.value);
if (!isFinite(weight) || weight < 0){
showError('Please enter a valid weight (0 or more).');
results.classList.add('njdtc-hidden');
return;
}
var unit = unitSelect.value === 'oz' ? 'oz' : 'g';
var salesTaxRate = (saleType === 'adult') ? STATE_SALES_TAX_RATE : 0;
// Compute in cents to reduce floating issues
var subtotalC = toCents(subtotal);
var muniC = toCents(fromCents(subtotalC) * muniRate);
var salesC = toCents(fromCents(subtotalC) * salesTaxRate);
var seefC = 0;
if (includeSeef.checked){
var oz = ouncesFromWeight(weight, unit);
if (!isFinite(oz)){
showError('Weight looks invalid.');
results.classList.add('njdtc-hidden');
return;
}
seefC = toCents(oz * SEEF_PER_OZ);
}
var totalC = subtotalC + muniC + salesC + seefC;
outSubtotal.textContent = formatMoney(fromCents(subtotalC));
outMuni.textContent = formatMoney(fromCents(muniC));
outSales.textContent = formatMoney(fromCents(salesC));
outSeef.textContent = includeSeef.checked ? formatMoney(fromCents(seefC)) : formatMoney(0);
outTotal.textContent = formatMoney(fromCents(totalC));
outMuniRate.textContent = (muniRate*100).toFixed(0) + '%';
outSalesRate.textContent = (salesTaxRate === 0) ? '0% (medical)' : formatPercent(salesTaxRate);
var state = {
saleType: saleType,
entryMode: entryMode,
subtotal: fromCents(subtotalC).toFixed(2),
linesRaw: linesRaw,
muniRate: muniRate,
weight: String(weight),
unit: unit,
includeSeef: includeSeef.checked
};
shareLink.value = buildShareUrl(state);
pendingLeadContext = {
tool: 'nj-dispensary-tax-calculator',
sale_type: saleType,
entry_mode: entryMode,
subtotal: fromCents(subtotalC).toFixed(2),
municipal_tax_rate: muniRate,
weight: String(weight),
weight_unit: unit,
include_seef: includeSeef.checked,
sales_tax: fromCents(salesC).toFixed(2),
municipal_tax: fromCents(muniC).toFixed(2),
seef: fromCents(seefC).toFixed(2),
total: fromCents(totalC).toFixed(2)
};
results.classList.add('njdtc-hidden');
if (leadSubmitted) {
results.classList.remove('njdtc-hidden');
results.scrollIntoView({behavior:'smooth', block:'start'});
} else {
leadGate.classList.remove('njdtc-hidden');
leadGate.scrollIntoView({behavior:'smooth', block:'start'});
}
}
function validEmail(value){
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(value || '').trim());
}
async function submitLead(){
var company = String(leadCompany.value || '').trim();
var email = String(leadEmail.value || '').trim();
var role = leadRole.value;
leadError.classList.add('njdtc-hidden');
leadError.textContent = '';
if (!company || !validEmail(email) || !role){
leadError.textContent = 'Please enter your company, a valid business email, and your role.';
leadError.classList.remove('njdtc-hidden');
return;
}
var payload = {
company: company,
email: email,
role: role,
domain: LEAD_CONFIG.DOMAIN_LABEL,
page: LEAD_CONFIG.PAGE_ID,
context: pendingLeadContext || {},
utm: {}
};
try {
var sp = new URLSearchParams(window.location.search);
['utm_source','utm_medium','utm_campaign','utm_term','utm_content'].forEach(function(k){
if (sp.get(k)) payload.utm[k] = sp.get(k);
});
} catch(e){}
try {
var ctrl = typeof AbortSignal !== 'undefined' && AbortSignal.timeout ? AbortSignal.timeout(2000) : undefined;
var ipRes = await fetch('https://api.ipify.org?format=json', { signal: ctrl });
var ipData = await ipRes.json();
payload.ip = ipData.ip;
} catch(e){}
try {
await fetch(LEAD_CONFIG.API_URL, {
method: 'POST',
headers: { 'Content-Type':'application/json', 'x-shared-secret': LEAD_CONFIG.SHARED_SECRET },
body: JSON.stringify(payload)
});
} catch(e){}
leadSubmitted = true;
leadGate.classList.add('njdtc-hidden');
results.classList.remove('njdtc-hidden');
results.scrollIntoView({behavior:'smooth', block:'start'});
}
function copyShareLink(){
var val = shareLink.value || '';
if (!val){
copyStatus.textContent = 'Calculate first to generate a link.';
return;
}
if (navigator.clipboard && navigator.clipboard.writeText){
navigator.clipboard.writeText(val).then(function(){
copyStatus.textContent = 'Link copied.';
}).catch(function(){
fallbackCopy(val);
});
} else {
fallbackCopy(val);
}
}
function fallbackCopy(text){
try{
shareLink.focus();
shareLink.select();
var ok = document.execCommand('copy');
copyStatus.textContent = ok ? 'Link copied.' : 'Copy failed—please copy manually.';
} catch(e){
copyStatus.textContent = 'Copy failed—please copy manually.';
}
}
// Events
for (var i=0;i<entryModeRadios.length;i++){
entryModeRadios[i].addEventListener('change', setEntryModeUI);
}
calcBtn.addEventListener('click', calculate);
copyBtn.addEventListener('click', copyShareLink);
showResultsBtn.addEventListener('click', submitLead);
// Init
applyStateFromUrl();
setEntryModeUI();
// Optional: auto-calc if URL has params that look complete
var qs = new URLSearchParams(window.location.search || '');
if (qs.has('sub') || qs.has('lines')){
// Only auto-calc if weight is present too (reduces surprise)
if (qs.has('w')) calculate();
}
})();
</script>
New Jersey’s adult-use cannabis taxes can be simple on paper, but confusing at checkout—especially when the local transfer tax changes by municipality and the Social Equity Excise Fee (SEEF) is measured per ounce. This guide explains how an NJ Dispensary Tax Calculator — interactive: 6.625% state sales tax, 0–2% municipal transfer tax selector, SEEF $2.50/oz pass-through, 280E line should work, what numbers to use, and how to apply them to real carts and pricing.
Key 2026 NJ adult-use tax inputs (from NJ-focused tax sources): 6.625% state sales tax, up to 2% municipal transfer tax, and SEEF set at $2.50 per ounce of usable recreational cannabis for 2026.
What an NJ Dispensary Tax Calculator Should Include (Interactive Inputs)
A strong calculator doesn’t just spit out a total. It mirrors the real components that drive an “out-the-door” price in New Jersey adult-use sales: state sales tax, optional local transfer tax (by municipality), and the SEEF amount based on ounces. Multiple NJ tax references agree on the core structure: 6.625% state sales tax + up to 2% local transfer tax + SEEF (reset annually) for adult-use cannabis in NJ (see Alloy Silverstein, CannabisPromotions, and The Library NJ).
Minimum interactive fields
- Pre-tax subtotal (the product total before any taxes/fees)
- Municipal transfer tax selector (0% to 2%), because NJ allows a transfer tax of up to 2% on recreational sales (per Alloy Silverstein)
- Ounces sold (or an ounce-equivalent input) to calculate SEEF at the 2026 rate
- Outputs: state sales tax amount (6.625%), municipal transfer tax amount (0–2%), SEEF dollars, and final total
Optional (but useful) outputs: “SEEF pass-through” and “280E line”
Even though your calculator’s math is tax-driven, the presentation can be operationally helpful:
- SEEF “pass-through” line: show SEEF as its own line item so the shopper (or your internal pricing team) can see the per-ounce excise amount clearly. The critical hard number for 2026 is $2.50/oz (documented in NJ tax guidance such as TC Advisors CPA and reiterated by NJ cannabis tax explainers like CannabisCPA.tax).
- “280E line”: a separate line or note for internal reporting that flags 280E-related tracking. NJ-focused cannabis accounting guidance explicitly discusses 280E alongside NJ excise obligations (see NJ Cannabis Business Tax Guide 2026: 280E & SEEF). Your calculator can include a placeholder line for internal use without changing the customer-facing total.
NJ Adult-Use Cannabis Tax Rates You Should Use (2026 Numbers)
To build or validate an NJ tax calculator, start with the rates consistently cited in NJ cannabis tax references.
1) NJ state sales tax: 6.625%
Multiple NJ tax sources cite the same statewide sales tax rate applied to recreational cannabis: 6.625% (for example Alloy Silverstein and The Library NJ).
2) Municipal transfer tax: 0% to 2% (selector)
New Jersey municipalities can impose a local transfer tax of up to 2% on recreational cannabis sales (noted by Alloy Silverstein and summarized in NJ rate roundups like CannabisPromotions). Because it’s municipality-dependent, your calculator should treat it as a drop-down or slider from 0% to 2%.
3) Social Equity Excise Fee (SEEF): $2.50 per ounce in 2026
For 2026, NJ’s Social Equity Excise Fee is clearly stated as $2.50 per ounce of usable recreational cannabis (see TC Advisors CPA). NJ tax summaries also describe SEEF as an additional component alongside sales and municipal transfer tax, and note it is reset annually, with 2026 figures around $2.50/oz (see CannabisPromotions).
What your total “tax rate” range looks like (before SEEF)
When you combine the state sales tax with the municipal transfer tax, New Jersey’s adult-use cannabis taxes commonly total 6.625% to 8.625% depending on the local rate, as summarized by The Library NJ. SEEF is then added based on ounces (a flat-dollar excise amount), so it’s best displayed as a separate line item rather than folded into a percentage.
How to Calculate NJ Cannabis Checkout Totals (Step-by-Step)
If you’re building a spreadsheet, POS logic, or an online widget, these steps keep the calculation transparent. The formulas below use only the tax values cited by NJ cannabis tax resources.
Step 1: Start with the pre-tax subtotal
Let’s call it Subtotal. Example: $100.00.
Step 2: Calculate NJ state sales tax (6.625%)
State Sales Tax = Subtotal × 0.06625
Example: $100.00 × 0.06625 = $6.63 (rounded).
Step 3: Calculate municipal transfer tax (0%–2%)
Municipal Transfer Tax = Subtotal × MunicipalRate
Example (2% municipality): $100.00 × 0.02 = $2.00.
This 0%–2% range is what your selector should represent, since NJ can charge a transfer tax up to 2% (per Alloy Silverstein).
Step 4: Calculate SEEF ($2.50 per ounce in 2026)
SEEF = OuncesSold × $2.50
The $2.50/oz figure for 2026 is stated directly in NJ cannabis accounting/tax guidance (see TC Advisors CPA) and is also reflected in NJ rate roundups (see CannabisPromotions).
Example: If the cart equals 0.25 oz, then SEEF = 0.25 × $2.50 = $0.63 (rounded).
Step 5: Add everything to get the estimated total
Total = Subtotal + State Sales Tax + Municipal Transfer Tax + SEEF
Example (Subtotal $100.00, Municipal 2%, Ounces 0.25):
- State sales tax: $6.63
- Municipal transfer tax: $2.00
- SEEF: $0.63
- Total: $109.26
Second example: Same cart, but 0% municipal transfer tax
Example (Subtotal $100.00, Municipal 0%, Ounces 0.25):
- State sales tax (6.625%): $6.63
- Municipal transfer tax (0%): $0.00
- SEEF ($2.50/oz): $0.63
- Total: $107.26
These side-by-side examples show why a municipal selector matters: the state sales tax stays fixed at 6.625% (per Alloy Silverstein), but the local transfer tax can move from 0% to 2% (per the same source), changing the total.
Using the Calculator for Pricing, Menus, and Compliance (Practical Tips)
An NJ Dispensary Tax Calculator — interactive: 6.625% state sales tax, 0–2% municipal transfer tax selector, SEEF $2.50/oz pass-through, 280E line is most useful when it supports decisions—pricing, menu transparency, and back-office reporting—using the correct NJ inputs.
Tip 1: Treat the municipal transfer tax as a setting, not a constant
NJ allows a transfer tax up to 2% (per Alloy Silverstein), and tax summaries present the combined state + local range as 6.625% to 8.625% (per The Library NJ). Operationally, that means:
- If you run one location, set the selector default to your municipality’s rate.
- If you run multiple locations, store the rate per store and have the calculator switch automatically based on location.
Tip 2: Keep SEEF as a per-ounce line (don’t hide it in a percentage)
SEEF is a flat-dollar excise amount calculated per ounce, with NJ guidance stating $2.50/oz for 2026 (see TC Advisors CPA). Because it’s not a percent, showing it as a separate line item makes the math easier to audit and explain.
If you want to label it as a “SEEF pass-through” in your tool, keep the number and unit clear: $2.50 × ounces (also consistent with “Multiply ounces sold by $2.50” style instructions shown in NJ cannabis tax calculation guides like CannabisCPA.tax).
Tip 3: Build receipts and menu pricing around the known range
Since the combined rate is often summarized as 6.625% to 8.625% depending on municipal tax (per The Library NJ), you can price and message more clearly by:
- Displaying “estimated taxes” with a breakdown (state sales tax, municipal transfer tax, and SEEF).
- Using the municipal selector in customer-facing calculators so shoppers can see how the local rate affects totals.
Tip 4: Add an internal “280E line” for bookkeeping visibility
NJ-focused cannabis tax/accounting guidance highlights the relevance of 280E in the same conversation as NJ excise obligations like SEEF (see NJ Cannabis Business Tax Guide 2026: 280E & SEEF). Without changing the shopper’s checkout total, your calculator can include an internal-only line or note labeled “280E” to help your team flag transactions for 280E-related reporting workflows.
Feature Checklist: Building a Reliable Interactive NJ Dispensary Tax Calculator
If you’re evaluating an online widget or building your own, use this checklist to keep it aligned with the NJ numbers cited by established NJ cannabis tax sources.
Core calculation rules (should be non-negotiable)
- State sales tax locked to 6.625% (per Alloy Silverstein).
- Municipal transfer tax selectable from 0% to 2% (NJ can charge up to 2% per Alloy Silverstein).
- SEEF calculated per ounce at the cited 2026 level of $2.50/oz (per TC Advisors CPA and NJ tax roundups like CannabisPromotions).
Usability features that reduce mistakes
- Clear labeling: “NJ state sales tax (6.625%),” “municipal transfer tax (0–2%),” and “SEEF ($2.50/oz in 2026).”
- Rounding rules: show cents rounding consistently in the output (important for customer trust and invoice clarity).
- Breakdown view: subtotal, each tax/fee line, and total—so users can verify each component against published NJ rates.
Best-practice transparency (good for customers and staff)
- Show the combined percentage range somewhere in the UI: 6.625% to 8.625% before SEEF, matching NJ summaries (per The Library NJ).
- Include a citation/help link near SEEF noting the 2026 value is $2.50/oz (per TC Advisors CPA).
Used correctly, this kind of calculator gives you fast, repeatable estimates while staying consistent with NJ references that cite the same pillars: 6.625% sales tax, up to 2% municipal transfer tax, and SEEF at $2.50/oz in 2026 (see Alloy Silverstein, The Library NJ, and TC Advisors CPA).
Frequently Asked Questions
What taxes should an NJ dispensary tax calculator include for adult-use sales?
NJ adult-use tax summaries typically include 6.625% state sales tax (per Alloy Silverstein), a municipal transfer tax up to 2% (also per Alloy Silverstein), and the Social Equity Excise Fee (SEEF), which NJ accounting/tax guidance lists as $2.50 per ounce for 2026 (per TC Advisors CPA).
What is the NJ municipal transfer tax rate range?
NJ references describe a transfer tax that can be up to 2% on recreational cannabis sales (per Alloy Silverstein). That’s why an interactive calculator should offer a selector from 0% to 2%.
How much is the SEEF in New Jersey for 2026?
The NJ Social Equity Excise Fee (SEEF) is cited as $2.50 per ounce of usable recreational cannabis for 2026 (per TC Advisors CPA). NJ tax rate summaries also reflect SEEF as a separate component alongside sales and local transfer tax (see CannabisPromotions).
What is the total NJ tax rate on recreational cannabis?
New Jersey adult-use summaries commonly present the combined rate as 6.625% to 8.625%, reflecting 6.625% state sales tax plus up to 2% municipal transfer tax (per The Library NJ). SEEF is then added separately as a per-ounce dollar amount (for 2026, $2.50/oz per TC Advisors CPA).
Why include a “280E line” in an NJ dispensary tax calculator?
NJ cannabis accounting guidance specifically discusses 280E along with NJ-specific fees like SEEF (see NJ Cannabis Business Tax Guide 2026: 280E & SEEF). Adding a “280E line” to your calculator can help your team separate internal reporting notes from the customer-facing tax breakdown while keeping the core NJ checkout math focused on the published NJ rates and fees.
If you want, share your municipality and a sample cart (subtotal and ounces), and you can validate whether your current POS/online tool matches the correct NJ inputs: 6.625% state sales tax, 0–2% municipal transfer tax, and SEEF $2.50/oz (2026).



















