Advanced Order Numbers for Magento

IMPORTANT ANNOUNCEMENT: Plugin development ceased, all plugins made available freely (GPL)

With great sadness we have to announce that we are ceasing development of all our VirtueMart, WooCommerce and Joomla plugins. Effective immediately, all our plugins -- even those that were paid downloads -- are made available for free from our homepage (GPL license still applies), but we cannot and will not provide any support anymore.

It has been a great pleasure to be part of the thriving development communities of VirtueMart as well as WooCommerce. However, during the last year it became painstakingly clear that in addition to a full-time job, a young family and several other time-consuming hobbies at professional level (like being a professional singer) the plugin development and the support that it requires is not sustainable and is taking its toll. It has been an honor, but it is now time to say good bye!

Advanced Order Numbers for Magento

Advanced Order Numbers for Magento (CE 1.9)

 OpenTools Magento Ordernumber OrderConfirmation



Introduction / About the plugin

Endless possibilities to have order/invoice numbers the way YOU like them

Whether you want simple order/invoice numbers with a prefix, or whether you want the shipment or credit memo number to match the invoice number, or whether you even want separate number counters for each country or even customer, OpenTools Advanced Ordernumbers for Magento is the solution you need!

While the order/invoice numbers might be just a nuissance to your users, using clean, professional numberings will give your customers the assurance that they are dealing with professionals - the small, subtle details are the difference between a good shop and an excellent shop. Rather than showing "boring" numbers like 1000001352, use a clean numbering scheme like "2015-US-0123" or "Mag-2015-01/0023"!

OpenTools Magento Ordernumber NumbersIncreasing annotatedOpenTools Magento Ordernumber NumbersPerCountry annotated

Easy configuration, yet powerful features

Key features of this module:

  • Freely customize order numbers, invoice numbers, shipment numbers and/or credit memo numbers to your desires!
  • Number format is given as an ordinary string that can contain a vast number of variables (date/time, order properties, customer properties, address, and even random numbers or letters) and a counter
  • Customizable counter resets, multiple parallel counters: Counter can be global (one counter for all orders or invoices) with no reset, or yearly/monthly/daily counters, or even more general counter resets. You can even have multiple counters running concurrently (e.g. one counter per country, or different counters and thus different order/invoice numbers for wholesale and retail customers).
  • Alternatively, you can re-use the order number as invoice, shipment and credit memo numbers, too (in some jurisdictions this might be problematic, because the order numbers can have gaps!)
  • Per-store or global configuration: The module supports Magento's multi-store feature and allows you to set the configuration either globally for all websites and stores, or a separate configuration with different number formats for each of your stores or even store views.
  • Counter increments and formatting: In addition to the number format, you can choose your custom counter increment (to prevent your competitors from seeing how many orders you actually get) and the padding of the counters with zeros on the left (e.g. a counter with value 35 can be displayed as 000035 inside the number format)
  • Manually set/change your counters in the module configuration
  • Define your own custom variables for use in the number formats.

The exotic...

The incredible flexibility of this Magento module means that you do not have to stop at the usual numbering schemes involving a counter. You can even use only the date/time of the order or even random numbers as order or invoice numbers:

OpenTools Magento Ordernumber NumbersExotic CurrentTime Random annotated



Configuration in the Magento Admin Area

OpenTools Magento Ordernumber Settings Menu annotatedOnce installed, the module adds a section to the configuration section of the admin area (Menu item "System" -> "Configuration", Tab "SALES" -> "Customize Order and Invoice Numbers" on the left).

Please note that immediately after installing the module via Magento connect, you will need to log out of the admin area and log back in. Otherwise you will get an error when trying to access the configuration page. 
The reason for this is that Magento's access control settings are only updated when you log in.

Basic settings for order/invoice/shipment/credit memo numbers

The module configuration has six areas, four for the configuration of Order, Invoice, Shipment and Credit Memo numbers, one to define custom variables for use in the number formats, and one final section to view and modify the current counter values for all the numbers.

OpenTools Magento Ordernumber Settings

Each of the Order, Invoice, Shipment and Credit Memo number configuration sections has the exact same configurations options:

  • "Customize .... numbers": Set to "Yes" to customize the corresponding numbers. If left to the default value of "No", the module will not assign the corresponding type of number and the Magento default will be used. All other configuration settings will be hidden, unless this is set to "Yes".
  • "Format of the ... numbers": The format of the order/invoice/shipment/credit memo numbers. The value of this setting is a simple string, where # indicates the running counter and [...] indicates a variable. Everything else is taken verbatim into the final number.
  • "Scope of the counter": (Multi-store installations only)
  • "Counter 'Reset'"
  • "Number of digits for the counter":
  • "Counter increment"

OpenTools Magento Ordernumber Settings annotated

All Available Variables


# Running counter (either global or per format-value); Not applicable to the order password!
Date and Time:
[year] Current year (4 digits)
[year2] Current year (2 digits)
[month] Current month (2 digits); leading zeros if necessary
[day] Current day (2 digits); leading zeros if necessary
[hour] Current hour in 24-hour format; leading zeros if necessary
[hour12] Current hour in 12-hour format; leading zeros if necessary
[ampm] Current am-pm (for 12-hour format) in lower-case
[minute] Current minute; leading zeros if necessary
[second] Current second; leading zeros if necessary
[decisecond] Current tenth of a second (1 digit)
[centisecond] Current hundreth of a second (2 digits, padded with 0 if neccessary)
[millisecond] Current millisecond (3 digits, padded with 0 if neccessary)
Random Numbers and Strings:
[randomDigit[n]] Random sequences of n decimal digits (n=1 if not given).
[randomHex[n]] Random sequences of n hexadecimal digits (n=1 if not given).
[randomLetter[n]] Random sequences of n (upper- and lowercase) letters (n=1 if not given).
[randomULetter[n]] Random sequences of n uppercase letters (n=1 if not given).
[randomLLetter[n]] Random sequences of n lowercase letters (n=1 if not given).
[randomAlphanum[n]] Random sequences of n general alphanumeric characters (A-Z, a-z, 0-9) (n=1 if not given).
Address information: Shipping address (if given, billing address otherwise) when no prefix is used; All variables also available with prefix Billing or Shipping (e.g. [ShippingZIP] and [BillingZIP])
Lastname Last name of the shopper
Firstname First name of the shopper
Company Company of the shopper
City City of the shopper
zip, PostCode ZIP of the shopper
Country Full county name
CountryCode2 2-letter ISO country code
CountryCode3 3-letter ISO country code
CountryID (internal) unique ID of the country
Region Full region name
Regioncode Short code for the region
RegionID (internal) unique ID of the region
addressid (internal) unique ID of the address
Store, Order and Invoice details:
StoreID ID of the current store (for multi-store installations)
StoreCurrency Currency of the current store
orderID (internal) unique ID of the order
orderNumber Order number, for which the invoice is created
orderStatus Status of the order (abbreviations: S, R, X, C, U, P)
Currency Currency of the order
CustomerID (internal) unique ID of the customer posting the order
TotalItems, TotalQuantity Total number of items and quantity of the order
ShippingMethod Shipping method of the order
InvoiceID (internal) unique ID of the invoice


Defining custom variables

OpenTools Magento Ordernumber CustomVariables

Manually Changing Counter Values

OpenTools Magento Ordernumber EditCounter2 annotated

How Counters Work in the Module

Examples of Numbering Schemes and their Settings

Technical Details

Version History

2014-12-31: Version 0.1.0 (Initial release)

How the plugin works

When a new order is submitted, a new invoice, shipment or credit memo is created, this plugin immediately creates the corresponding order/invoice/shipment/creditmemo number. This plugin works by listening to the proper events emitted by Magento and does NOT replace Mageto core code or rewrite core classes. Some things might be conceptionally cleaner when one rewrites classes, but a class can only be rewritten by exactly one extension. For this reason, we prefer listeners over core rewrites to prevent incompatibilities with other modules.

 Order/Invoice Number Format Strings

The format strings are simple texts, where the following variables will be replaced. Everything that does not match one of these is taken verbatim into the invoice/order/customer numbers and order password.


  • For example, a format "[year][month]-#" will create numbers like:


  • A format "[year2]-[month]: [randomHex3]-[randomULetter5][randomDigit]-#" will create order/invoice numbers like:

12-11: a3b-ETZKE8-1
12-11: 808-KWCHZ1-2
12-11: 3cfb-JKIKR0-3
12-11: 328-QXPZJ7-4

  • If you want the invoice numbers to match the order numbers, you can use a format "[orderNumber]" (notice the lack of the running counter!). However, this might not fulfil the legal requirement of successive invoice numbers, as some orders might be cancelled (but still counted) before an invoice is issued!
  • The default order/invoice numbers of Magento more or less corresponds to a format "[storeId]#" with proper counter padding.
  • For customer numbers (which are by default not displayed in VirtueMart's invoices) we strongly recommend to use a GLOBAL counter and no date-specific part in the customer number, as this will give a hint of the customer's first order date, which might be even regarded as sensitive information! Also, the customer number format cannot contain any order-specific placeholders for obvious reasons (the customer needs to register BEFORE any order can be created).


 Format-specific counters

As a general rule of thumb for format-specific counters, whenever any of the variables included in the format changes, the counter will be reset to 1.

For example, with a format "[year]-[month]-[day]/#", the counter will be reset each day. With a format "[year][month][day][hour][minute]-#", the counter will be reset each minute. So by default it is no possible to have e.g. a format "[year][month][day]/#" and have the counter reset only yearly.


The details

In fact, it's actually a bit more complicated: The plugin does not have one counter, that is reset at the beginning of a new year/month.
Rather is has multiple concurrent counters. When generating the order number, the plugin will first replace all [...] parts with the variable values. Then the resulting string is used as the name for the counter. The counter is looked up in the database (if not found, a value of 0 is used) and then incremented, stored back to the database and inserted for the # in the format.


This approach is best understood at an example:

Number format [year][month][day]-#:

FIRST ORDER on Aug 18, 2014:

  1. The plugin will insert all variables except for the counter.
    Result today: "20140818-#"
  2. Then it checks in the database if a counter with this name already exists.
    This is not the case, so it uses a counter of 1:
    Result today: "20140818-1"
  3. The counter value 1 for "20140818-#" is stored in the database.

NEXT ORDER on Aug 18, 2014:

  1. First, the plugin will insert all variables except for the counter.
    Result today: "20140818-#" (same as above)
  2. Now this counter already exists and has a value of 1 in the database. The plugin uses this and increases it to 2. Then it inserts this into the order number:
    Result today: "20140818-2"
  3. The counter value 2 for "20140818-#" is stored in the database.

FIRST ORDER  on Aug 19, 2014:

  1. The plugin will insert all variables except for the counter.
    Result tomorrow: "20140819-#" (different than above!)
  2. Then it checks in the database if a counter with this name already exists.
    This is not the case, so it uses a counter of 1:
    Result today: "20140819-1"
  3. The counter value 1 for "20140819-#" is stored in the database.

As you can see, with a format-specific counter, whenever any of the variables in the format changes, a new counter is created and it starts from 1.

If you want one global counter that does not reset, simply select "Global counter" in the plugin configuration. 



So, in effect it appears as if the counter is reset daily, while in fact a new counter is used for each day. This approach has the advantage that you can have e.g. different counters for orders to different countries. If you use the format "[year]-[countrycode2]-#", each country will have its own counter and you have order numbers like "2014-AT-1", "2014-DE-1", "2014-AT-2", "2014-AT-3", "2014-CH-1", "2014-DE-2", etc. (Notice that the orders for AT have one counter, while the DE have another independent countet).

This approach is very generic (and very simple, yet really powerful), but unfortunately it also means that having a format of "[year][month]#" where the counter is reset only each year is NOT possible by default, since the format value will change each month and the format value will be used as the counter name...


Advanced Topic: Separate counter format

To solve the problem described in the previous paragraph (the counter resets if and only if any of the variables used in the format changes, which is not always what is desired), you can even give your own custom counter name. Notice that this is needed only in exceptional cases and certainly not intended for a normal installation. If you think that you really need this feature in your shop, it is probably best to ask in the support forum, because this feature has a lot of potential to cause havoc.

A typical example is a number format like "[year][month]/#" where the shop owner wants the counter to be running inside the year. By default, a new counter will be used each month (since the month variable changes each month...). Starting with plugin version 1.12, the shop owner can now use a number format "[year][month]/#", but let the plugin use a counter name of "[year]/#", which will cause the counter to be reset only at the beginning of each year. The proper format string in this case is:


This gives the shop owner even more flexibility, but is quite hard to understand with all consequences. In particular, a wrong counter format can cause orders with duplicate numbers, in which case VirtueMart will append the current timestamp to the number (leading to ugly numbers like "201410/1_2014-10-16T15:10:12". To prevent this, the counter format should ONLY use variables that are also in the number format string. Everything else will lead to duplicate numbers.

Changing counter values (or "How can I start the counter from 1234?")

For each counter, its current value is stored in the database and read from there when the plugin creates a new number. Directly after installation, each counter will start from 1 (its current value is 0). If your shop has been running for a while, you might want it to start from some other value.

The easiest way to achieve this is to set up the plugin, make one test order so that the plugin creates the counter, and then adjust its name in the plugin configuration in the backend.

If you are using a global counter, modify the "Global counter" row, otherwise find the corresponding counter and modify that. 

If you don't want to create a test order and the counter you want to modify does not exist yet, you can manually create a counter with the proper button in the table. Your browser will ask you for the counter name and then send the request to your server to create a counter with that name and initial value 0. To create the global counter, simply leave the field completely empty.
Please read the section on format-specific counters to determine the correct counter name for your format. In particular, the counter name will be the format string where all variables like [year] etc. have been replaced with their corresponding value at the time an order is made. Only the counter (the #) is left unchanged.


Known Incompatibilities

  • The iDEAL payment method does not work if the order number contains SPACES!
  • Similarly, an order number that contains - (or any character other than letters and digits!), the iDEAL payment server will return an error and the payment will fail.

The only solution is to use an order number format that only contains letters and digits, but no other characters like -, /, etc.

How can I change the order and invoice numbers of existing orders?

The short answer: You can't! This plugin can only modify the order and invoice numbers of new orders.