Is there a way to print cheques in manager? If so, how do you write the code to do it.
You can do it with a classic custom theme. Code has previously been posted on the forum. Be aware that custom themes are considered obsolete, however and have been announced as headed for removal from the program.
I am aware that custom themes will be gone at some point as the developer has stated that something new is in the works. I hope consideration will be given to the topic of this post as I would like to join @finetune with the request for check printing well.
Personally, I think you are unlikely to see this capability added. Cheque layout varies widely by country and by bank. Anti-forgery measures are often included, which Manager obviously could not include. Printing on blank, but serialized, forms is very difficult to standardize. Further, there is great mismatch between data on a cheque and content of a payment transaction. Ultimately, this would be quite difficult to implement for general use.
You should not believe the developer has never considered this subject.
I’m new here because I hate Intuit and Microsoft and am trying Manager (V26.1.21.3171) out. I used MYOB for years but was forced out because of Windows updates. Then I used QuickBooks and am now being forced out because of Inuit’s greed. Which brings me to the point that I miss being able to print checks, and by that I mean filling in preprinted checks, not actually printing the entire check on a blank sheet of paper. I have read as many of the check printing threads as I can stand and found that check printing was promised in 2015 but failed to appear. Then in February 2021 VISA-MC posted code for a custom theme, in April 2022 Mark showed that it worked (V22.3.3), and in June 2023 Tut posted that custom themes had been removed, and that printing checks was too complicated. I’m guessing that Tut refers to printing the entire check on blank paper as I was (filing in) printing checks 40 years ago. It can’t be that hard to program… I understand that you can’t satisfy everyone but let’s start somewhere. One check and two vouchers sound kind of popular. My concern is the errors inherent in hand writing checks and then entering them in Manager. Or am I missing something?
I agree with you, RandiB. I believe the ability to fill out a preprinted cheque is, hopefully, what most people are looking for. I would not be looking to print an entire cheque on a blank piece of paper. I don’t understand what security issues would be involved if you are just filling out a pre printed cheque. This would be a fairly standard way of printing checks (cheques) in the US.
Hello all. I’ve been wanting a simple, voucher style 3 part check/cheque template that I can use for pre-printed check stock (USA based). The check prints on the top part, the 2nd and 3rd part of vouchers. It is an extremely common business/computer style format in the USA.
I’ve gone ahead and created a theme to print 3 part/voucher style checks. It works for me as of early 2026.
Copy the code below and paste it into a theme. In the payments section, for a specific payment, I just select the option Custom theme and select Voucher check (or whatever you called the theme).
And yes, I know Custom Theme is scheduled to go away so enjoy while it lasts.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
@page {
size: 8.5in 11in;
margin: 0;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 8.5in;
height: 11in;
font-family: 'Arial', 'Times New Roman', serif;
font-size: 12px;
position: relative;
margin: 0;
padding: 0;
background: white;
}
/* Hide any inherited Manager.io template elements */
header, #title, #business-logo, #recipient-info, #fields, #business-info,
#description, #table-headers, #table-rows, #custom-fields, #footers, #status, #qrcode {
display: none !important;
visibility: hidden !important;
}
.check-section {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3.5in;
}
.date-line {
position: absolute;
top: 45px;
right: 30px;
display: flex;
align-items: center;
}
.date-label {
font-size: 11px;
margin-right: 8px;
}
.date-value {
border-bottom: 1px solid #000;
padding: 2px 8px;
min-width: 120px;
text-align: right;
font-weight: bold;
}
.payee-line {
position: absolute;
top: 95px;
left: 30px;
right: 30px;
display: flex;
align-items: flex-end;
}
.payee-label {
font-size: 11px;
margin-right: 5px;
white-space: nowrap;
}
.payee-underline {
flex: 1;
border-bottom: 1px solid #000;
padding: 2px 8px;
min-height: 20px;
}
.amount-box {
width: 120px;
border: 2px solid #000;
padding: 8px 8px 4px 8px;
text-align: right;
font-weight: bold;
font-size: 14px;
flex-shrink: 0;
display: flex;
align-items: center;
height: 32px;
}
.dollar-symbol {
font-size: 14px;
margin-right: 4px;
}
.amount-words-line {
position: absolute;
top: 140px;
left: 30px;
right: 80px;
display: flex;
align-items: baseline;
border-bottom: 2px solid #000;
padding-bottom: 4px;
}
.amount-words-text {
padding-right: 8px;
white-space: nowrap;
}
.amount-words-dotted-line {
flex: 1;
border-bottom: 2px dotted #000;
margin-bottom: -4px;
min-width: 20px;
}
.dollars-label {
font-size: 11px;
margin-left: 5px;
white-space: nowrap;
}
.memo-line {
position: absolute;
bottom: 65px;
left: 30px;
}
.memo-label {
font-size: 10px;
margin-right: 8px;
}
.memo-value {
display: inline-block;
border-bottom: 1px solid #000;
min-width: 250px;
padding: 2px 8px;
}
.signature-section {
position: absolute;
bottom: 65px;
right: 30px;
}
.signature-line {
border-bottom: 1px solid #000;
width: 220px;
}
.signature-label {
font-size: 9px;
font-style: italic;
text-align: center;
}
.perforation {
position: absolute;
left: 15px;
right: 15px;
height: 0;
border-top: 3px dashed #999;
}
.voucher-section {
position: absolute;
left: 0;
right: 0;
background: #fafafa;
}
.voucher-1 {
top: 3.5in;
height: 3.75in;
border-top: 1px solid #000;
border-bottom: 1px solid #000;
}
.voucher-2 {
bottom: 0;
height: 3.75in;
border-top: 1px solid #000;
}
.voucher-header {
background: #e8e8e8;
padding: 10px 15px;
border-bottom: 2px solid #000;
font-weight: bold;
font-size: 12px;
display: flex;
justify-content: space-between;
align-items: center;
}
.voucher-content {
padding: 15px;
}
.voucher-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
margin-bottom: 15px;
}
.voucher-field {
display: flex;
flex-direction: column;
}
.voucher-field label {
font-size: 9px;
color: #666;
text-transform: uppercase;
margin-bottom: 3px;
font-weight: bold;
}
.voucher-field .value {
border-bottom: 1px solid #ccc;
padding: 4px 8px;
font-family: 'Courier New', monospace;
font-size: 11px;
min-height: 20px;
background: white;
}
.voucher-table {
width: 100%;
border-collapse: collapse;
font-size: 10px;
margin-bottom: 10px;
}
.voucher-table th,
.voucher-table td {
border: 1px solid #000;
padding: 6px 8px;
text-align: left;
}
.voucher-table th {
background: #e0e0e0;
font-weight: bold;
text-transform: uppercase;
font-size: 9px;
}
.voucher-table .amount {
text-align: right;
font-family: 'Courier New', monospace;
}
.notes-area {
margin-top: 10px;
}
.notes-area label {
font-size: 9px;
color: #666;
text-transform: uppercase;
font-weight: bold;
display: block;
margin-bottom: 5px;
}
.notes-area .lines {
border: 1px solid #ddd;
padding: 8px;
min-height: 50px;
background: repeating-linear-gradient(
to bottom,
transparent,
transparent 17px,
#ddd 17px,
#ddd 18px
);
}
</style>
</head>
<body>
<!-- CHECK SECTION -->
<div class="check-section">
<!-- Date -->
<div class="date-line">
<span class="date-label">Date:</span>
<span class="date-value" id="check-date"></span>
</div>
<!-- Payee Line -->
<div class="payee-line">
<span class="payee-label">Pay to the Order Of:</span>
<div class="payee-underline" id="payee-name"></div>
<div class="amount-box"><span class="dollar-symbol">$</span><span id="amount-numeric"></span></div>
</div>
<!-- Amount in Words -->
<div class="amount-words-line">
<span class="amount-words-text" id="amount-words"></span>
<span class="amount-words-dotted-line"></span>
<span class="dollars-label">Dollars</span>
</div>
<!-- Memo -->
<div class="memo-line">
<span class="memo-label">Memo:</span>
<span class="memo-value" id="memo-text"></span>
</div>
<!-- Signature -->
<div class="signature-section">
<div class="signature-line"></div>
<div class="signature-label">Authorized Signature</div>
</div>
</div>
<div class="perforation" style="top: 3.5in;"></div>
<!-- VOUCHER 1 -->
<div class="voucher-section voucher-1">
<div class="voucher-header">
<span>PAYMENT VOUCHER</span>
<span id="voucher1-checknum"></span>
</div>
<div class="voucher-content">
<div class="voucher-grid">
<div class="voucher-field">
<label>Date</label>
<div class="value" id="voucher1-date"></div>
</div>
<div class="voucher-field">
<label>Check Number</label>
<div class="value" id="voucher1-number"></div>
</div>
<div class="voucher-field">
<label>Pay To</label>
<div class="value" id="voucher1-payee"></div>
</div>
<div class="voucher-field">
<label>Amount</label>
<div class="value" id="voucher1-amount"></div>
</div>
<div class="voucher-field" style="grid-column: 1 / -1;">
<label>Memo / Description</label>
<div class="value" id="voucher1-memo"></div>
</div>
</div>
<table class="voucher-table">
<thead>
<tr>
<th>Account</th>
<th>Description</th>
<th class="amount">Amount</th>
</tr>
</thead>
<tbody id="voucher1-rows">
<!-- Rows will be inserted here -->
</tbody>
</table>
</div>
</div>
<div class="perforation" style="top: 7.25in;"></div>
<!-- VOUCHER 2 -->
<div class="voucher-section voucher-2">
<div class="voucher-header">
<span>PAYMENT VOUCHER - RECORD COPY</span>
<span id="voucher2-checknum"></span>
</div>
<div class="voucher-content">
<div class="voucher-grid">
<div class="voucher-field">
<label>Date</label>
<div class="value" id="voucher2-date"></div>
</div>
<div class="voucher-field">
<label>Check Number</label>
<div class="value" id="voucher2-number"></div>
</div>
<div class="voucher-field">
<label>Pay To</label>
<div class="value" id="voucher2-payee"></div>
</div>
<div class="voucher-field">
<label>Amount</label>
<div class="value" id="voucher2-amount"></div>
</div>
<div class="voucher-field" style="grid-column: 1 / -1;">
<label>Memo / Description</label>
<div class="value" id="voucher2-memo"></div>
</div>
</div>
<table class="voucher-table">
<thead>
<tr>
<th>Account</th>
<th>Description</th>
<th class="amount">Amount</th>
</tr>
</thead>
<tbody id="voucher2-rows">
<!-- Rows will be inserted here -->
</tbody>
</table>
<div class="notes-area">
<label>Notes</label>
<div class="lines"></div>
</div>
</div>
</div>
<script>
function sendResize() {
window.parent.postMessage({
type: "resize",
width: document.documentElement.scrollWidth + 1,
height: document.documentElement.scrollHeight + 1
}, "*");
}
window.addEventListener("message", (event) => {
if (event.source !== window.parent) return;
if (event.data.type !== 'context-response') return;
const data = event.data.body;
// Extract data using Manager.io's postMessage API
const recipient = data.recipient || {};
const fields = data.fields || [];
const totals = data.table?.totals || [];
const rows = data.table?.rows || [];
// Find date field
const dateField = fields.find(f =>
f.label && f.label.toLowerCase().includes('date')
);
const dateValue = dateField?.text || '';
// Find check number field
const numberField = fields.find(f =>
f.label && (f.label.toLowerCase().includes('number') ||
f.label.toLowerCase().includes('reference') ||
f.label.toLowerCase().includes('check'))
);
const numberValue = numberField?.text || '';
// Find amount from totals
const amountTotal = totals.find(t => t.key === 'Total') || totals[totals.length - 1];
const amountValue = amountTotal?.text || '';
// Populate CHECK section
document.getElementById('check-date').textContent = dateValue;
document.getElementById('payee-name').textContent = recipient.name || '';
// Remove $ from amount value if present, since $ is already in HTML
let cleanAmount = amountValue.replace(/^\$/, '').replace(/^USD/, '').trim();
document.getElementById('amount-numeric').textContent = cleanAmount;
document.getElementById('memo-text').textContent = data.description || '';
// Amount in words - convert numeric amount to words
document.getElementById('amount-words').textContent = numberToWords(cleanAmount);
// Populate VOUCHER 1
document.getElementById('voucher1-checknum').textContent = numberValue ? 'Check #' + numberValue : '';
document.getElementById('voucher1-date').textContent = dateValue;
document.getElementById('voucher1-number').textContent = numberValue;
document.getElementById('voucher1-payee').textContent = recipient.name || '';
document.getElementById('voucher1-amount').textContent = amountValue;
document.getElementById('voucher1-memo').textContent = data.description || '';
// Populate VOUCHER 1 table rows
const voucher1Rows = document.getElementById('voucher1-rows');
voucher1Rows.innerHTML = '';
rows.forEach(row => {
const tr = document.createElement('tr');
const cells = row.cells || [];
// Account name (usually first column)
const accountName = cells[0]?.text || cells[0]?.account?.name || '';
// Description (usually second or third column)
const description = cells[1]?.text || cells[2]?.text || '';
// Amount (usually last column)
const amount = cells[cells.length - 1]?.text || '';
tr.innerHTML = `
<td>${accountName}</td>
<td>${description}</td>
<td class="amount">${amount}</td>
`;
voucher1Rows.appendChild(tr);
});
// Add total row to Voucher 1
if (amountValue) {
const totalRow = document.createElement('tr');
totalRow.innerHTML = `
<td colspan="2" style="font-weight: bold; text-align: right;">Total Payment:</td>
<td class="amount" style="font-weight: bold;">${amountValue}</td>
`;
voucher1Rows.appendChild(totalRow);
}
// Populate VOUCHER 2
document.getElementById('voucher2-checknum').textContent = numberValue ? 'Check #' + numberValue : '';
document.getElementById('voucher2-date').textContent = dateValue;
document.getElementById('voucher2-number').textContent = numberValue;
document.getElementById('voucher2-payee').textContent = recipient.name || '';
document.getElementById('voucher2-amount').textContent = amountValue;
document.getElementById('voucher2-memo').textContent = data.description || '';
// Populate VOUCHER 2 table rows
const voucher2Rows = document.getElementById('voucher2-rows');
voucher2Rows.innerHTML = '';
rows.forEach(row => {
const tr = document.createElement('tr');
const cells = row.cells || [];
const accountName = cells[0]?.text || cells[0]?.account?.name || '';
const description = cells[1]?.text || cells[2]?.text || '';
const amount = cells[cells.length - 1]?.text || '';
tr.innerHTML = `
<td>${accountName}</td>
<td>${description}</td>
<td class="amount">${amount}</td>
`;
voucher2Rows.appendChild(tr);
});
// Add total row to Voucher 2
if (amountValue) {
const totalRow = document.createElement('tr');
totalRow.innerHTML = `
<td colspan="2" style="font-weight: bold; text-align: right;">Total Payment:</td>
<td class="amount" style="font-weight: bold;">${amountValue}</td>
`;
voucher2Rows.appendChild(totalRow);
}
sendResize();
}, false);
window.addEventListener("load", () => {
window.parent.postMessage({ type: "context-request" }, "*");
});
// Number to words converter function
function numberToWords(amount) {
// Parse amount string like "76.46"
const match = amount.match(/^(\d+\.?\d*)$/);
if (!match) return amount; // Return as-is if not a number
const parts = amount.split('.');
const dollars = parseInt(parts[0]) || 0;
const cents = parts[1] ? parseInt(parts[1]) : 0;
// Convert dollars to words
const ones = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine',
'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen',
'Seventeen', 'Eighteen', 'Nineteen'];
const tens = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];
function convertHundreds(num) {
if (num === 0) return '';
let words = '';
if (num >= 100) {
words += ones[Math.floor(num / 100)] + ' Hundred ';
num %= 100;
}
if (num >= 20) {
words += tens[Math.floor(num / 10)] + ' ';
num %= 10;
}
if (num > 0) {
words += ones[num] + ' ';
}
return words.trim();
}
let result = '';
if (dollars === 0) {
result = 'Zero';
} else if (dollars < 20) {
result = ones[dollars];
} else if (dollars < 100) {
result = tens[Math.floor(dollars / 10)];
if (dollars % 10 > 0) {
result += ' ' + ones[dollars % 10];
}
} else {
result = convertHundreds(dollars);
}
// Add cents
if (cents > 0) {
const centsStr = cents.toString().padStart(2, '0');
result += ' and ' + centsStr + '/100';
}
return result;
}
</script>
</body>
</html>
I thought cheques would be obsolete in most places by now. Last cheque I filled out was well over 8 years ago.
According to the Federal Reserve (the US central bank), nearly 80% of small businesses in the United States still use paper checks (cheques), 66% medium and large businesses still use paper checks. This is 2024 data.