{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"type":"markdown"},"seo":{"title":"Displaying Balances","description":"Developer documentation for the WHMCS API — the","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"displaying-balances","__idx":0},"children":["Displaying Balances"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["WHMCS 8.2 adds the ability to display payment gateway balances directly in the WHMCS Admin Area. By default, these balances are available for Stripe and PayPal Basic at ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Billing > Transactions"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["By default, balance information will display in the Admin Area for admins with the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Full Administrator"]}," role. To allow other admin roles to see balance information, enable ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["View Gateway Balances"]}," for the desired role."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can display the balances for other payment gateways through two payment gateway module classes: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BalanceInterface"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BalanceCollection"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"example","__idx":1},"children":["Example"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Successful implementations of this functionality within a payment gateway module should resemble the example below:"," ","You can display the balances for other payment gateways through two payment gateway module classes: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BalanceInterface"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BalanceCollection"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"connecting-to-gateways","__idx":2},"children":["Connecting to Gateways"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before you can retrieve balance information, connect to the desired gateway. For example:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"<?php\n\nuse WHMCS\\Module\\Gateway\\Balance;\nuse WHMCS\\Module\\Gateway\\BalanceCollection;\n\n/**\n * @param array $params\n *\n * @return BalanceCollection\n */\nfunction yourmodulename_account_balance(array $params = []): BalanceCollection\n{\n    $balanceInfo = [];\n\n    // Connect to gateway to retrieve balance information.\n    $postfields = [\n        'account' => $params['apikey'],\n    ];\n\n    $ch = curl_init();\n    curl_setopt($ch, CURLOPT_URL, 'https://www.example.com/api/balance');\n    curl_setopt($ch, CURLOPT_POST, 1);\n    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields));\n    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);\n    $response = curl_exec($ch);\n    curl_close($ch);\n\n    $balanceData = json_decode($response, true);\n\n    // Add Balance objects as many times as needed for each gateway\n    // balance type (most gateways will only have one).\n    foreach ($balanceData['available'] as $availableData) {\n        $currencyCode = strtoupper($availableData['currency']);\n        $amount[$currencyCode] = ($availableData['amount'] / 100);\n\n        // Add a Balance object using the default label and format color.\n        $balanceInfo[] = Balance::factory(\n            $amount[$currencyCode],\n            $currencyCode\n        );\n    }\n\n    foreach ($balanceData['pending'] as $pendingData) {\n        $currencyCode = strtoupper($pendingData['currency']);\n        $pending[$currencyCode] = ($pendingData['amount'] / 100);\n\n        // Add a Balance object overriding the default label and color.\n        $balanceInfo[] = Balance::factory(\n            $pending[$currencyCode],\n            $currencyCode,\n            'status.pending', //The default label is status.available.\n            '#6ecacc' //The default color hex code is #5dc560.\n        );\n    }\n\n    // The BalanceCollection object accepts an array containing any number of\n    // Balance objects. Passing an item in the array that is not a Balance\n    // object will cause a fatal error.\n    return BalanceCollection::factoryFromItems(...$balanceInfo);\n}\n"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"the-balance-class","__idx":3},"children":["The Balance Class"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After you connect to the gateway, add an object for the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Balance"]}," class."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can repeat this process as many times as needed for each balance type that the gateway supports (for example, ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Available"]}," and ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Pending"]},"). However, most gateways will only have one ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Balance"]}," type."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can do this in two ways:"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"using-the-default-label-and-color","__idx":4},"children":["Using the default label and color"]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You must add an object for the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Balance"]}," class using this method ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["at least"]}," once."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"foreach ($balanceData['available'] as $availableData) {\n    $currencyCode = strtoupper($availableData['currency']);\n    $amount[$currencyCode] = ($availableData['amount'] / 100);\n\n    // Add a Balance object using the default label and format colour.\n    $balanceInfo[] = Balance::factory(\n        $amount[$currencyCode],\n        $currencyCode\n    );\n}\n"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"overriding-the-label-and-color","__idx":5},"children":["Overriding the label and color"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Adding an object that overrides the label, color, or both is optional. To override the label and color, add the desired label and hex color code as in the example below:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"$balanceInfo[] = Balance::factory(\n    $pending[$currencyCode],\n    $currencyCode,\n    'status.pending', // Default label is 'status.available'\n    '#6ecacc' //default colour is #5dc560\n);\n"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"the-balancecollection-class","__idx":6},"children":["The BalanceCollection Class"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Next, add an object to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BalanceCollection"]}," class. It should accept an array of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Balance"]}," objects."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If anything in the array ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["isn't"]}," a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Balance"]}," object, WHMCS will encounter a fatal error."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"// The BalanceCollection object accepts an array containing any number of Balance objects.\n// Passing an item in the array that is not a Balance object will cause a fatal error.\nreturn BalanceCollection::factoryFromItems(...$balanceInfo);\n"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"required-permissions","__idx":7},"children":["Required Permissions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["By default, balance information will display in the Admin Area for admins with the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Full Administrator"]}," role. To allow other admin roles to see balance information, enable ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["View Gateway Balances"]}," for the desired role."]}]},"headings":[{"value":"Displaying Balances","id":"displaying-balances","depth":1},{"value":"Example","id":"example","depth":2},{"value":"Connecting to Gateways","id":"connecting-to-gateways","depth":2},{"value":"The Balance Class","id":"the-balance-class","depth":2},{"value":"Using the default label and color","id":"using-the-default-label-and-color","depth":3},{"value":"Overriding the label and color","id":"overriding-the-label-and-color","depth":3},{"value":"The BalanceCollection Class","id":"the-balancecollection-class","depth":2},{"value":"Required Permissions","id":"required-permissions","depth":2}],"frontmatter":{"title":"Displaying Balances","seo":{"title":"Displaying Balances"}},"lastModified":"2026-08-03T17:00:42.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/payment-gateways/displaying-balances","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}