Custom integration

Custom integration and generic mode

BlissRADIUS Embedded can be integrated with your own built billing software by using generic mode that comes with program. Process is straight forward and method of interaction is same as with WHMCS, Blesta or any other billing software. Once customization is done, installation procedure is not different from any other host type.

Customization, in its simplest form, requires from your software to have HTTP receiver (web page) for all API requests coming from BlissRADIUS Embedded. This can be done as easily as adding one PHP script to web server that is running your billing software. Your software must periodically call BlissRADIUS Embedded API to notify it when certain events occur, and to fetch pieces of HTML code that are injected into your billing web pages.

Example

This example assumes your billing software is Linux or Windows based PHP/MySQL/Apache solution served as a local web site at http://localhost/my_billing. BlissRADIUS Embedded is installed and you are using web browser on/from the same computer.

Handling incoming requests

First thing you need is to add script to your software that will be called by BlissRADIUS Embedded when it needs to fetch service data or send email via your software. Create PHP file that will be accessible at URL http://localhost/my_billing/api.php and save contents below:

<?php

// All API responses are JSON encoded dictionary to UTF-8 text. See example below.

// Optional IP address check, you might want to restrict who can call API. This permits only localhost.
// Note: if there is proxy or NAT involved, REMOTE_ADDR will not always return correct address of client.
$remote_addr = $_SERVER["REMOTE_ADDR"];
if ($remote_addr != "127.0.0.1" && $remote_addr != "::1") {
    echo json_encode(array("Result" => "error", "Message" => "access denied to ".$remote_addr));
    return;
}

// API username/password check, if credentials do not match then reject call. 
// This permits only blissembed as default username and password.
// It demonstrates how digest is created from salt, username and password using MD5 algorithm.
// BlissRADIUS Embedded sends api_username, api_salt and api_digest with every API request.
const USERNAME = "blissembed";
const PASSWORD = "blissembed";
$api_username = @$_REQUEST["api_username"];
$api_salt = @$_REQUEST["api_salt"];
$api_digest = @$_REQUEST["api_digest"];
if ($api_username != USERNAME || md5($api_salt.":".$api_username.":".PASSWORD) != $api_digest){
    echo json_encode(array("Result" => "error", "Message" => "wrong credentials for ".$api_username));
    return;
}


// Two API actions are handled, get_service and send_email. api_action parameter contains desired action.
// Each action comes with own set of additional parameters and returns own response.
$api_action = @$_REQUEST["api_action"];
if ($api_action != "send_email" && $api_action != "get_service"){
    echo json_encode(array("Result" => "error", "Message" => "unsupported action ".$api_action));
    return;
}

// Handle action send_email. This is used when BlissRADIUS Embedded is configured to send email via host API.
if ($api_action == "send_email"){

    // Additional paremeters provided by this action
    $address = @$_REQUEST["address"];
    $subject = @$_REQUEST["subject"];
    $text = @$_REQUEST["text"];
    $service_id = @$_REQUEST["service_id"];
    $client_id = @$_REQUEST["client_id"];

    // Send email, but first check for correctness of address, service_id and client_id.
    // There are no guarantees address will be valid, or that service_id or client_id point to existing entities.

    // Confirm success
    echo json_encode(array("Result" => "success", "Message" => ""));
    return;
}


// Handle action get_service

// Provided are either one of these parameters: id for exact match, or username for service username lookup.
// Lookup by id is simple and quick operation if you use primary keys of database.
// Username lookup must be case insensitive. Newer/active services should take precedence if there are multiple services with same username.
$service_id = @$_REQUEST["id"];
$service_username = @$_REQUEST["username"];

// For this example, both parameters are ignored and same test service is always returned.
// It is completely up to you to organize service/product/client/topup data as you desire and extract data from it into meaningful service details.
// Only thing important is that returned response must contain these fields.
$response = array(
    "Result" => "success", // "success" or "error", error is set only if there is some kind of programming/database error
    "Message" => "", // description of error that prevented API call
    "Found" => true, // if service is not found this must be set to false along with "Result" => "success"
    "Service" => array( // not present if service is not found
        "Id" => 1, // integer ID of service
        "Enabled" => true, // true or false if disabled/expired/suspended etc.
        "Created" => "2001-01-01T23:00:00+01:00", // ISO 8601 date format, use PHP date() function with "c" format if needed
        "Username" => "test", // lower case username
        "Password" => "test123", // plain text password, RADIUS authentication methods can't work with password hashes
        "Options" => "Permanent = no \n Duration months = 1000 \n GB limit = 10.0 \n Session attributes = Mikrotik-Rate-Limit=512k/5M", // aggregate of product + service options, product options first, separated by newline
        "Client" => "John Doe", // human readable client name (first, last name, organization etc.)
        "Email" => "john@example.com, john2@test.com", // comma separated list of email addresses that receive notifications
        "Phone" => "123456789", // comma separated list of mobile phone number that receive SMS notifications
        "Product" => "Test product 10Gbs", // human readable product name
        "ProductId" => 123, // integer ID of product
        "ClientId" => 221, // integer ID of client
        "Topups" => array( // array of all topups for service
            array(
                "Created" => date("c", strtotime("now")), // ISO 8601 date format, affects topup application (expired, not activated yet etc.)
                "Enabled" => true, // true or false if disabled/suspended
                "Option" => "GB limit", // canonical option name
                "Amount" => 100.0, // amount as floating point number
            ),
            array(
                "Created" => date("c", strtotime("now")),
                "Enabled" => false,
                "Option" => "GB limit",
                "Amount" => 50.0,
            ),
        ),
    ),
    "HostVersion" => "1.0.0", // optional, version string of your software
    "HostTime" => date("c", strtotime("now")), // optional but recommended, current time at host
);

// Return response
echo json_encode($response);

?>

Now login to your BlissRADIUS Embedded web area at http://localhost:9071 and under Config > Host API set http://localhost/my_billing/api.php as API URL. Make sure that blissembed is set as username and password, then press Test API button. If everything is correct you will get confirmation that host is responding correctly.

Change URL in browser address bar to http://localhost:9071/service?id=1 to open service details page. You should be able to see full service details fetched from PHP script you have just created.

This is basic principle how things work. Next step, once you complete this tutorial, is to modify script to query real data from your database and return real service information.

Calling back when changes occur

BlissRADIUS Embedded caches all service data fetched from host and stores it locally. This is required for performance reasons. Without it host would have to respond to hundreds of requests per second, which is out of reach for vast majority of billing software solutions.

Because of caching BlissRADIUS Embedded can't know if service data is up to date. It is up to host to notify BlissRADIUS Embedded when changes occur and instruct it to empty cache for services changed.

Your billing software must make empty_cache API call to BlissRADIUS Embedded every time this happens directly or indirectly.

Empty cache by using these parameters after these events:

Empty whole cache (call without parameters) is used as last resort if some change in your billing software affect services in a way not described above. This can be expensive operation as reloading large number of services may temporally overload host software.

If you suspect cache is not up to date for a service it will be once you open service details page in BlissRADIUS Embedded as this always reloads cache.

Example code below is implementation of function to call BlissRADIUS Embedded API using PHP and cURL:

<?php

// You might want to have API URL configurable separately, and not passed as parameter with every function call.
define("BLISSEMBED_API_URL", "http://localhost:9071/api");

// Calls BlissRADIUS Embedded API at URL with action and optional parameters provided as associative array.
// Returns array with two elements (bool, string) with boolean success and response text/error message.
function blissembed_api_call($action, $params=array()){

    $params["action"] = $action; // add to list of parameters

    $c = curl_init();
    curl_setopt($c, CURLOPT_URL, BLISSEMBED_API_URL);
    curl_setopt($c, CURLOPT_POST, 1);
    curl_setopt($c, CURLOPT_HEADER, 0);
    curl_setopt($c, CURLOPT_POSTFIELDS, http_build_query($params));
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 3);
    $data = curl_exec($c);
    $error = curl_error($c); // will be empty string if no error
    curl_close($c);
    if ($data === false) {
        return array(false, "server at ".BLISSEMBED_API_URL." is unreachable: PHP-cURL error: $error");
    }

    $data = explode("\n", $data, 2);
    if (count($data) == 2)
        return array($data[0] == "SUCCESS", $data[1]);
    else 
        return array(false, "response from ".BLISSEMBED_API_URL." is invalid");
}

?>

Using function implemented you can now call BlissRADIUS Embedded through your PHP code and instruct it to empty cache for service with ID 7 because it was changed:

<?php

// Making changes to service ID 7
// .....

// Empty cache when changes done
blissembed_api_call("empty_cache", array("service_id" => 7));

?>

UI integration

Pieces of BlissRADIUS Embedded web interfaces can be injected in HTML code of your billing software. Make following API calls to BlissRADIUS Embedded to fetch them:

Example code below shows how you can fetch HTML code to inject into your web page using function implemented earlier:

<?php

// Prepare to build service report page in admin area for service ID 7

// Fetch data
$response = blissembed_api_call("html_service_admin", array("id" => 7));

if ($response[0] === true){
    $html_code = $response[1];

    // Inject $html_code into your web page
    // .....

} else {
    $error_message = $response[1];

    // Show $error_message in page with notification that server is unavailable or that there was a problem
    // ....
}

?>

Database structure

It is up to you to organize database structure of your billing software as you desire. Below is description of concepts used by BlissRADIUS Embedded, understanding them may help you with customization:

BlissRADIUS Embedded knows nothing about concepts like payments, transactions, currencies, recurring billing etc. It is up to your software to keep track of those things, and if needed, change service properties. Eg. if monthly billed service fails to renew then change status from active to suspended and inform BlissRADIUS Embedded to reload service.

Tips

2025-03-16
Referral program is active, existing users can win bonus license time if they bring new customers in.
2025-03-02
BlissRADIUS Embedded™ 1.16 is out with new features.
2024-09-27
BlissRADIUS Embedded™ 1.15 is out with postpaid license support.
2024-09-19
We are introducing changes to payment methods. See Home page for more details.
2023-07-06
BlissRADIUS Embedded™ 1.14 is out with new features.
2022-11-18
BlissRADIUS Embedded™ 1.13 is released with new fixes and features.
2021-12-31
BlissRADIUS Embedded™ 1.12 is out with new features.
2021-06-22
Volume discount for monthly BlissRADIUS™ licenses is available now.