Skip to content

Invoice Templates

An invoice template is the HTML layout of the PDF invoice an account receives. Macros such as ${AMOUNT_DUE} are replaced with the account’s figures for the billing period, and table macros repeat a row for every call or charge. Each customer keeps its own templates; every account uses one of them. How and when invoices are issued is described in Invoicing.

Open Payments → Invoice Templates in the left sidebar. The URL is /invoice_templates.php. The item is available to admin and reseller logins that are not restricted by an access level.

Screenshot "admin-panel/invoice-templates" has not been generated yet — see scripts/screenshots/screens.yml.
Column Meaning
Name Template name, linking to the form
Description Free text
Action Trash icon to delete the template. Not shown for the system template

The filter matches Name with is like or is not like, case-insensitively and against the whole name; use % as a wildcard. The root customer also sees the system template Default Account Invoice. It is read-only, it is the default template of new accounts, and it is the best starting point for your own.

  1. Click Add Based on Existing.
  2. Select Base Template, for example Default Account Invoice. Name is filled in as Copy of …; change it.
  3. Click Proceed. The form opens with a copy of the layout and CSS.
  4. Edit the layout in the editor and the styles in CSS.
  5. Click Preview PDF to check the result.
  6. Click Save & Close.

Add New starts from an empty layout instead. Name is required and must be unique among your templates.

Basic Parameters holds Name and Description. Invoice Template holds CSS and the editor.

The editor is a visual HTML editor. Its toolbar has Insert Macro, which inserts any macro below and shows a short help for each, table tools, an image button, and a button that opens the HTML source. Edit the source for table macros: they must sit in rows of their own.

Preview PDF renders the current content of the editor, saved or not, with sample data and opens the PDF in a new window. To see an invoice with real figures, assign the template to a test account and use Generate Invoice (see Invoicing). Save and Save & Close are hidden for the system template.

Screenshot "admin-panel/invoice-template-form" has not been generated yet — see scripts/screenshots/screens.yml.

Amounts are in the account’s currency and rounded to its decimal places. Dates have the form 31-Oct-2026. Durations have the form [h:]mm:ss.

Macro Value
${I_INVOICE} Invoice number: the internal ID of the invoice, unique on the switch
${I_ACCOUNT} ID of the account
${USERNAME} Account name
${SALUTATION}, ${FIRST_NAME}, ${LAST_NAME}, ${COMPANY_NAME} From the Address tab of the account
${STREET_ADDR}, ${POSTAL_CODE}, ${CITY}, ${STATE}, ${COUNTRY} From the Address tab of the account
${CURRENCY} Currency of the account
Macro Value
${INVOICE_START_DATE} First day of the billed period
${INVOICE_END_DATE} Last day of the billed period
${BILL_DATE} Date the period ends, which is the billing date
${LAST_BILL_DATE} Date of the previous invoice; the start of the period when there is none
Macro Value
${TOTAL_CHARGES} Service plan charges and minute plan fees in the period
${ADDITIONAL_CHARGES} All other charges in the period: DID fees, manual charges and the like
${TARIFF_CALLS_PRICE} Cost of calls billed by the tariff, that is, beyond the minutes of the service plan
${TOTAL_DID_CALLS_CHARGES} Cost of incoming calls to the account’s DIDs
${PAYMENTS_AMOUNT} Payments received in the period
${LAST_BILL_AMOUNT} Amount of the previous invoice; 0 when there is none
${FORWARD_AMOUNT} Debt brought forward: the negative balance at the start of the period, as a positive number; 0 otherwise
${BALANCE} Balance at the end of the period
${AMOUNT_DUE} What the account owes at the end of the period; 0 unless the balance is below zero
Macro Value
${ALL_CALLS_DURATION} Billed duration of all calls in the period
${PLAN_CALLS_DURATION} Billed duration covered by the minutes of the service plan
${TARIFF_CALLS_DURATION} Billed duration beyond the service plan minutes

A table macro repeats one HTML table row per record. Put ${TABLE:<name>} alone in a row, the ${TD:<field>} cells in the next row, and ${TABLE_END} alone in the row after it. The rows that hold ${TABLE} and ${TABLE_END} are removed from the result.

<table>
<tr><th>#</th><th>Date</th><th>Number</th><th>Length</th><th>Cost</th></tr>
<tr><td colspan="5">${TABLE:cdrs;max_rows=500}</td></tr>
<tr>
<td>${TD:_num}</td>
<td>${TD:date} ${TD:time}</td>
<td>${TD:cld_in}</td>
<td>${TD:duration;fmt=duration}</td>
<td>${TD:cost} ${CURRENCY}</td>
</tr>
<tr><td colspan="5">${TABLE_END}</td></tr>
</table>

Tables cannot be nested. ${TD:_num} is the row number in every table. Decimal values are rounded to the currency’s decimal places; add ;fmt=duration to show a number of seconds as [h:]mm:ss.

Table Parameters Fields
cdrs: the account’s calls that ended in the period, by start time max_rows: 1–1000, default 100. show_zero_cdrs: true to include zero-duration calls, default false date (26 Oct), time (15:04), cld_in, cli_in, duration, billed_duration, cost, prefix, remote_ip, the destination’s country code and description, and any other CDR field
cdrs_summary: the same calls grouped by destination group_by: country,description (default) or country. order_by: country, description, num_calls, effective_rate, duration or cost, with an optional :ASC or :DESC country (name), description, num_calls, duration (seconds), cost, effective_rate (cost per minute). Calls whose country is not known show Unknown
charges: charges to the account in the period max_rows: 1–1000, default 100 charge_time, date, time, amount, currency, name (type of charge), description
service_plan_charges: recurring charges of the account’s service plan none description, price
service_plan_minutes: minute plans of the service plan none description, price, seconds_total, destinations

Parameters follow the table name, separated by semicolons: ${TABLE:cdrs;show_zero_cdrs=true;max_rows=1000}, ${TABLE:cdrs_summary;group_by=country;order_by=cost:DESC}.

${EVAL:<expression>;<format>} computes a value after all other macros are replaced. The expression may contain only digits, spaces, +, -, *, /, parentheses and the decimal point. The format is a printf-style pattern such as %.2f; without it the raw result is printed.

Example Result
${EVAL: ${TOTAL_CHARGES} * 1.2 ; %.2f} Service plan charges plus 20% tax
${EVAL: ${TOTAL_CHARGES} * 0.2 ; %.2f} The tax alone
${EVAL: ${TARIFF_CALLS_PRICE} + ${ADDITIONAL_CHARGES} ; %.2f} Calls plus other charges

Use only amount and number macros inside ${EVAL}. A text macro or an empty value makes the expression invalid, and the invoice cannot be rendered.

  1. Open /images.php (the Images screen has no sidebar item).
  2. Upload your logo or other images. JPG, GIF and PNG up to about 500 KB are accepted.
  3. In the template editor, click the image button and select the image from the list.

Images are embedded into the PDF when the invoice is rendered, so the PDF does not depend on the panel being reachable. A template can use only images of its own customer.

The CSS box holds the style sheet of the invoice; the editor shows it as well. The default template uses it for headings and table alignment:

h2 {
background-color: #ff9900;
border: 1px solid #544f4f;
text-align: center;
}
table.fixed {
width: 100%;
table-layout: fixed;
}

Open the account, switch to the Advanced tab, check Invoicing Enabled and select the Invoice Template. For many accounts at once, set the Invoicing Enabled and Invoice Template columns of the account upload file. See Invoicing.

  1. Click the trash icon in the row.
  2. Click Yes in the confirmation.

Accounts that used the template switch to the system template Default Account Invoice. Invoices already issued are not affected.