This guide will show how to install A2Billing on a Redhat Enterprise Linux based system. It is assumed you already have Linux and Asterisk and FreePBX installed using a procedure similar to this one. We do not cover the installation of the callback daemon.
This guide was tested using the following software:
CentOS Linux v5
Asterisk v1.8.5
FreePBX v2.9
A2Billing v1.9.4
The following 2 diagrams illustrate A2billing inbound and outbound call flow.
All commands are assuming you are at run level 3 running in a shell as root. In other words, not in a Gnome/KDE GUI and not using a limited access account.
PHP 5.2 is required and available via the CentOS 5 testing repository. We shall create the testing respository file and configure it to only pull PHP packages.
nano /etc/yum.repos.d/centos-testing.repo
and add the following:
[c5-testing]
name=CentOS-5 Testing
baseurl=http://dev.centos.org/centos/$releasever/testing/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://dev.centos.org/centos/RPM-GPG-KEY-CentOS-testing
includepkgs=php*
Now update
yum update
Install additional required packages if not already installed
yum -y install php-mcrypt perl-DBD-Pg
Change php folder permission back to what it was set to during Asterisk/FreePBX install before PHP update
chown -R asterisk:asterisk /var/lib/php/session
Restart
apache for the changes to take effect
service httpd restart
Get a2billing source
cd /usr/src
wget --no-check-certificate https://github.com/Star2Billing/a2billing/tarball/v1-current
dir
Note the filename of the downloaded file and use it as follows:
tar zxvf Star2Billing-a2billing-v1-current-x-xxxxxx.tar.gz
Replace the 'x..x' with whatever the actual file name is called.
Rename the directory
mv Star2Billing-a2billing-xxxxx a2billing
Prepare MySQL database
cd /usr/src/a2billing
If you did not create a mysql root password during the asterisk install you should create one now.
mysqladmin -u root password 'rootmysqlpassword'
If you get access denied the password has already been set. For PowerPBX install guide a password of 'abcdef' was used. For distributions such as PiaF, the password is 'passw0rd'. This will be the password the following commands will ask for.
mysql -u root -p < DataBase/mysql-5.x/a2billing-createdb-user.sql
which will create:
Database name: mya2billing
Database user: a2billinguser
Database user password: a2billing
Now run script to create tables and insert some basic configuration data
cd /usr/src/a2billing/DataBase/mysql-5.x
./install-db.sh
Answer questions as follows:
Enter Database Name: mya2billing
Enter Hostname: localhost
Enter UserName: root
Enter Password: 'mysqlrootpassword'
Now check that the database and 90+ tables have been created
mysql -u root -p mya2billing
>show tables;
+---------------------------+
| Tables_in_mya2billing |
+---------------------------+
| cc_agent |
| cc_agent_commission |
.
.
.
.
.
| cc_version |
| cc_voucher |
+---------------------------+
97 rows in set (0.00 sec)
>exit
cp /usr/src/a2billing/a2billing.conf /etc/
nano /etc/a2billing.conf
Make sure the following parameters are set as shown.
[database]
hostname = localhost
port = 3306
user = a2billinguser
password = a2billing
dbname = mya2billing
dbtype = mysql
Create files and set permissions
Only required if not using Asterisk Realtime. If unsure then proceed as if you are not using Asterisk Realtime.
chmod 777 /etc/asterisk
touch /etc/asterisk/additional_a2billing_iax.conf
touch /etc/asterisk/additional_a2billing_sip.conf
echo \#include additional_a2billing_sip.conf >> /etc/asterisk/sip_custom.conf
echo \#include additional_a2billing_iax.conf >> /etc/asterisk/iax_custom.conf
chown -Rf asterisk:asterisk /etc/asterisk/additional_a2billing_iax.conf
chown -Rf asterisk:asterisk /etc/asterisk/additional_a2billing_sip.conf
Run sound installation script
cd /usr/src/a2billing/addons/sounds
./install_a2b_sounds.sh
chown -R asterisk:asterisk /var/lib/asterisk/sounds/
Add the following to /etc/asterisk/manager_custom.conf
You can also do it via the FreePBX Asterisk API module.
[myasterisk]
secret=mycode
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.0
read=system,call,log,verbose,command,agent,user
write=system,call,log,verbose,command,agent,user
Set up a2billing web folder
mkdir /var/www/html/a2billing
cp -Rf /usr/src/a2billing/admin /var/www/html/a2billing/admin
cp -Rf /usr/src/a2billing/agent /var/www/html/a2billing/agent
cp -Rf /usr/src/a2billing/customer /var/www/html/a2billing/customer
cp -Rf /usr/src/a2billing/common /var/www/html/a2billing/common
chown -R asterisk:asterisk /var/www/html/a2billing
chmod 755 /var/www/html/a2billing/admin/templates_c
chmod 755 /var/www/html/a2billing/customer/templates_c
chmod 755 /var/www/html/a2billing/agent/templates_c
Set up AGI
mkdir /var/lib/asterisk/agi-bin
cd /usr/src/a2billing/AGI
cp a2billing.php /var/lib/asterisk/agi-bin/
chown -R asterisk:asterisk /var/lib/asterisk/agi-bin
chmod 755 /var/lib/asterisk/agi-bin/a2billing.php
ln -s /var/www/html/a2billing/common/lib /var/lib/asterisk/agi-bin/lib
Add the following extensions to /etc/asterisk/extensions_custom.conf.
[macro-dialout-trunk-predial-hook]
exten => s,1,GotoIf($["${OUT_${DIAL_TRUNK}:4:4}" = "A2B/"]?custom-freepbx-a2billing,${OUTNUM},1:2)
exten => s,2,MacroExit
[custom-freepbx-a2billing]
exten => _X.,1,DeadAGI(a2billing.php,${OUT_${DIAL_TRUNK}:8})
exten => _X.,n,Hangup()
[a2billing]
exten => _X.,1,Answer
exten => _X.,n,Wait(1)
exten => _X.,n,deadAGI(a2billing.php,1)
exten => _X.,n,Hangup
[a2billing-callback]
exten => _X.,1,deadAGI(a2billing.php,1,callback)
exten => _X.,n,Hangup
[a2billing-cid-callback]
exten => _X.,1,deadAGI(a2billing.php,1,cid-callback,34) ;last parameter is the callback area code
exten => _X.,n,Hangup
[a2billing-all-callback]
exten => _X.,1,deadAGI(a2billing.php,1,all-callback,34) ;last parameter is the callback area code
exten => _X.,n,Hangup
[a2billing-did]
exten => _X.,1,deadAGI(a2billing.php,1,did)
exten => _X.,2,Hangup
[a2billing-voucher]
exten => _X.,1,deadAGI(a2billing.php,1,voucher)
exten => _X.,n,Hangup
[custom-a2billing-did]
exten => _X.,1,deadAGI(a2billing.php,1,did)
exten => _X.,2,Hangup
[custom-a2billing]
exten => _X.,1,deadAGI(a2billing.php,1)
exten => _X.,n,Hangup
Go into FreePBX GUI>Setup>Trunks>Add Custom Trunk give it a name and add the following dial string:
This is the trunk that is used to send calls out via A2Billing. Simply select this trunk in outbound routes. The /1 refers to which agi-conf is going to be used in /etc/a2billing.conf.
Add custom destinations to FreePBX via FreePBX GUI>Tools>Custom Destinations
Custom Destination: custom-a2billing,${EXTEN},1
Destination Quick Pick: (pick destination)
Description: A2Billing - Callthrough
Custom Destination: custom-a2billing-did,${EXTEN},1
Destination Quick Pick: (pick destination)
Description: A2Billing - DID
Start or restart FreePBX
amportal restart
Recurring Services
Recurring services are handled via the /etc/crontab.
Make directory for A2Billing cron PID
mkdir -p /var/run/a2billingchown asterisk:asterisk /var/run/a2billing
Copy cron files to some permanent location such as /usr/local
mkdir -p /usr/local/a2billing
cp -R /usr/src/a2billing/Cronjobs /usr/local/a2billing/
ln -sf /var/www/html/a2billing/common/lib /usr/local/a2billing/Cronjobs/lib
chown -R asterisk:asterisk /usr/local/a2billing
Add the cron jobs to /var/spool/cron/asterisk.
# update the currency table
0 6 * * * php /usr/local/a2billing/Cronjobs/currencies_update_yahoo.php
# manage the monthly services subscription
0 6 1 * * php /usr/local/a2billing/Cronjobs/a2billing_subscription_fee.php
# To check account of each Users and send an email if the balance is less than the user have choice.
0 * * * * php /usr/local/a2billing/Cronjobs/a2billing_notify_account.php
# this script will browse all the DID that are reserve and check if the customer need to pay for it.
# bill them or warn them per email to know if they want to pay in order to keep their DIDs.
0 2 * * * php /usr/local/a2billing/Cronjobs/a2billing_bill_diduse.php
# This script will take care of the recurring service.
0 12 * * * php /usr/local/a2billing/Cronjobs/a2billing_batch_process.php
# To generate invoices and for each user.
0 6 * * * php /usr/local/a2billing/Cronjobs/a2billing_batch_billing.php
# to proceed the autodialer
*/5 * * * * php /usr/local/a2billing/Cronjobs/a2billing_batch_autodialer.php
# manage alarms
0 * * * * php /usr/local/a2billing/Cronjobs/a2billing_alarm.php
# manage archive
0 12 * * * php /usr/local/a2billing/Cronjobs/a2billing_archive_data_cront.php
#autorefill
0 10 21 * * php /usr/local/a2billing/Cronjobs/a2billing_autorefill.php
15 * * * * php /usr/local/a2billing/Cronjobs/a2billing_batch_cache.php
Add log files:
mkdir -p /var/log/a2billing
touch /var/log/a2billing/cront_a2b_alarm.log
touch /var/log/a2billing/cront_a2b_autorefill.log
touch /var/log/a2billing/cront_a2b_batch_process.log
touch /var/log/a2billing/cront_a2b_archive_data.log
touch /var/log/a2billing/cront_a2b_bill_diduse.log
touch /var/log/a2billing/cront_a2b_subscription_fee.log
touch /var/log/a2billing/cront_a2b_currency_update.log
touch /var/log/a2billing/cront_a2b_invoice.log
touch /var/log/a2billing/cront_a2b_check_account.log
touch /var/log/a2billing/a2billing_paypal.log
touch /var/log/a2billing/a2billing_epayment.log
touch /var/log/a2billing/a2billing_api_ecommerce_request.log
touch /var/log/a2billing/a2billing_api_callback_request.log
touch /var/log/a2billing/a2billing_api_card.log
touch /var/log/a2billing/a2billing_agi.log
chown -R asterisk:asterisk /var/log/a2billing
Add index file to prevent browsing of root folder
touch /var/www/html/a2billing/index.html
Log into the webpage
http://<ip-addr>/a2billing/admin
user: root
pass: changepassword
Change password
Go into System settings>Global list. Go to the bottom left and set to display all. From your web browser search for "asterisk_version". It will find that setting twice. One for Global group and one for agi-conf1 group. Change both to "1_6" even if you are running Asterisk 1.8. It does not recognize 1_8 but will still work with Asterisk 1.8.
Still in System settings>Global search for "realtime". Change that setting to "no".
Asterisk Realtime
It may be beneficial to use Asterisk Realtime with A2billing. If running Asterisk Realtime you do not need to reload every time you add/remove/change a customer. Also it allows you to share the A2billing database between multiple Aserisk/FreePBX servers if you needed to do that. I am guessing there are some performance advantages as well. If you need to create many customers it just makes more sense to use a database instead of putting them all in a flat text file.
First add the following to /etc/asterisk/extconfig.conf
[settings]
iaxusers => mysql,general,cc_iax_buddies
iaxpeers => mysql,general,cc_iax_buddies
sipusers => mysql,general,cc_sip_buddies
sippeers => mysql,general,cc_sip_buddies
extensions => mysql,general,cc_sip_buddies
Then add the following to /etc/asterisk/res_config_mysql.conf
[general]
dbhost = 127.0.0.1
dbname = mya2billing
dbuser = a2billinguser
dbpass = YOURPASS
dbport = 3306
;dbsock = /var/lib/mysql/mysql.sock
Assuming (as we did in this guide) that the dbname=mya2billing, dbuser=a2billinguser, dbpassword=YOURPASSword. Double check that these settings match /etc/a2billing.conf and substitute as necessary.
Now restart freepbx/asterisk with "amportal restart"
To check if this is working:
From Asterisk CLI>
>core show config mappings
Should produce something along the lines of:
Config Engine: mysql
===> extensions (db=general, table=cc_sip_buddies)
===> iaxpeers (db=general, table=cc_iax_buddies)
===> iaxusers (db=general, table=cc_iax_buddies)
===> sippeers (db=general, table=cc_sip_buddies)
===> sipusers (db=general, table=cc_sip_buddies)
and
>realtime load sipusers name 1234567890
Where 1234567890 is one of your existing A2billing account numbers should produce:
Column Name Column Value
-------------------- --------------------
id 1
id_cc_card 1
name 1234567890
accountcode 1234567890
regexten 1234567890
amaflags billing
callgroup
callerid NXXNXXXXXX
canreinvite YES
context a2billing
DEFAULTip
dtmfmode RFC2833
fromuser
fromdomain
host dynamic
.
.
.
.
maxcallbitrate
outboundproxy
rtpkeepalive 0
useragent
In the A2Billing GUI go into System settings>Global and search for "realtime". Change that setting to "yes".