BILLmanager 6
en En
es Es

Modules. General principles

The following terms are used in the article

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

Class

Directory

Base class (Python SDK)

Main commands (required ones are highlighted in bold)

Article with additional information

Service processing module

/usr/local/mgr5/processing/

ProcessingModule

features , open, suspend, resume, close, setparam, prolong, sync_item, check_connection

How to add a custom processing module

Payment system module

/usr/local/mgr5/paymethods/

PaymethodModule

config , pmtune , pmvalidate , crtune , crvalidate , crset , rfset , tfset , rcset , rcpay, checkpay

How to add a payment gateway module

Domain registrar module

/usr/local/mgr5/processing/

ProcessingModule

the same as for the processing module and transfer, import, WHOIS, update_ns, get_contact_type, cancel_prolong

How to add a domain registrar module

SSL certificate sales module

/usr/local/mgr5/processing/

ProcessingModule

the same as for the processing module and approver, usercreate, reopen

How to add SSL certificate module

Notification module

/usr/local/mgr5/notify/

No base implementation

features , process , getmessage

How to add a notification module 

Message gateway module

/usr/local/mgr5/gate/

GatewayModule

features , outgoing , ingoing, formtune, check_connection

How to add a notification module

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 features command (config for 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 --runningoperation parameter. 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 -R

When 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 in features, BILLmanager passes these parameters to the module unencrypted only in the check_connection command. 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.
Example input XML for check_connection:
<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;
  • config must contain the <features> element.
Example for a service processing module:
<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 456

If 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:

  1. BILLmanager creates an XML file with connection parameters. Encryption is not used.
  2. BILLmanager starts the module:
    /usr/local/mgr5/processing/myprocessor --command check_connection
  3. BILLmanager passes the XML to the module's stdin.
  4. The module receives the stdin and performs the check. For example, it calls the provider's API.
  5. Depending on the result, it outputs to stdout:
    • on success: <doc/>
    • on error: <doc><error type="msg_error_*" .../></doc>
  6. 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:

Element

Description

<group>

Module type: processing_module, payment_method, payment_cash_register, gateway, plugin

<author>

Module author (optional)

<params>

Additional parameters:

  • for a service processing module — <type name="..."/> (supported type: domain, certificate, all);
  • for all types — <priority lang="ru">number</priority> for sorting in the interface (smaller means higher);
  • for the processing module — <notype name="..."/> (unsupported product type)

<msg>

Short and full module description (attributes name="desc_short_<name>", name="desc_full_<name>", lang). There can also be price_<name> for marketplace pricing.

Example for a service processing module (domain registrar):
<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>


Example for a payment method (NOWPayments):
<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.

Example pmnic for a service processing module (ProcessingModule)
Example pm2checkout for a payment method (PaymethodModule):
Example crcustom for cash register modules (CashregisterModule)
Example gwcustom for message gateway modules (GatewayModule)

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.

Example for a payment method (pm2checkout):
Example for a service processing module (pmnic):

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>].

Example for RU-Center (general profile):
Example for the .ru zone:
Example of form inheritance through

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).

Example for Jabber:

Attributes of <input> and other elements

Frequently used <input> attributes:

Attribute

Description

type

Element type. Possible values:

  • text;
  • password;
  • checkbox;
  • select;
  • textarea;
  • link.

required="yes"

Required field.

private="yes"

Do not display in the interface (but it is passed to the module).

crypted="yes"

The attribute must be stored encrypted in the database.

check

Built-in validation: url, email, domain, int, and others. To use validator plugins, specify the name after the check. prefix.

identifier="yes"

Identifier field (for gateways).

maxlength

Maximum string length.

default

Default value.

readonly="yes"

Read-only field.

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):

Module type

messages name block

Purpose

Examples of <msg> names

All (except notification module notify)

plugin

Plugin description.

desc_short_<name>, desc_full_<name>, price_<name>

Service processing module




processing.edit.<name>

Labels of the settings form fields.

<field_name>, hint_<field_name>

processing.edit.<name>.createuser

Labels of the user creation form.

outerlink and others

service_profile.<name>

Labels of the service profile fields.

<field_name>, hint_<field_name>

domain.<name>.<zone>

Messages specific to the domain zone.

uin, authid, and so on

Payment method



label_paymethod (or paymethods.include)

Module name in the interface.

module_<name>, <name>

paymethod.edit.<name>

Labels of the settings form fields.

<field_name>, hint_<field_name>

paymethod.edit.<name>.createuser

Labels of the user creation form.

outerlink

Cash register


payment_cash_register.include

Module name in the interface.

module_<name>, <name>

payment_cash_register.edit.<name>

Labels of the settings form fields.

<field_name>, hint_<field_name>

Gateway


gateway_include

Module name in the interface.

module_<name>, <name>, desc_<name>

gateway.<name>

Labels of the settings form fields.

<field_name>, hint_<field_name>

Notification module


include.notify

Notification type.

type_nt<name>, modulename_nt<name>, nt<name>

user.edit

Labels of the field in the user profile.

<field_name>, hint_<field_name>

All

msgerror

Error messages

msg_error_...


Example for gateway (gwcustom)
<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>


Example for a payment method (pm2checkout)
<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>
Example for a service processing module (pmnic)
<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:

  1. msg_error_<type>
  2. 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

Module type

<group>

<plugin>

Examples of <metadata name="...">

Service processing module

processing_module

Yes

processing.edit.<name>
processing.edit.<name>.createuser
service_profile.<name>
service_profile.<name>.<zone>

Payment method

payment_method

Yes

paymethod.edit.<name>
paymethod.edit.<name>.createuser

Cash register

payment_cash_register

Yes

payment_cash_register.edit.<name>

Notification module

—

No

user_include

Message gateway

gateway

Yes

gateway.<name>

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 in include.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 the features command (or config for 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 ..._include or label_... block, but it can also be in plugin (for service processing modules, the name is often taken from desc_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.