{"id":18063362,"url":"https://github.com/eugenefvdm/whmcs-api","last_synced_at":"2025-04-11T15:42:05.985Z","repository":{"id":61923510,"uuid":"420378781","full_name":"eugenefvdm/whmcs-api","owner":"eugenefvdm","description":"A testable PHP/Laravel API for WHMCS","archived":false,"fork":false,"pushed_at":"2024-11-01T05:53:08.000Z","size":149,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-06T02:34:54.781Z","etag":null,"topics":["whmcs-api"],"latest_commit_sha":null,"homepage":"https://eugenefvdm.com","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eugenefvdm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-23T10:17:10.000Z","updated_at":"2024-11-03T21:44:51.000Z","dependencies_parsed_at":"2025-04-06T02:35:02.288Z","dependency_job_id":"83783bcf-254f-40af-a2ed-065701cbcbc8","html_url":"https://github.com/eugenefvdm/whmcs-api","commit_stats":null,"previous_names":["eugenefvdm/whmcs-api","fintech-systems/whmcs-php-api"],"tags_count":10,"template":false,"template_full_name":"fintech-systems/packagist-boilerplate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eugenefvdm%2Fwhmcs-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eugenefvdm%2Fwhmcs-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eugenefvdm%2Fwhmcs-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eugenefvdm%2Fwhmcs-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eugenefvdm","download_url":"https://codeload.github.com/eugenefvdm/whmcs-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248433154,"owners_count":21102516,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["whmcs-api"],"created_at":"2024-10-31T05:10:42.629Z","updated_at":"2025-04-11T15:42:05.947Z","avatar_url":"https://github.com/eugenefvdm.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WHMCS API\n![GitHub release (latest by date)](https://img.shields.io/github/v/release/fintech-systems/whmcs-php-api) ![Tests](https://github.com/fintech-systems/whmcs-php-api/actions/workflows/tests.yml/badge.svg) ![GitHub](https://img.shields.io/github/license/eugenefvdm/whmcs-api) ![Downloads](https://img.shields.io/packagist/dt/eugenefvdm/whmcs-api)\n\nA testable WHMCS API designed to run standalone or as part of a Laravel Application\n\nRequirements:\n\n- PHP 8.2\n- WHMCS\n\n# Installation\n\n```bash\ncomposer require eugenefvdm/whmcs-api\n```\n\nPublish the configuration file:\n\n```bash\nphp artisan vendor:publish --provider=\"Eugenefvdm\\Whmcs\\WhmcsServiceProvider\" \n```\n\n## Configuration Settings `whmcs.php`\n\n```php\n\u003c?php\n\nreturn [\n    'url' =\u003e env('WHMCS_URL'),\n    'api_identifier' =\u003e env('WHMCS_API_IDENTIFIER'),\n    'api_secret' =\u003e env('WHMCS_API_SECRET'),\n    'limitnum' =\u003e env('WHMCS_LIMITNUM', 10000),\n    'debug' =\u003e env('WHMCS_DEBUG'),\n];\n```\n\n`WHMCS_URL` should be without the trialing slash.\n\n## WHMCS Setup\n\nAllow the IP address of the system connecting to WHMCS:\n\n```\nSystems Settings =\u003e General =\u003e Security =\u003e API IP Access Restriction\n```\n\nCreate API permissions:\n\n```\nSystem Settings =\u003e API credentials =\u003e Generate New API Credential\n```\n\n### Example API permissions required:\n\n- addclient\n- getclientsdetails\n- getclientsdomains\n- custom list of API calls you are developing\n\n### Example, creating a new client with custom fields:\n\n```php\ntest('it can create a new client in WHMCS', function () {\n    $customfields = base64_encode(\n        serialize(\n            [\n                8 =\u003e '50-100',\n            ]\n        )\n    );\n\n    $client = [\n        'firstname' =\u003e $this-\u003efaker-\u003efirstName,\n        'lastname' =\u003e $this-\u003efaker-\u003elastName,\n        'email' =\u003e $this-\u003efaker-\u003eemail,\n        'address1' =\u003e $this-\u003efaker-\u003enumberBetween(1, 100).' '.$this-\u003efaker-\u003estreetName,\n        'address2' =\u003e $this-\u003efaker-\u003esecondaryAddress,\n        'city' =\u003e $this-\u003efaker-\u003ecity,\n        'state' =\u003e $this-\u003efaker-\u003estate,\n        'postcode' =\u003e $this-\u003efaker-\u003epostcode,\n        'country' =\u003e config('whmcs.default_country'),\n        'phonenumber' =\u003e $this-\u003efaker-\u003ephoneNumber,\n        'password2' =\u003e bin2hex(random_bytes(8)),\n        'customfields' =\u003e $customfields,\n    ];\n\n    $result = Whmcs::addClient($client);\n\n    expect($result)-\u003etoHaveKey('result')\n        -\u003eand($result['result'] == 'success');\n})-\u003eonly();\n```\n\n### Custom API calls\n\nWHMCS removed the ability to add custom API calls, but there is a hack to get it working again. \n\nAn example of a custom API call would be to get a client by their phone number. Let's call this `getclientbyphonenumber`. At least two steps are required.\n\n1. Create a custom API call\n2. Inject the permission into the database\n\n#### Example custom API call\n\nSave the example code below here:\n`includes/api/getclientbyphoneumber.php`\n\n```php\n\u003c?php\n\nuse WHMCS\\Database\\Capsule;\n\nif (!defined(\"WHMCS\"))\n    die(\"This file cannot be accessed directly\");\n\ntry {\n    $client = Capsule::table('tblclients')\n        -\u003ewhere(\"phonenumber\", $_REQUEST['phonenumber'])\n        -\u003efirst();\n\n    if ($client) {\n        $apiresults = [\n            \"result\" =\u003e \"success\",\n            \"message\" =\u003e \"ok\",\n            'clientid' =\u003e $client-\u003eid,\n        ];\n    } else {\n        $apiresults = [\n            \"result\" =\u003e \"error\",\n            \"message\" =\u003e \"not found\",\n        ];\n    }\n} catch (Exception $e) {\n    $apiresults = [\"result\" =\u003e \"error\", \"message\" =\u003e $e-\u003egetMessage()];\n}\n```\n\nNext to use the custom API call `getclientbyphonenumber` you need to manually update `tblapi_roles` and add it there.\n\nAlso remember\nto update it every time again you make a changes in the UI because the UI will *overwrite* the custom API call.\n\nIn the example below, the JSON in the database has been updated to include the new API call `getclientbyphonenumber`.\n\n```json\n{\"addclient\":1,\"getclientsdetails\":1,\"getclientbyphonenumber\":1}\n```\n\nIf you haven't added the PHP file yet, you'll get `API Function Not Found`.\n\n# Examples\n\n## Framework Agnostic PHP\n\n```php\n\u003c?php\n\nuse Eugenefvdm\\WhmcsApi\\WhmcsApi;\n\nrequire 'vendor/autoload.php';\n\n$dotenv = Dotenv\\Dotenv::createImmutable(__DIR__);\n$dotenv-\u003eload();\n\n$server = [\n    'url'            =\u003e env('WHMCS_URL'),\n    'api_identifier' =\u003e env('WHMCS_API_IDENTIFIER'),\n    'api_secret'     =\u003e env('WHMCS_API_SECRET'),\n];\n\n$api = new WhmcsApi($server);\n\n$result = $api-\u003egetClients();\n```\n\n## Laravel\n\nPublish the configuration file:\n\n`php artisan vendor:publish --tag=whmcs-config`\n\n# Changelog\n\nSee [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n# Features\n\n## Set Server\n\nProvides the ability to connect to a secondary WHMCS server away from the Facade initiation\n\n```php\nWhmcs::setServer([\n    'url'            =\u003e env('WHMCS_URL2'),\n    'api_secret'     =\u003e env('WHMCS_API_SECRET2'),\n    'api_identifier' =\u003e env('WHMCS_API_IDENTIFIER2'),\n])\n```\n\nChange Package\n\n## Change Package\n\nFramework Agnostic PHP:\n\n```php\n$newServiceId = 5;\n\n$api = new WhmcsApi;\n$api-\u003echangePackage($newServiceId);\n```\n\nLaravel App:\n\n## Change server\n\nSince we're using a Facade instantiated when it's called,\nwe need some other way to call the constructor when we're connecting to another server.\n\n```php\npublic function setServer($server) {\n        $this-\u003eurl            = $server['url'];\n        $this-\u003eapi_identifier = $server['api_identifier'];\n        $this-\u003eapi_secret     = $server['api_secret'];\n    }\n```\n\n```php\n$newServiceId = 5;\n\nWhmcsApi::changePackage($newServiceId);\n```\n\nResult:\n\nA new package is applied to the service. If the package is linked to an API, the API will be called. \n\n# Testing\n\nBefore testing, please ensure you have copied over the `.env.example` file to `.env` as the tests use `dotenv`.\n\n```bash\ncp .env.example .env\n```\n\n## Debugging\n\nSet `WHMCS_DEBUG=true` in your `.env` file to enable debugging. This will output to Spatie Ray if it's installed.\n\n## Running the tests\n\n`./vendor/bin/pest`\n\nTo test custom API actions, use a script such as the following:\n\n`sh .scp updateclientaddon.php;./vendor/bin/pest`\n\nThe `.scp` file should have a copy command, e.g.:\n\n```bash\n#!/bin/bash\necho \"Present Working Directory:\"\npwd\necho \"Copying $1 to WHMCS install directory\"\n\ncp includes/api/$1 ../whmcs/includes/api\necho \"Done.\"\nls -la ../whmcs/includes/api/$1\n```\n\n## No errors on API actions but not working\n\nAPI actions are difficult to troubleshoot if you don't observe the server log file.\nOnly some exceptions, e.g., model problems will be caught by the Try Catch block.\nSo help tail your server log file.\nFor example, if you're using Laravel's Valet's Nginx server, do this:\n\n`tail -f ~/.valet/Log/nginx-error.log`\n\n## Invalid IP 127.0.0.1\n\nIf you get `Invalid IP 127.0.0.1` that means you haven't allowed WHMCS API access from localhost. \n\nNavigate here: https://whmcs.test/admin/configgeneral.php and make sure you add `127.0.0.1` to API IP Access Restriction.\n\n## Invalid or missing credentials\n\nIf you get `Invalid or missing credentials` that means you haven't added API roles and API credentials. Both are required before you can test. Also be sure to add them to your `.env` file:\n\n```\nWHMCS_API_IDENTIFIER=\nWHMCS_API_SECRET=\n```\n\n## Invalid Permissions: API action \"addclient\" is not allowed\n\nIf you get `Invalid Permissions: API action \"addclient\" is not allowed` that means,\nalthough you've added API roles and credentials, your roles are not set up properly for the API call.\nRevisit roles and the requisite subsection and see where you have to click the checkbox to allow this API call.\n\n## Storage folder examples\n\nThe `storage` folder has examples API responses, also used for caching during tests.\n\n# Local Editing\n\nFor local editing, add this to `composer.json`:\n\n```\n\"repositories\" : [\n        {\n            \"type\": \"path\",\n            \"url\": \"../whmcs-api\"\n        }\n    ],\n```\n\nThen in `require` section:\n\n```\n\"eugenefvdm/whmcs-api\": \"dev-main\",\n```\n\nThen do this to symlink:\n\n```bash\ncomposer require eugenefvdm/whmcs-api:dev-main\n```\n\n# License\n\nMIT\n\n# Author\n\nhello (at) eugenefvdm.com \u003cbr\u003e\nhttps://eugenefvdm.com \u003cbr\u003e\n+27 82 309–6710 \u003cbr\u003e\nI am a Laravel, hosting, and WHMCS specialist.\nContact me any time for assistance.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feugenefvdm%2Fwhmcs-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feugenefvdm%2Fwhmcs-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feugenefvdm%2Fwhmcs-api/lists"}