Modules provide integration of BILLmanager with external systems: payment gateways, domain registrars, service providers, and so on. Modules do not change the behavior of the platform itself; they enable it to work with an external service. This article describes module classes, their working principles, and the XML description structure.
BILLmanager modifications
BILLmanager lets you add the following modifications:
- modules — large, standalone system components that perform a specific function or set of functions. For example, they extend functionality through integration with a third-party system. Modules:
- usually have their own dependencies and can include several plugins;
- are not designed to dynamically change system behavior in real time;
- may require changes to the core system architecture;
- are divided by functionality into:
- service handlers;
- payment methods;
- message gateways;
- cash registers;
- document workflow modules;
- modules for coordination with third-party systems — LDAP, Omni, amoCRM, etc.
- plugins — usually simpler software components that add specific functionality or change the behavior of the core system. Plugins let you:
- integrate new features without changing the source code;
- intercept internal events;
- add new interface elements;
- run background tasks through triggers on specific events;
- adapt the system to specific needs.
See the article Background plugins for more details.
See the comparison of plugins and modules in the article Creating modules.
Module classes
A module is an external executable file that BILLmanager calls with the argument --command <command> and a set of parameters in the form --<name> <value>. For some commands, an XML document may be passed on standard input (stdin), or the module may be required to write to stdout. The module does not react to platform events; instead, it implements a specific type of integration.
All modules must support the --command features command (for payment methods — config), which returns an XML document describing the supported capabilities (<features>, <params>, <itemtypes>, and so on). Unsupported commands must not be mentioned in the features response; otherwise, BILLmanager will try to call them, which will lead to errors.
Below is a comparison of the main module classes supported by BILLmanager, supported by BILLmanager.
Comparison table of module classes
General development notes
When developing modules, keep in mind several general rules that apply to all module classes. Following these rules ensures correct operation of the module and its integration with BILLmanager:
- the
featurescommand (configfor payment methods) must be implemented in any module. Do not include unsupported commands in the XML response; - long-running operations (domain registration, certificate issuance) receive the
--runningoperationparameter. When the operation finishes, you must call the corresponding BILLmanager function (for example,domain.open,certificate.open,service.postclose, and so on), otherwise the operation will be repeated; - connection parameters that need protection must have the
crypted="yes"attribute in the XML description. BILLmanager will store them in encrypted form; - it is recommended to place CGI scripts for payment methods and gateways in the /usr/local/mgr5/cgi/ directory;
- it is recommended to keep logs in the /usr/local/mgr5/var/ directory. For Python, use billmgr.logger.
General XML notes
All XML must be valid. After changing the file, be sure to restart BILLmanager with the command:
/usr/local/mgr5/sbin/mgrctl -m billmgr -RWhen creating XML documents, follow these rules:
- An XML document without data (
<doc/>)means successful completion without additional data; - errors are returned in the form:
<doc>
<error type="<value указанное после msg_error_ в сообщениях>" object="*" value="*"/>
</doc>or for a specific field, the msg_error_value message is defined:
<doc>
<error type="value" object="*" value="*"/>
</doc>- use UTF-8 encoding for all XML files;
- with the
crypted="yes"attribute infeatures, BILLmanager passes these parameters to the module unencrypted only in thecheck_connectioncommand. In other cases, they are stored encrypted in the database and are not passed; - messages can be overridden on specific forms or globally through XML configuration by specifying them in the required section. This will overwrite the existing message.
Module working principles
Modules BILLmanager are started with command-line arguments --command <command> [--parameter value] and can exchange data through standard input and output streams. This section describes the module call format and the data exchange principles.
Call format
BILLmanager starts the module with the command:
/путь/к/модулю --command <command> [--parameter1 value1] [--parameter2 value2] ...Where:
- each parameter is passed in the form
--name value; - the required argument is
--command, which specifies the module function to call (for example,open,close,features,process); - the remaining arguments are named parameters (for example,
--item 42,--cash_register 1).
Passing data through standard input (stdin)
Some commands require structured data that is inconvenient or impossible to pass through command-line arguments. For example, complex XML forms or multiline values. In such cases, BILLmanager sends XML to the module's stdin.
Commands that usually use stdin:
check_connection— gets connection parameters in plain form;tune_connection,form_tune,*tune(pmtune, crtune, rftune, and so on) — get the current XML form template;*validate(pmvalidate, crvalidate, and so on) — get the data entered by the user;*set(rfset, tfset, and so on) — get additional operation data.
<doc>
<api_url>https://api.provider.com</api_url>
<api_key>test_key</api_key>
<extra_param>value</extra_param>
</doc>The module uses the XML code from stdin, processes it, and outputs the result to stdout.
Outputting results to standard output (stdout)
The result of the command is output by the module to stdout. The output format is always an XML file (except when the module performs external actions without returning data, but even then it is recommended to output an empty XML).
Output data types:
- successful completion without additional data — empty XML file:
<doc/>; - successful completion with data — an XML file whose structure depends on the command. For example:
features— returns the module capabilities description;WHOIS— returns the WHOIS string in the<WHOIS>node;approver— returns a list of email addresses.
Example for approver:<doc> <email>admin@example.com</email> <email>hostmaster@example.com</email> </doc> - execution with an error — an XML file with the
<error>node:<doc> <error type="connection" value="*" object="*"/> </doc>
Required command features (or config for payment methods)
All modules must support the --command features command (for payment methods — --command config). This command does not receive input data (stdin is not used) and outputs an XML file that describes:
- which types of items the module handles (
<itemtypes>); - which parameters are needed for its setup (
<params>); - which commands (functions) it supports (
<features>); - additional information. For example,
<templates>for an SSL certificate,<contact_type>for notifications; configmust contain the<features>element.
<doc>
<itemtypes><itemtype name="domain"/></itemtypes>
<params>
<param name="api_url"/>
<param name="api_key" crypted="yes"/>
</params>
<features>
<feature name="open"/>
<feature name="close"/>
<feature name="check_connection"/>
</features>
</doc>BILLmanager will not call commands that are not listed in the features response. If the module supports a command, but the administrator did not specify it in features, it will remain unused.
Long-running operations and the --runningoperation parameter
Some operations (domain registration, certificate issuance, VPS creation) may take a long time. For such commands, BILLmanager passes the additional --runningoperation <id> parameter.
After the actual operation is completed, the module must notify BILLmanager of the result (success or error) by calling mgrctl .
/usr/local/mgr5/sbin/mgrctl -m billmgr service.postclose --elid 456If the module does not call the corresponding function, BILLmanager will periodically restart the command, considering that the operation is still not finished.
Parameter encryption
In the XML metadata of a module, parameters can be marked with the crypted="yes" attribute. This means that BILLmanager will store them in the database in encrypted form.
Important exception: when the check_connection command is called (as well as pmvalidate, crvalidate, and other validation commands), BILLmanager passes these parameters in plain form to the module's stdin. This is necessary so that the module can verify them, for example by making a test API connection.
In all other commands, encrypted parameters are not passed to the module.
Encoding requirements
To avoid parsing errors and ensure correct data processing by the system, follow these requirements:
- input (stdin) and output (stdout) XML must be encoded in UTF-8;
- BILLmanager expects UTF-8 specifically; using other encodings may lead to parsing errors.
Example of a full call cycle
Consider a call of the check_connection command for a service processing module:
- BILLmanager creates an XML file with connection parameters. Encryption is not used.
- BILLmanager starts the module:
/usr/local/mgr5/processing/myprocessor --command check_connection - BILLmanager passes the XML to the module's
stdin. - The module receives the
stdinand performs the check. For example, it calls the provider's API. - Depending on the result, it outputs to
stdout:- on success:
<doc/> - on error:
<doc><error type="msg_error_*" .../></doc>
- on success:
- BILLmanager reads the stdout, parses the XML code, and determines whether the check was successful.
If the command does not use stdin (for example, features), the module ignores stdin.
XML description (billmgr_mod_<name>.xml file)
The metadata file describes the module for BILLmanager: its type, settings form, localized names, and error messages. The file format depends on the module type and may include several <metadata> sections for different purposes (main settings, user creation, service profile, and so on).
For more information about working with XML forms, finding tags, and their attributes, see the COREmanager documentation.
General rules
- root element —
<mgrdata>; - encoding — UTF-8;
- location — /usr/local/mgr5/etc/xml/;
- the file name is formed according to the format:
- service processing module: billmgr_mod_pm<name>.xml;
- payment method: billmgr_mod_pm<name>.xml;
- cash register: billmgr_mod_cr<name>.xml;
- notification module: billmgr_mod_nt<name>.xml;
- message gateway: billmgr_mod_gw<name>.xml;
- after changing the XML file, restart BILLmanager:
/usr/local/mgr5/sbin/mgrctl -m billmgr exit
Element <plugin>
The <plugin> element is used for modules that are standalone plugins:
- service processing modules (
group=processing_module); - payment methods (
group=payment_method); - cash registers (
group=payment_cash_register); - message gateways (
group=gateway); - plugins (
group=plugin).
Attributes:
name— internal module name (matches the executable file name and part of the XML file name).
Child elements:
<plugin name="pmnic">
<group>processing_module</group>
<author>BILLmanager team</author>
<params>
<type name="domain"/>
<priority lang="ru">1800</priority>
<priority lang="en">700</priority>
</params>
</plugin><plugin name="pmnowpayments">
<group>payment_method</group>
<author>BILLmanager team</author>
<params>
<priority lang="en">3810</priority>
<priority lang="ru">1800</priority>
</params>
</plugin>The <plugin> section is used to display in the interface:
- the module in the installation section;
- sorting;
- description.
If you remove this section from the XML file, the module or plugin will continue to work. Since the executable file remains in the corresponding folder, it will be loaded as a regular BinaryModule. But the function of installing and configuring the module through the web interface will not be available.
Element <metadata>
There can be several <metadata> blocks in one file. Each one describes a specific form: module settings, user creation form, service profile, and so on.
General attributes:
name— form identifier. The format depends on the purpose. See the table for details;type="form"— required for forms.
Internal structure: <metadata> contains <form>, which can include several pages (<page>) and fields (<field>). <link> (links) and <include> for reusing form parts are also supported.
Main module settings form
Used to enter connection parameters (API keys, URLs, logins, passwords, and so on).
Below are examples of the main form for different module types.
User creation form (optional)
Some modules (for example, payment methods and registrars) require a separate form to create an account in the external system. The name of such a form usually contains the suffix .createuser.
Service profile form (service_profile)
For service processing modules (for example, domain registrars), a form for entering contact details specific to the domain zone may be required. The name of such a form is: service_profile.<module_name>[.<zone>].
Notification module: adding a field to the user profile
Notification modules do not have their own settings form. Instead, they add a field to the user profile (user_include).
Attributes of <input> and other elements
Frequently used <input> attributes:
Element <select>
<field name="pay_method">
<select name="pay_method" private="yes"/>
</field>The selection options are defined in localization (see the COREmanager documentation).
Element <link>
<field name="link">
<link name="outerlink" target="_blank"/>
</field>Used to display a hyperlink in the form.
Element <if> inside <select>
Allows fields to be hidden depending on the selected value.
Element <lang> and message blocks
The name attribute is used to localize strings by specifying a language (ru, en, es, and so on). Inside there are <messages name="..."> blocks, each of which contains <msg name="..." value="..."/> (or text between tags).
Main message blocks (by module type):
<lang name="ru">
<messages name="gateway.gwcustom">
<msg name="custom_param_url">API URL</msg>
<msg name="custom_param_api_key">API Key</msg>
</messages>
<messages name="gateway_include">
<msg name="module_gwcustom">gwcustom</msg>
<msg name="gwcustom">gwcustom</msg>
<msg name="desc_gwcustom">SMS gateway</msg>
</messages>
</lang><lang name="ru">
<messages name="label_paymethod">
<msg name="pm2checkout">2CheckOut</msg>
<msg name="module_pm2checkout">2CheckOut</msg>
</messages>
<messages name="paymethod.edit.2checkout">
<msg name="sid">2CO Account #</msg>
<msg name="pay_method">Payment method</msg>
<msg name="cc">Payment cards</msg>
<msg name="ppi">PayPal</msg>
</messages>
</lang><lang name="ru">
<messages name="processing.edit.pmnic">
<msg name="contract_num">Contract number</msg>
<msg name="msg_lang">Language</msg>
<msg name="partner_domain">Domain</msg>
</messages>
</lang>The module name may not be in a separate block; it is taken from plugin, and processing.edit.pmnic is used for field labels.
Error messages (msgerror section)
The module can return errors in XML format (see the Outputting results to standard output (stdout) section). BILLmanager localizes them using messages from the msgerror section. Message lookup works as follows:
msg_error_<type>msg_error_unknown
Example definition in pmnowpayments:
<messages name="msgerror">
<msg name="msg_error_invalid_api_key">Invalid API key</msg>
<msg name="msg_error_api_down">Gateway unavailable</msg>
<msg name="msg_error_wrong_email_form">Invalid email format</msg>
</messages>Summary table: module types and <metadata> identifiers
Important notes
- Notification modules do not contain
<plugin>. They only add a field to the user profile (user_include) and define a new notification type ininclude.notify. The actual sending of messages is performed by the corresponding gateway (gw*); - Field names in
<field name="...">must exactly match the names of the parameters specified in the response to thefeaturescommand (orconfigfor payment methods); - The
private="yes"attribute hides the field in the interface, but the value may be shown in logs during debugging. For passwords and keys, it is recommended to use both attributes:private="yes" crypted="yes"; messages name="..."blocks do not have a strict standard — they must match the name of the corresponding<metadata>(for field labels) or common names (plugin,label_paymethod,gateway_include,payment_cash_register.include). The module name in the interface is most often defined in the..._includeorlabel_...block, but it can also be inplugin(for service processing modules, the name is often taken fromdesc_short_<name>);- The sorting priority (
<priority lang="ru">number</priority>) affects the display order of the module in the selection list. A smaller number means higher in the list; - To add multiple localizations for a plugin, add
<lang name="...">blocks for each supported language. For example,en,ru,es,de.
En
Es