{
"success": false,
"message": "Failed to connect to local FBRIMS service: Network error: NetworkError when attempting to fetch resource.. Check if FBRIMS service is running and accessible."
}
Ah, I have just realized that you are conducting a test for the local sandbox with FBRIMS. Perhaps you could try using Postman to ensure that the FBRIMS server is operating on your local computer.
You may also directly enter the URL endpoint in your browser to ascertain whether the IMS Fiscal service is operational on your computer.
http://localhost:8524/api/IMSFiscal/get
will do that for confirmation.
The system functions well for the local Sandbox,
Yet it currently lacks support for multiple computers, as only one POS ID is stored in the Manager Business Details and it operates solely for one FBR IMS.
Each FBR IMS can only be utilized for a single POS ID.
What would you suggest?
Should the POS ID be configured at the time of Invoice Creation to align with each userβs computer?
In my point of view it should be aligned to each user computer.
Basically, you are right. However, in my opinion, the FBR POS should not be installed separately in a way that creates isolated data for each system. Instead, each POS should be installed individually, but all systems must reflect data in one single business.
For example, we are running a mart with 4 POS counters and 4 separate systems. If we install Manager individually on each system and integrate them one by one, the actual business picture is not properly reflectedβespecially for inventory. One system may show stock in hand, while another may show the same item as out of stock. This creates confusion and inaccurate reporting.
The better solution would be to install Manager.io Server Edition so that all 4 systems access the same centralized business database. In this way, inventory, sales, and overall financial data will be updated in real time across all counters.
As per Federal Board of Revenue (FBR) rules, if we have 4 systems, we are required to install 4 FBR POS integrations, as already shown in the image. Therefore, we need to discuss what solution would be most suitable in this case. For a single counter, the current setup is working fine so far.
The modifications I require are:
-
The FBR logo should be displayed on the invoice, similar to digital invoicing requirements.
-
Invoices should be submitted through a βDigital Invoicingβ button at the bottom.
-
Sometimes, we create invoices during the day but want the option to submit all invoices in bulk at once through your designated digital invoicing feature.
-
The invoice template should be professionally designed, similar to the format commonly used by marts.
in short the process of submission of invoice must be same like a digital invoice extension.
@Abdul_Qadir_Arif what directory is this message coming forΫ
All business files are located in the directory I am using, i.e., Documents/Manager.io.
Okz, what about the cloudβ¦
I have not tested it on the cloud yet. I will test it today and let you know.
On certain computers, the FBRIMS application is unable to access C:\Program Files (x86)\PRAL for database initialization according to the POS ID and Access Code.
The best approach is to select βCustomβ during the installation of FMBIMS, possibly on drive D, or in a Data Folder as demonstrated by @Abdul_Qadir_Arif.
FBR POS Extension Update
- Multi-User and Cloud Submission Support
- POS ID is now included in Sales Invoices and Credit Notes.
- Each user must select the POS ID corresponding to their own computer.
- All registered POS IDs must be manually added into the dropdown list in the POS ID custom field.
- Debit Note Handling
- Debit Notes should still be created using a Sales Invoice by selecting Invoice Type 2. Debit.
- The Ref USIN field must be filled in manually, referencing the Sales Invoice or Credit Note that needs to be debited.
- QRCode Image Custom Field
- The QRCode Image custom field now contains a combination of the FBR POS Logo and the QR Code.
- USIN Prefix by Document Type
- A prefix has been added to the USIN according to the type of document.
Working Perfect. ![]()
one more thing, In my opinion, the theme of FBR-POS should be thermal paper.
You can start from this AI generated Codes
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
@page { size: 58mm auto; margin: 0; }
*, ::after, ::before { margin: 0; padding: 0; box-sizing: border-box; border: 0 solid; }
body {
font-family: Consolas, 'Courier New', monospace;
font-size: 11px; line-height: 1.4; color: #111;
width: 58mm; padding: 4mm 3mm;
}
@media print { body { padding: 2mm 3mm; } }
/* Header */
#header { text-align: center; margin-bottom: 3px; }
#business-logo img { max-width: 46mm; max-height: 15mm; display: block; margin: 0 auto 3px; }
#business-name { font-size: 14px; font-weight: bold; text-transform: uppercase; letter-spacing: .5px; }
#business-address { font-size: 10px; color: #555; margin-top: 1px; }
#title { font-size: 11px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; margin-top: 4px; }
#description { font-size: 10px; color: #444; margin-top: 2px; }
/* Dividers */
.div { border: none; border-top: 1px dashed #aaa; margin: 4px 0; }
.div-solid { border: none; border-top: 1px solid #111; margin: 4px 0; }
/* Fields */
#fields { font-size: 11px; margin-bottom: 2px; }
#fields .row { display: flex; justify-content: space-between; gap: 4px; padding: 1px 0; }
#fields .lbl { color: #555; flex: 1; }
#fields .val { font-weight: bold; text-align: right; }
/* Recipient */
#recipient-section { margin-bottom: 3px; text-align: center; }
#recipient-section > small { font-size: 9px; text-transform: uppercase; color: #777; letter-spacing: .4px; }
#recipient-name { font-size: 11px; font-weight: bold; }
#recipient-detail { font-size: 10px; color: #555; }
/* Items table β 3 col: Item | Qty | Total */
#items-table { width: 100%; border-collapse: collapse; font-size: 9.5px; }
#items-table th {
font-size: 10px; font-weight: bold; text-transform: uppercase; color: #444;
padding: 2px 1px; white-space: nowrap;
border-top: 1px solid #111; border-bottom: 1px solid #111;
}
#items-table td { padding: 2px 1px; vertical-align: top; text-align: right; }
#items-table tr.item-row td { border-bottom: 1px dotted #ddd; }
.col-item { text-align: left !important; word-break: break-word; line-height: 1.3; }
.col-qty { text-align: center !important; width: 18px; }
.col-total { font-weight: bold; width: 30px; }
/* Column totals */
#items-table tr.col-total td {
font-size: 10px; font-weight: bold; text-align: right;
white-space: nowrap; border-top: 1px solid #111; padding: 2px 1px;
}
/* Invoice totals */
#items-table tr.total td { font-size: 10px; white-space: nowrap; text-align: right; padding: 1px; }
#items-table tr.total td:first-child { color: #555; }
#items-table tr.total.emphasis td {
font-size: 11px; font-weight: bold;
border-top: 1px solid #111; padding-top: 3px;
}
/* Tax breakdown table */
#tax-breakdown { width: 100%; border-collapse: collapse; font-size: 9px; margin-top: 3px; }
#tax-breakdown thead th {
font-size: 9px; font-weight: bold; text-transform: uppercase; color: #777;
padding: 1px; border-bottom: 1px dashed #aaa; text-align: right;
}
#tax-breakdown thead th:first-child { text-align: left; }
#tax-breakdown td { padding: 1px; text-align: right; color: #444; }
#tax-breakdown td:first-child { text-align: left; font-weight: bold; }
/* Custom fields */
#custom-fields { margin-top: 4px; font-size: 10px; text-align: center; }
#custom-fields .cf-lbl { font-size: 9px; font-weight: bold; text-transform: uppercase; color: #777; letter-spacing: .3px; }
#custom-fields .cf-val { font-size: 10px; word-break: break-all; margin-bottom: 4px; }
#custom-fields .cf-qr { text-align: center; margin: 3px 0 5px; }
#custom-fields .cf-qr img { max-width: 35mm; width: 35mm !important; height: auto !important; image-rendering: pixelated; display: block; margin: 0 auto; }
/* Amount in words */
#amount-in-words { display: none; font-size: 10px; margin-top: 4px; border-top: 1px dashed #aaa; padding-top: 3px; text-align: center; }
#amount-in-words strong { font-size: 9px; text-transform: uppercase; color: #666; display: block; margin-bottom: 1px; }
/* Footers & bottom */
#footers { font-size: 11px; margin-top: 4px; }
#receipt-footer { text-align: center; margin-top: 6px; padding-top: 4px; border-top: 1px dashed #aaa; font-size: 9px; color: #888; }
</style>
</head>
<body>
<div id="header">
<div id="business-logo"></div>
<div id="business-name"></div>
<div id="business-address"></div>
<div id="title"></div>
<div id="description"></div>
</div>
<hr class="div-solid" />
<div id="fields"></div>
<hr class="div" />
<div id="recipient-section">
<small>Bill To</small>
<div id="recipient-name"></div>
<div id="recipient-detail"></div>
</div>
<hr class="div" />
<!-- 3-col items table -->
<table id="items-table">
<thead><tr id="table-headers"></tr></thead>
<tbody id="table-rows"></tbody>
</table>
<!-- Tax breakdown per tax code -->
<table id="tax-breakdown" style="display:none">
<thead>
<tr>
<th style="text-align:left">Tax</th>
<th>Taxable</th>
<th>Tax Amt</th>
</tr>
</thead>
<tbody id="tax-rows"></tbody>
</table>
<div id="custom-fields"></div>
<div id="amount-in-words"></div>
<div id="footers"></div>
<div id="receipt-footer">*** Thank You ***</div>
<script src="resources/writtennumber/writtennumber.js"></script>
<script>
const $ = id => document.getElementById(id);
function sendResize() {
window.parent.postMessage({
type: 'resize',
width: document.documentElement.scrollWidth + 1,
height: document.documentElement.scrollHeight + 1
}, '*');
}
function el(tag, { cls, html, text, colSpan, id, dataset } = {}) {
const e = document.createElement(tag);
if (cls) e.className = cls;
if (html) e.innerHTML = html;
if (text) e.textContent = text;
if (colSpan) e.colSpan = colSpan;
if (id) e.id = id;
if (dataset) Object.assign(e.dataset, dataset);
return e;
}
function addField(parent, label, value) {
parent.insertAdjacentHTML('beforeend',
`<div class="row"><span class="lbl">${label}</span><span class="val">${value}</span></div>`);
}
function colIdx(cols, ...labels) {
return cols.findIndex(c => labels.includes((c.label || '').toLowerCase()));
}
// ββ Build tax breakdown from rows ββββββββββββββββββββββββββββββββββββββ
// Groups by tax code, sums taxable amount and tax amount per code
function buildTaxBreakdown(rows, fullCols) {
const taxI = colIdx(fullCols, 'tax', 'vat', 'gst');
const amtI = colIdx(fullCols, 'amount');
const taxAmtI = colIdx(fullCols, 'tax amount');
if (taxI < 0 || amtI < 0 || taxAmtI < 0) return [];
const map = new Map();
rows.forEach(row => {
const code = row.cells[taxI]?.text || '';
const amt = row.cells[amtI]?.value || 0;
const taxAmt = row.cells[taxAmtI]?.value || 0;
if (!code) return;
const entry = map.get(code) || { taxable: 0, taxAmt: 0 };
entry.taxable += amt;
entry.taxAmt += taxAmt;
map.set(code, entry);
});
return [...map.entries()].map(([code, v]) => ({
code,
taxable: v.taxable.toFixed(2),
taxAmt: v.taxAmt.toFixed(2),
}));
}
// ββ Amount-in-words ββββββββββββββββββββββββββββββββββββββββββββββββββββ
function spellRupeeLike(n, unit, subunit, single) {
const fr = Math.round(n * 100) % 100;
return spellOutRupees(n) + ' ' + unit +
(fr === 0 ? ' Only' : fr === 1 ? ` and One ${single}` : ` and ${spellOutRupees(fr)} ${subunit}`);
}
function renderAmountInWords(aiw, totals) {
const entry = [...(totals || [])].reverse().find(t => t.key === 'Total');
if (!entry) return;
const n = entry.number;
let text;
if (aiw.currencyPrefix === 'βΉ' || aiw.currencyCode === 'INR')
text = spellRupeeLike(n, 'Rupees', 'Paise', 'Paisa');
else if (aiw.currencyPrefix === 'ΰ§³' || aiw.currencyCode === 'BDT')
text = spellRupeeLike(n, 'Taka', 'Paise', 'Paisa');
else {
const mult = 10 ** aiw.decimalPlaces;
let wn = writtenNumber(Math.floor(n), { language: aiw.language, currency: aiw.currencyCode });
if (wn) wn = wn[0].toUpperCase() + wn.slice(1);
const fr = Math.round(n * mult) % mult;
text = wn + (fr > 0 ? ` ${aiw.andText} ${fr}/${'1' + '0'.repeat(aiw.decimalPlaces)}` : '');
}
if (text) {
const div = $('amount-in-words');
div.style.display = 'block';
div.innerHTML = `<strong>${aiw.label}</strong>${text}`;
}
sendResize();
}
// ββ Main βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
window.addEventListener('message', ({ source, data: msg }) => {
if (source !== window.parent || msg.type !== 'context-response') return;
const d = msg.body;
document.documentElement.dir = d.direction || 'ltr';
document.title = [d.business?.name, d.title, d.reference].filter(Boolean).join(' - ');
// Logo
if (d.business?.logo) {
const img = Object.assign(document.createElement('img'), { src: d.business.logo });
img.addEventListener('load', sendResize);
$('business-logo').appendChild(img);
}
// Header
$('business-name').textContent = d.business?.name || '';
$('business-address').innerHTML = (d.business?.address || '').replace(/\n/g, '<br>');
$('title').textContent = (d.title || '').toUpperCase();
$('description').textContent = d.description || '';
// Fields
const fieldsDiv = $('fields');
fieldsDiv.innerHTML = '';
(d.fields || []).forEach(f => addField(fieldsDiv, f.label, f.text));
// Recipient
$('recipient-name').textContent = d.recipient?.name || '';
$('recipient-detail').innerHTML = [d.recipient?.code, d.recipient?.address]
.filter(Boolean).join('<br>');
// ββ 3-col table: Item | Qty | Total βββββββββββββββββββββββββββββββββββ
const fullCols = d.table.columns || [];
const qtyI = colIdx(fullCols, 'pce', 'qty', 'quantity');
const itemI = colIdx(fullCols, 'item', 'description', 'product');
const totalI = fullCols.findIndex(c => c.alwaysShow) !== -1
? fullCols.findIndex(c => c.alwaysShow)
: colIdx(fullCols, 'total');
const condensed = [
{ label: 'Item', cls: 'col-item', srcI: itemI !== -1 ? itemI : 1, sumText: null },
{ label: fullCols[qtyI]?.label || 'Qty', cls: 'col-qty', srcI: qtyI, sumText: fullCols[qtyI]?.sumText || null },
{ label: fullCols[totalI]?.label || 'Total', cls: 'col-total', srcI: totalI, sumText: fullCols[totalI]?.sumText || null },
];
// Headers
const thead = $('table-headers');
thead.innerHTML = '';
condensed.forEach(c => thead.appendChild(el('th', { cls: c.cls, text: c.label })));
// Rows
const tbody = $('table-rows');
tbody.innerHTML = '';
(d.table.rows || []).forEach(row => {
const tr = el('tr', { cls: 'item-row' });
condensed.forEach(col => {
tr.appendChild(el('td', {
cls: col.cls,
html: row.cells[col.srcI]?.text || ''
}));
});
tbody.appendChild(tr);
});
// Column totals
const ctTr = el('tr', { cls: 'col-total' });
let hasCT = false;
condensed.forEach(c => {
const td = el('td', { cls: c.cls });
if (c.sumText) { td.textContent = c.sumText; hasCT = true; }
ctTr.appendChild(td);
});
if (hasCT) tbody.appendChild(ctTr);
// Invoice totals β only show emphasis row (grand total), skip sub-total & tax rows
(d.table.totals || []).filter(t => t.emphasis).forEach(t => {
const tr = el('tr', { cls: 'total' + (t.emphasis ? ' emphasis' : '') });
tr.appendChild(el('td', { text: t.label, colSpan: condensed.length - 1 }));
const tdVal = el('td', { html: t.text, id: t.key || '', dataset: { value: t.number } });
if (t.class) tdVal.classList.add(t.class);
tr.appendChild(tdVal);
tbody.appendChild(tr);
});
// ββ Tax breakdown ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
const taxData = buildTaxBreakdown(d.table.rows || [], fullCols);
if (taxData.length) {
const taxTbody = $('tax-rows');
taxTbody.innerHTML = '';
taxData.forEach(({ code, taxable, taxAmt }) => {
taxTbody.insertAdjacentHTML('beforeend',
`<tr>
<td>${code}</td>
<td>${taxable}</td>
<td>${taxAmt}</td>
</tr>`);
});
$('tax-breakdown').style.display = 'table';
}
// Custom fields
const cfDiv = $('custom-fields');
cfDiv.innerHTML = '';
(d.custom_fields || []).forEach(f => {
if (f.displayAtTheTop) return addField(fieldsDiv, f.label, f.text);
const isImg = (f.text || '').includes('<img');
cfDiv.insertAdjacentHTML('beforeend',
`<div class="cf-lbl">${f.label}</div>
<div class="${isImg ? 'cf-qr' : 'cf-val'}">${
isImg ? f.text : (f.text || '').replace(/\n/g, '<br>')
}</div>`);
// Strip inline width/height from QR images so CSS can scale them properly
if (isImg) {
cfDiv.querySelectorAll('.cf-qr img').forEach(img => {
img.style.removeProperty('width');
img.style.removeProperty('height');
});
}
});
// Amount in words
if (d.amountInWords) {
const s = Object.assign(document.createElement('script'),
{ src: `resources/writtennumber/lang-${d.amountInWords.language}.js` });
s.onload = () => renderAmountInWords(d.amountInWords, d.table.totals);
document.head.appendChild(s);
}
// Footers
const footersDiv = $('footers');
footersDiv.innerHTML = '';
(d.footers || []).forEach(f => {
const div = Object.assign(document.createElement('div'), { innerHTML: f });
div.style.marginTop = '8px';
div.querySelectorAll('script').forEach(s => {
const ns = document.createElement('script');
[...s.attributes].forEach(a => ns.setAttribute(a.name, a.value));
ns.textContent = s.textContent;
s.replaceWith(ns);
});
footersDiv.appendChild(div);
});
sendResize();
});
window.addEventListener('load', () =>
window.parent.postMessage({ type: 'context-request' }, '*')
);
</script>
</body>
</html>
Thank you so much, brother. I have also checked at my end and everything seems to be working fine so far.
However, invoices are being submitted successfully, but my main concern is that the sandbox invoices are not reflecting in the Federal Board of Revenue (FBR) Sandbox portal. I will share a screenshot tomorrow after the lapse of 24 hours for your review.
Additionally, we would like to suggest a small improvement. Kindly consider adding a separate menu button in your forum titled βExtensions / Pluginsβ, where all developed extensions can be listed. This will make it much easier for users to search and access the available extensions.
@Mabaega Kindly check your inbox. I have also shared the details regarding the Punjab Revenue Authority (PRA) POS integration.
I believe this process is similar.
Thank you once again for your support.
Hey is there any guide to integrate FBR with Manager in layman terms or easy process without code knowledge
@fahadalarab You may coordinate privately with anyone necessary to assist with the solution and integration process.







