Back to Blog Posts

Displaying Payment Gateway Balances

By Sarah / June 1st, 2021


In WHMCS 8.2, we added the ability to view payment gateway balance information in the WHMCS Admin Area. Natively, this includes displaying information from Stripe and PayPal Basic in the list of transactions at Billing > Transactions List and from Stripe in the information for individual transactions.

This blog post covers displaying balances. For more information on displaying transaction information, see Transaction Information in our Developer Documentation.

Balances and Payment Gateway Modules
The Gateway module now allows you to display the data from any payment gateway through two new classes: Balance and BalanceCollection. For developers, especially payment gateway developers, this is exciting new functionality that lets you add balance display support to any payment gateway.

By default in WHMCS, we've already implemented built-in balance display for both Stripe and PayPal Basic in the transactions list. However, when you use these new classes to customize a payment gateway module, it can include any payment gateway that you successfully use with WHMCS.

Displaying Balance Information
To display this information, use the WHMCS\Module\Gateway\Balance and WHMCS\Module\Gateway\BalanceCollection classes.

When you use these classes, we recommend performing these steps to implement them:

1. Connect to the gateway to retrieve the necessary information.
use WHMCS\Module\Gateway\Balance;
use WHMCS\Module\Gateway\BalanceCollection;

/**
*@param array $params
*
*@return BalanceCollection
*/

function yourmodulename_account_balance(array $params = []): BalanceCollection
{
    $balanceInfo = [];
    /**
     * Connect to gateway to retrieve balance information.
     */
    $postfields = [
        'account' => $params['apikey'],
    ];
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://www.example.com/api/balance');
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = curl_exec($ch);
    curl_close($ch);
         
    $balanceData = json_decode($response);

2. Add an object for the Balance class using the default label and formatting color.
Repeat this step for each of the gateway's supported currency codes that will display a different balance. For example, Stripe supports available and pending balances. However, most gateways will only have one Balance type.
foreach ($balanceData['available'] as $availableData) {
    $currencyCode = strtoupper($availableData['currency']);
    $amount[$currencyCode] = ($availableData['amount'] / 100);
 
    /**
     * Add a Balance object using the default label and format colour.
     */
    $balanceInfo[] = Balance::factory(
        $amount[$currencyCode],
        $currencyCode
    );
}

3. Add an object for the Balance class, overriding the label and color.
This is optional, and, as in the step above, you can repeat it as many times as necessary if a gateway supports different balance types.
foreach ($balanceData['pending'] as $pendingData) {
    $currencyCode = strtoupper($pendingData['currency']);
    $pending[$currencyCode] = ($pendingData['amount'] / 100);
 
    /**
     * Add a Balance object and override the default label and colour.
     */
    $balanceInfo[] = Balance::factory(
        $pending[$currencyCode],
        $currencyCode,
        'status.pending', //default label is status.available
        '#6ecacc' //default colour is #5dc560
    );
}

4. Add an object for the BalanceCollection class to accept an array of Balance objects.
It's important to note that if anything in the array isn't a Balance object, WHMCS will encounter a fatal error.
/**
     * The BalanceCollection object accepts an array containing any number of Balance objects.
     * Passing an item in the array that is not a Balance object, will cause a fatal error.
     */
    return BalanceCollection::factory(...$balanceInfo);
}

Success
For a successful use of this functionality with a payment gateway module, your code should resemble the example below:
use WHMCS\Module\Gateway\Balance;
use WHMCS\Module\Gateway\BalanceCollection;
 
/**
 * @param array $params
 *
 * @return BalanceCollection
 */
function yourmodulename_account_balance(array $params = []): BalanceCollection
{
    $balanceInfo = [];
    /**
     * Connect to gateway to retrieve balance information.
     */
    $postfields = [
        'account' => $params['apikey'],
    ];
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://www.example.com/api/balance');
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = curl_exec($ch);
    curl_close($ch);
         
    $balanceData = json_decode($response);
    foreach ($balanceData['available'] as $availableData) {
        $currencyCode = strtoupper($availableData['currency']);
        $amount[$currencyCode] = ($availableData['amount'] / 100);
 
        /**
         * Add a Balance object using the default label and format colour.
         */
        $balanceInfo[] = Balance::factory(
            $amount[$currencyCode],
            $currencyCode
        );
    }
 
    foreach ($balanceData['pending'] as $pendingData) {
        $currencyCode = strtoupper($pendingData['currency']);
        $pending[$currencyCode] = ($pendingData['amount'] / 100);
 
        /**
         * Add a Balance object and override the default label and colour.
         */
        $balanceInfo[] = Balance::factory(
            $pending[$currencyCode],
            $currencyCode,
            'status.pending', //default label is status.available
            '#6ecacc' //default colour is #5dc560
        );
    }
 
    /**
     * The BalanceCollection object accepts an array containing any number of Balance objects.
     * Passing an item in the array that is not a Balance object, will cause a fatal error.
     */
    return BalanceCollection::factoryFromItems(...$balanceInfo);
}

When you use your code in WHMCS, make sure that logged in users have the correct permissions. By default, Full Administrators have full access to payment gateway balance displays, but other admin roles will require you to enable View Gateway Balance Totals to view this information.

Next Steps
Once you upgrade to WHMCS 8.2, you can view Stripe and PayPal Basic balances easily at Billing > Transactions List.

It's also worth noting that, separately from this module and functionality, we added a new Admin Area Dashboard widget specifically for Stripe balances. You can read more about that on this blog, in our documentation, or view information on creating custom widgets for the Admin Area Dashboard here.

Liked this article? Share it