├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── modules └── registrars │ └── registrarmodule │ ├── hooks.php │ ├── lib │ ├── ApiClient.php │ └── README.md │ ├── logo.png │ └── registrarmodule.php ├── phpunit.xml.dist ├── tests ├── WHMCSSampleRegistrarModuleTest.php └── _bootstrap.php └── whmcs.json /.gitignore: -------------------------------------------------------------------------------- 1 | # PHPStorm 2 | .idea 3 | 4 | # Composer 5 | composer.phar 6 | composer.lock 7 | vendor/* 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 WHMCS, Limited 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WHMCS Sample Registrar Module # 2 | 3 | ## Summary ## 4 | 5 | Registrar Modules allow you to create modules that allow for the 6 | registration and management of domain names in WHMCS. 7 | 8 | The sample files here demonstrates how a registrar module for WHMCS should 9 | be structured and exercises all supported functionality. 10 | 11 | For more information, please refer to the documentation at: 12 | 13 | https://developers.whmcs.com/domain-registrars/ 14 | 15 | ## Getting Started 16 | 17 | Clone the sample registrar module locally: 18 | 19 | ```bash 20 | git clone git@github.com:WHMCS/sample-registrar-module.git 21 | ``` 22 | 23 | Rename the module directory and file to your desired module name: 24 | 25 | ```bash 26 | mv modules/registrars/registrarmodule/registrarmodule.php modules/registrars/registrarmodule/newmodule.php 27 | mv modules/registrars/registrarmodule/ modules/registrars/newmodule/ 28 | ``` 29 | 30 | Open the newmodule.php file and replace all occurencies of `registrarmodule_` with the new name, in this instance `newmodule_`. 31 | 32 | Login to the WHMCS Admin Area and navigate to Setup > Products > Domain Registrars to activate. 33 | 34 | ## Recommended Module Content ## 35 | 36 | The recommended structure of a registrar module is as follows. 37 | 38 | ``` 39 | registrarmodule/ 40 | |- lib/ 41 | |- templates/ 42 | |- tests/ 43 | | hooks.php 44 | | logo.png 45 | | registrarmodule.php 46 | ``` 47 | 48 | ## Minimum Requirements ## 49 | 50 | For the latest WHMCS minimum system requirements, please refer to 51 | https://docs.whmcs.com/System_Requirements 52 | 53 | We recommend your module follows the same minimum requirements wherever 54 | possible. 55 | 56 | ## Tests ## 57 | 58 | We strongly encourage you to write unit tests for your work. Within this SDK we 59 | provide a sample unit test based upon the widely used PHPUnit. 60 | 61 | ## Useful Resources 62 | * [Developer Resources](https://developers.whmcs.com/) 63 | * [Hook Documentation](https://developers.whmcs.com/hooks/) 64 | * [API Documentation](https://developers.whmcs.com/api/) 65 | 66 | [WHMCS Limited](https://www.whmcs.com) 67 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "whmcs/sample-registrar-module", 3 | "description": "Sample Registrar Module for WHMCS Billing Automation Platform", 4 | "keywords": [ 5 | "whmcs", 6 | "web host automation platform", 7 | "registrar module", 8 | "domain registrar module" 9 | ], 10 | "homepage": "https://www.whmcs.com/", 11 | "license": "MIT", 12 | "authors": [ 13 | { 14 | "name": "WHMCS Development Team", 15 | "email": "development@whmcs.com", 16 | "homepage": "https://www.whmcs.com/", 17 | "role": "Developer" 18 | } 19 | ], 20 | "support": { 21 | "email": "support@whmcs.com", 22 | "forum": "https://forums.whmcs.com/", 23 | "wiki": "https://developers.whmcs.com/" 24 | }, 25 | "require-dev": { 26 | "phpunit/phpunit": "@stable" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/registrars/registrarmodule/hooks.php: -------------------------------------------------------------------------------- 1 | 62 | Your widget output goes here... 63 | 64 | EOF; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /modules/registrars/registrarmodule/lib/ApiClient.php: -------------------------------------------------------------------------------- 1 | results = $this->processResponse($response); 44 | 45 | logModuleCall( 46 | 'Registrarmodule', 47 | $action, 48 | $postfields, 49 | $response, 50 | $this->results, 51 | array( 52 | $postfields['username'], // Mask username & password in request/response data 53 | $postfields['password'], 54 | ) 55 | ); 56 | 57 | if ($this->results === null && json_last_error() !== JSON_ERROR_NONE) { 58 | throw new \Exception('Bad response received from API'); 59 | } 60 | 61 | return $this->results; 62 | } 63 | 64 | /** 65 | * Process API response. 66 | * 67 | * @param string $response 68 | * 69 | * @return array 70 | */ 71 | public function processResponse($response) 72 | { 73 | return json_decode($response, true); 74 | } 75 | 76 | /** 77 | * Get from response results. 78 | * 79 | * @param string $key 80 | * 81 | * @return string 82 | */ 83 | public function getFromResponse($key) 84 | { 85 | return isset($this->results[$key]) ? $this->results[$key] : ''; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /modules/registrars/registrarmodule/lib/README.md: -------------------------------------------------------------------------------- 1 | Include libraries and third party modules here. 2 | -------------------------------------------------------------------------------- /modules/registrars/registrarmodule/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WHMCS/sample-registrar-module/78881ca9b9b75436c30246dabd104ae1d8e674ab/modules/registrars/registrarmodule/logo.png -------------------------------------------------------------------------------- /modules/registrars/registrarmodule/registrarmodule.php: -------------------------------------------------------------------------------- 1 | 'Sample Registrar Module for WHMCS', 60 | 'APIVersion' => '1.1', 61 | ); 62 | } 63 | 64 | /** 65 | * Define registrar configuration options. 66 | * 67 | * The values you return here define what configuration options 68 | * we store for the module. These values are made available to 69 | * each module function. 70 | * 71 | * You can store an unlimited number of configuration settings. 72 | * The following field types are supported: 73 | * * Text 74 | * * Password 75 | * * Yes/No Checkboxes 76 | * * Dropdown Menus 77 | * * Radio Buttons 78 | * * Text Areas 79 | * 80 | * @return array 81 | */ 82 | function registrarmodule_getConfigArray() 83 | { 84 | return [ 85 | // Friendly display name for the module 86 | 'FriendlyName' => [ 87 | 'Type' => 'System', 88 | 'Value' => 'Sample Registrar Module for WHMCS', 89 | ], 90 | // a text field type allows for single line text input 91 | 'APIUsername' => [ 92 | 'FriendlyName' => 'API Username', 93 | 'Type' => 'text', 94 | 'Size' => '25', 95 | 'Default' => '1024', 96 | 'Description' => 'Enter in megabytes', 97 | ], 98 | // a password field type allows for masked text input 99 | 'APIKey' => [ 100 | 'FriendlyName' => 'API Password', 101 | 'Type' => 'password', 102 | 'Size' => '25', 103 | 'Default' => '', 104 | 'Description' => 'Enter secret value here', 105 | ], 106 | // the yesno field type displays a single checkbox option 107 | 'TestMode' => [ 108 | 'FriendlyName' => 'Test Mode', 109 | 'Type' => 'yesno', 110 | 'Description' => 'Tick to enable', 111 | ], 112 | // the dropdown field type renders a select menu of options 113 | 'AccountMode' => [ 114 | 'FriendlyName' => 'Account Mode', 115 | 'Type' => 'dropdown', 116 | 'Options' => [ 117 | 'option1' => 'Display Value 1', 118 | 'option2' => 'Second Option', 119 | 'option3' => 'Another Option', 120 | ], 121 | 'Description' => 'Choose one', 122 | ], 123 | // the radio field type displays a series of radio button options 124 | 'EmailPreference' => [ 125 | 'FriendlyName' => 'Email Preference', 126 | 'Type' => 'radio', 127 | 'Options' => 'First Option,Second Option,Third Option', 128 | 'Description' => 'Choose your preference', 129 | ], 130 | // the textarea field type allows for multi-line text input 131 | 'Email' => [ 132 | 'FriendlyName' => 'Email', 133 | 'Type' => 'textarea', 134 | 'Rows' => '3', 135 | 'Cols' => '60', 136 | 'Description' => 'Freeform multi-line text input field', 137 | ], 138 | ]; 139 | } 140 | 141 | /** 142 | * Register a domain. 143 | * 144 | * Attempt to register a domain with the domain registrar. 145 | * 146 | * This is triggered when the following events occur: 147 | * * Payment received for a domain registration order 148 | * * When a pending domain registration order is accepted 149 | * * Upon manual request by an admin user 150 | * 151 | * @param array $params common module parameters 152 | * 153 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 154 | * 155 | * @return array 156 | */ 157 | function registrarmodule_RegisterDomain($params) 158 | { 159 | // user defined configuration values 160 | $userIdentifier = $params['APIUsername']; 161 | $apiKey = $params['APIKey']; 162 | $testMode = $params['TestMode']; 163 | $accountMode = $params['AccountMode']; 164 | $emailPreference = $params['EmailPreference']; 165 | 166 | // registration parameters 167 | $sld = $params['sld']; 168 | $tld = $params['tld']; 169 | $registrationPeriod = $params['regperiod']; 170 | 171 | /** 172 | * Nameservers. 173 | * 174 | * If purchased with web hosting, values will be taken from the 175 | * assigned web hosting server. Otherwise uses the values specified 176 | * during the order process. 177 | */ 178 | $nameserver1 = $params['ns1']; 179 | $nameserver2 = $params['ns2']; 180 | $nameserver3 = $params['ns3']; 181 | $nameserver4 = $params['ns4']; 182 | $nameserver5 = $params['ns5']; 183 | 184 | // registrant information 185 | $firstName = $params["firstname"]; 186 | $lastName = $params["lastname"]; 187 | $fullName = $params["fullname"]; // First name and last name combined 188 | $companyName = $params["companyname"]; 189 | $email = $params["email"]; 190 | $address1 = $params["address1"]; 191 | $address2 = $params["address2"]; 192 | $city = $params["city"]; 193 | $state = $params["state"]; // eg. TX 194 | $stateFullName = $params["fullstate"]; // eg. Texas 195 | $postcode = $params["postcode"]; // Postcode/Zip code 196 | $countryCode = $params["countrycode"]; // eg. GB 197 | $countryName = $params["countryname"]; // eg. United Kingdom 198 | $phoneNumber = $params["phonenumber"]; // Phone number as the user provided it 199 | $phoneCountryCode = $params["phonecc"]; // Country code determined based on country 200 | $phoneNumberFormatted = $params["fullphonenumber"]; // Format: +CC.xxxxxxxxxxxx 201 | 202 | /** 203 | * Admin contact information. 204 | * 205 | * Defaults to the same as the client information. Can be configured 206 | * to use the web hosts details if the `Use Clients Details` option 207 | * is disabled in Setup > General Settings > Domains. 208 | */ 209 | $adminFirstName = $params["adminfirstname"]; 210 | $adminLastName = $params["adminlastname"]; 211 | $adminCompanyName = $params["admincompanyname"]; 212 | $adminEmail = $params["adminemail"]; 213 | $adminAddress1 = $params["adminaddress1"]; 214 | $adminAddress2 = $params["adminaddress2"]; 215 | $adminCity = $params["admincity"]; 216 | $adminState = $params["adminstate"]; // eg. TX 217 | $adminStateFull = $params["adminfullstate"]; // eg. Texas 218 | $adminPostcode = $params["adminpostcode"]; // Postcode/Zip code 219 | $adminCountry = $params["admincountry"]; // eg. GB 220 | $adminPhoneNumber = $params["adminphonenumber"]; // Phone number as the user provided it 221 | $adminPhoneNumberFormatted = $params["adminfullphonenumber"]; // Format: +CC.xxxxxxxxxxxx 222 | 223 | // domain addon purchase status 224 | $enableDnsManagement = (bool) $params['dnsmanagement']; 225 | $enableEmailForwarding = (bool) $params['emailforwarding']; 226 | $enableIdProtection = (bool) $params['idprotection']; 227 | 228 | /** 229 | * Premium domain parameters. 230 | * 231 | * Premium domains enabled informs you if the admin user has enabled 232 | * the selling of premium domain names. If this domain is a premium name, 233 | * `premiumCost` will contain the cost price retrieved at the time of 234 | * the order being placed. The premium order should only be processed 235 | * if the cost price now matches the previously fetched amount. 236 | */ 237 | $premiumDomainsEnabled = (bool) $params['premiumEnabled']; 238 | $premiumDomainsCost = $params['premiumCost']; 239 | 240 | // Build post data 241 | $postfields = array( 242 | 'username' => $userIdentifier, 243 | 'password' => $apiKey, 244 | 'testmode' => $testMode, 245 | 'domain' => $sld . '.' . $tld, 246 | 'years' => $registrationPeriod, 247 | 'nameservers' => array( 248 | 'ns1' => $nameserver1, 249 | 'ns2' => $nameserver2, 250 | 'ns3' => $nameserver3, 251 | 'ns4' => $nameserver4, 252 | 'ns5' => $nameserver5, 253 | ), 254 | 'contacts' => array( 255 | 'registrant' => array( 256 | 'firstname' => $firstName, 257 | 'lastname' => $lastName, 258 | 'companyname' => $companyName, 259 | 'email' => $email, 260 | 'address1' => $address1, 261 | 'address2' => $address2, 262 | 'city' => $city, 263 | 'state' => $state, 264 | 'zipcode' => $postcode, 265 | 'country' => $countryCode, 266 | 'phonenumber' => $phoneNumberFormatted, 267 | ), 268 | 'tech' => array( 269 | 'firstname' => $adminFirstName, 270 | 'lastname' => $adminLastName, 271 | 'companyname' => $adminCompanyName, 272 | 'email' => $adminEmail, 273 | 'address1' => $adminAddress1, 274 | 'address2' => $adminAddress2, 275 | 'city' => $adminCity, 276 | 'state' => $adminState, 277 | 'zipcode' => $adminPostcode, 278 | 'country' => $adminCountry, 279 | 'phonenumber' => $adminPhoneNumberFormatted, 280 | ), 281 | ), 282 | 'dnsmanagement' => $enableDnsManagement, 283 | 'emailforwarding' => $enableEmailForwarding, 284 | 'idprotection' => $enableIdProtection, 285 | ); 286 | 287 | if ($premiumDomainsEnabled && $premiumDomainsCost) { 288 | $postfields['accepted_premium_cost'] = $premiumDomainsCost; 289 | } 290 | 291 | try { 292 | $api = new ApiClient(); 293 | $api->call('Register', $postfields); 294 | 295 | return array( 296 | 'success' => true, 297 | ); 298 | 299 | } catch (\Exception $e) { 300 | return array( 301 | 'error' => $e->getMessage(), 302 | ); 303 | } 304 | } 305 | 306 | /** 307 | * Initiate domain transfer. 308 | * 309 | * Attempt to create a domain transfer request for a given domain. 310 | * 311 | * This is triggered when the following events occur: 312 | * * Payment received for a domain transfer order 313 | * * When a pending domain transfer order is accepted 314 | * * Upon manual request by an admin user 315 | * 316 | * @param array $params common module parameters 317 | * 318 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 319 | * 320 | * @return array 321 | */ 322 | function registrarmodule_TransferDomain($params) 323 | { 324 | // user defined configuration values 325 | $userIdentifier = $params['APIUsername']; 326 | $apiKey = $params['APIKey']; 327 | $testMode = $params['TestMode']; 328 | $accountMode = $params['AccountMode']; 329 | $emailPreference = $params['EmailPreference']; 330 | 331 | // registration parameters 332 | $sld = $params['sld']; 333 | $tld = $params['tld']; 334 | $registrationPeriod = $params['regperiod']; 335 | $eppCode = $params['eppcode']; 336 | 337 | /** 338 | * Nameservers. 339 | * 340 | * If purchased with web hosting, values will be taken from the 341 | * assigned web hosting server. Otherwise uses the values specified 342 | * during the order process. 343 | */ 344 | $nameserver1 = $params['ns1']; 345 | $nameserver2 = $params['ns2']; 346 | $nameserver3 = $params['ns3']; 347 | $nameserver4 = $params['ns4']; 348 | $nameserver5 = $params['ns5']; 349 | 350 | // registrant information 351 | $firstName = $params["firstname"]; 352 | $lastName = $params["lastname"]; 353 | $fullName = $params["fullname"]; // First name and last name combined 354 | $companyName = $params["companyname"]; 355 | $email = $params["email"]; 356 | $address1 = $params["address1"]; 357 | $address2 = $params["address2"]; 358 | $city = $params["city"]; 359 | $state = $params["state"]; // eg. TX 360 | $stateFullName = $params["fullstate"]; // eg. Texas 361 | $postcode = $params["postcode"]; // Postcode/Zip code 362 | $countryCode = $params["countrycode"]; // eg. GB 363 | $countryName = $params["countryname"]; // eg. United Kingdom 364 | $phoneNumber = $params["phonenumber"]; // Phone number as the user provided it 365 | $phoneCountryCode = $params["phonecc"]; // Country code determined based on country 366 | $phoneNumberFormatted = $params["fullphonenumber"]; // Format: +CC.xxxxxxxxxxxx 367 | 368 | /** 369 | * Admin contact information. 370 | * 371 | * Defaults to the same as the client information. Can be configured 372 | * to use the web hosts details if the `Use Clients Details` option 373 | * is disabled in Setup > General Settings > Domains. 374 | */ 375 | $adminFirstName = $params["adminfirstname"]; 376 | $adminLastName = $params["adminlastname"]; 377 | $adminCompanyName = $params["admincompanyname"]; 378 | $adminEmail = $params["adminemail"]; 379 | $adminAddress1 = $params["adminaddress1"]; 380 | $adminAddress2 = $params["adminaddress2"]; 381 | $adminCity = $params["admincity"]; 382 | $adminState = $params["adminstate"]; // eg. TX 383 | $adminStateFull = $params["adminfullstate"]; // eg. Texas 384 | $adminPostcode = $params["adminpostcode"]; // Postcode/Zip code 385 | $adminCountry = $params["admincountry"]; // eg. GB 386 | $adminPhoneNumber = $params["adminphonenumber"]; // Phone number as the user provided it 387 | $adminPhoneNumberFormatted = $params["adminfullphonenumber"]; // Format: +CC.xxxxxxxxxxxx 388 | 389 | // domain addon purchase status 390 | $enableDnsManagement = (bool) $params['dnsmanagement']; 391 | $enableEmailForwarding = (bool) $params['emailforwarding']; 392 | $enableIdProtection = (bool) $params['idprotection']; 393 | 394 | /** 395 | * Premium domain parameters. 396 | * 397 | * Premium domains enabled informs you if the admin user has enabled 398 | * the selling of premium domain names. If this domain is a premium name, 399 | * `premiumCost` will contain the cost price retrieved at the time of 400 | * the order being placed. The premium order should only be processed 401 | * if the cost price now matches that previously fetched amount. 402 | */ 403 | $premiumDomainsEnabled = (bool) $params['premiumEnabled']; 404 | $premiumDomainsCost = $params['premiumCost']; 405 | 406 | // Build post data 407 | $postfields = array( 408 | 'username' => $userIdentifier, 409 | 'password' => $apiKey, 410 | 'testmode' => $testMode, 411 | 'domain' => $sld . '.' . $tld, 412 | 'eppcode' => $eppCode, 413 | 'nameservers' => array( 414 | 'ns1' => $nameserver1, 415 | 'ns2' => $nameserver2, 416 | 'ns3' => $nameserver3, 417 | 'ns4' => $nameserver4, 418 | 'ns5' => $nameserver5, 419 | ), 420 | 'years' => $registrationPeriod, 421 | 'contacts' => array( 422 | 'registrant' => array( 423 | 'firstname' => $firstName, 424 | 'lastname' => $lastName, 425 | 'companyname' => $companyName, 426 | 'email' => $email, 427 | 'address1' => $address1, 428 | 'address2' => $address2, 429 | 'city' => $city, 430 | 'state' => $state, 431 | 'zipcode' => $postcode, 432 | 'country' => $countryCode, 433 | 'phonenumber' => $phoneNumberFormatted, 434 | ), 435 | 'tech' => array( 436 | 'firstname' => $adminFirstName, 437 | 'lastname' => $adminLastName, 438 | 'companyname' => $adminCompanyName, 439 | 'email' => $adminEmail, 440 | 'address1' => $adminAddress1, 441 | 'address2' => $adminAddress2, 442 | 'city' => $adminCity, 443 | 'state' => $adminState, 444 | 'zipcode' => $adminPostcode, 445 | 'country' => $adminCountry, 446 | 'phonenumber' => $adminPhoneNumberFormatted, 447 | ), 448 | ), 449 | 'dnsmanagement' => $enableDnsManagement, 450 | 'emailforwarding' => $enableEmailForwarding, 451 | 'idprotection' => $enableIdProtection, 452 | ); 453 | 454 | try { 455 | $api = new ApiClient(); 456 | $api->call('Transfer', $postfields); 457 | 458 | return array( 459 | 'success' => true, 460 | ); 461 | 462 | } catch (\Exception $e) { 463 | return array( 464 | 'error' => $e->getMessage(), 465 | ); 466 | } 467 | } 468 | 469 | /** 470 | * Renew a domain. 471 | * 472 | * Attempt to renew/extend a domain for a given number of years. 473 | * 474 | * This is triggered when the following events occur: 475 | * * Payment received for a domain renewal order 476 | * * When a pending domain renewal order is accepted 477 | * * Upon manual request by an admin user 478 | * 479 | * @param array $params common module parameters 480 | * 481 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 482 | * 483 | * @return array 484 | */ 485 | function registrarmodule_RenewDomain($params) 486 | { 487 | // user defined configuration values 488 | $userIdentifier = $params['APIUsername']; 489 | $apiKey = $params['APIKey']; 490 | $testMode = $params['TestMode']; 491 | $accountMode = $params['AccountMode']; 492 | $emailPreference = $params['EmailPreference']; 493 | 494 | // registration parameters 495 | $sld = $params['sld']; 496 | $tld = $params['tld']; 497 | $registrationPeriod = $params['regperiod']; 498 | 499 | // domain addon purchase status 500 | $enableDnsManagement = (bool) $params['dnsmanagement']; 501 | $enableEmailForwarding = (bool) $params['emailforwarding']; 502 | $enableIdProtection = (bool) $params['idprotection']; 503 | 504 | /** 505 | * Premium domain parameters. 506 | * 507 | * Premium domains enabled informs you if the admin user has enabled 508 | * the selling of premium domain names. If this domain is a premium name, 509 | * `premiumCost` will contain the cost price retrieved at the time of 510 | * the order being placed. A premium renewal should only be processed 511 | * if the cost price now matches that previously fetched amount. 512 | */ 513 | $premiumDomainsEnabled = (bool) $params['premiumEnabled']; 514 | $premiumDomainsCost = $params['premiumCost']; 515 | 516 | // Build post data. 517 | $postfields = array( 518 | 'username' => $userIdentifier, 519 | 'password' => $apiKey, 520 | 'testmode' => $testMode, 521 | 'domain' => $sld . '.' . $tld, 522 | 'years' => $registrationPeriod, 523 | 'dnsmanagement' => $enableDnsManagement, 524 | 'emailforwarding' => $enableEmailForwarding, 525 | 'idprotection' => $enableIdProtection, 526 | ); 527 | 528 | try { 529 | $api = new ApiClient(); 530 | $api->call('Renew', $postfields); 531 | 532 | return array( 533 | 'success' => true, 534 | ); 535 | 536 | } catch (\Exception $e) { 537 | return array( 538 | 'error' => $e->getMessage(), 539 | ); 540 | } 541 | } 542 | 543 | /** 544 | * Fetch current nameservers. 545 | * 546 | * This function should return an array of nameservers for a given domain. 547 | * 548 | * @param array $params common module parameters 549 | * 550 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 551 | * 552 | * @return array 553 | */ 554 | function registrarmodule_GetNameservers($params) 555 | { 556 | // user defined configuration values 557 | $userIdentifier = $params['APIUsername']; 558 | $apiKey = $params['APIKey']; 559 | $testMode = $params['TestMode']; 560 | $accountMode = $params['AccountMode']; 561 | $emailPreference = $params['EmailPreference']; 562 | 563 | // domain parameters 564 | $sld = $params['sld']; 565 | $tld = $params['tld']; 566 | $registrationPeriod = $params['regperiod']; 567 | 568 | // Build post data 569 | $postfields = array( 570 | 'username' => $userIdentifier, 571 | 'password' => $apiKey, 572 | 'testmode' => $testMode, 573 | 'domain' => $sld . '.' . $tld, 574 | ); 575 | 576 | try { 577 | $api = new ApiClient(); 578 | $api->call('GetNameservers', $postfields); 579 | 580 | return array( 581 | 'ns1' => $api->getFromResponse('nameserver1'), 582 | 'ns2' => $api->getFromResponse('nameserver2'), 583 | 'ns3' => $api->getFromResponse('nameserver3'), 584 | 'ns4' => $api->getFromResponse('nameserver4'), 585 | 'ns5' => $api->getFromResponse('nameserver5'), 586 | ); 587 | 588 | } catch (\Exception $e) { 589 | return array( 590 | 'error' => $e->getMessage(), 591 | ); 592 | } 593 | } 594 | 595 | /** 596 | * Save nameserver changes. 597 | * 598 | * This function should submit a change of nameservers request to the 599 | * domain registrar. 600 | * 601 | * @param array $params common module parameters 602 | * 603 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 604 | * 605 | * @return array 606 | */ 607 | function registrarmodule_SaveNameservers($params) 608 | { 609 | // user defined configuration values 610 | $userIdentifier = $params['APIUsername']; 611 | $apiKey = $params['APIKey']; 612 | $testMode = $params['TestMode']; 613 | $accountMode = $params['AccountMode']; 614 | $emailPreference = $params['EmailPreference']; 615 | 616 | // domain parameters 617 | $sld = $params['sld']; 618 | $tld = $params['tld']; 619 | 620 | // submitted nameserver values 621 | $nameserver1 = $params['ns1']; 622 | $nameserver2 = $params['ns2']; 623 | $nameserver3 = $params['ns3']; 624 | $nameserver4 = $params['ns4']; 625 | $nameserver5 = $params['ns5']; 626 | 627 | // Build post data 628 | $postfields = array( 629 | 'username' => $userIdentifier, 630 | 'password' => $apiKey, 631 | 'testmode' => $testMode, 632 | 'domain' => $sld . '.' . $tld, 633 | 'nameserver1' => $nameserver1, 634 | 'nameserver2' => $nameserver2, 635 | 'nameserver3' => $nameserver3, 636 | 'nameserver4' => $nameserver4, 637 | 'nameserver5' => $nameserver5, 638 | ); 639 | 640 | try { 641 | $api = new ApiClient(); 642 | $api->call('SetNameservers', $postfields); 643 | 644 | return array( 645 | 'success' => true, 646 | ); 647 | 648 | } catch (\Exception $e) { 649 | return array( 650 | 'error' => $e->getMessage(), 651 | ); 652 | } 653 | } 654 | 655 | /** 656 | * Get the current WHOIS Contact Information. 657 | * 658 | * Should return a multi-level array of the contacts and name/address 659 | * fields that be modified. 660 | * 661 | * @param array $params common module parameters 662 | * 663 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 664 | * 665 | * @return array 666 | */ 667 | function registrarmodule_GetContactDetails($params) 668 | { 669 | // user defined configuration values 670 | $userIdentifier = $params['APIUsername']; 671 | $apiKey = $params['APIKey']; 672 | $testMode = $params['TestMode']; 673 | $accountMode = $params['AccountMode']; 674 | $emailPreference = $params['EmailPreference']; 675 | 676 | 677 | // domain parameters 678 | $sld = $params['sld']; 679 | $tld = $params['tld']; 680 | 681 | // Build post data 682 | $postfields = array( 683 | 'username' => $userIdentifier, 684 | 'password' => $apiKey, 685 | 'testmode' => $testMode, 686 | 'domain' => $sld . '.' . $tld, 687 | ); 688 | 689 | try { 690 | $api = new ApiClient(); 691 | $api->call('GetWhoisInformation', $postfields); 692 | 693 | return array( 694 | 'Registrant' => array( 695 | 'First Name' => $api->getFromResponse('registrant.firstname'), 696 | 'Last Name' => $api->getFromResponse('registrant.lastname'), 697 | 'Company Name' => $api->getFromResponse('registrant.company'), 698 | 'Email Address' => $api->getFromResponse('registrant.email'), 699 | 'Address 1' => $api->getFromResponse('registrant.address1'), 700 | 'Address 2' => $api->getFromResponse('registrant.address2'), 701 | 'City' => $api->getFromResponse('registrant.city'), 702 | 'State' => $api->getFromResponse('registrant.state'), 703 | 'Postcode' => $api->getFromResponse('registrant.postcode'), 704 | 'Country' => $api->getFromResponse('registrant.country'), 705 | 'Phone Number' => $api->getFromResponse('registrant.phone'), 706 | 'Fax Number' => $api->getFromResponse('registrant.fax'), 707 | ), 708 | 'Technical' => array( 709 | 'First Name' => $api->getFromResponse('tech.firstname'), 710 | 'Last Name' => $api->getFromResponse('tech.lastname'), 711 | 'Company Name' => $api->getFromResponse('tech.company'), 712 | 'Email Address' => $api->getFromResponse('tech.email'), 713 | 'Address 1' => $api->getFromResponse('tech.address1'), 714 | 'Address 2' => $api->getFromResponse('tech.address2'), 715 | 'City' => $api->getFromResponse('tech.city'), 716 | 'State' => $api->getFromResponse('tech.state'), 717 | 'Postcode' => $api->getFromResponse('tech.postcode'), 718 | 'Country' => $api->getFromResponse('tech.country'), 719 | 'Phone Number' => $api->getFromResponse('tech.phone'), 720 | 'Fax Number' => $api->getFromResponse('tech.fax'), 721 | ), 722 | 'Billing' => array( 723 | 'First Name' => $api->getFromResponse('billing.firstname'), 724 | 'Last Name' => $api->getFromResponse('billing.lastname'), 725 | 'Company Name' => $api->getFromResponse('billing.company'), 726 | 'Email Address' => $api->getFromResponse('billing.email'), 727 | 'Address 1' => $api->getFromResponse('billing.address1'), 728 | 'Address 2' => $api->getFromResponse('billing.address2'), 729 | 'City' => $api->getFromResponse('billing.city'), 730 | 'State' => $api->getFromResponse('billing.state'), 731 | 'Postcode' => $api->getFromResponse('billing.postcode'), 732 | 'Country' => $api->getFromResponse('billing.country'), 733 | 'Phone Number' => $api->getFromResponse('billing.phone'), 734 | 'Fax Number' => $api->getFromResponse('billing.fax'), 735 | ), 736 | 'Admin' => array( 737 | 'First Name' => $api->getFromResponse('admin.firstname'), 738 | 'Last Name' => $api->getFromResponse('admin.lastname'), 739 | 'Company Name' => $api->getFromResponse('admin.company'), 740 | 'Email Address' => $api->getFromResponse('admin.email'), 741 | 'Address 1' => $api->getFromResponse('admin.address1'), 742 | 'Address 2' => $api->getFromResponse('admin.address2'), 743 | 'City' => $api->getFromResponse('admin.city'), 744 | 'State' => $api->getFromResponse('admin.state'), 745 | 'Postcode' => $api->getFromResponse('admin.postcode'), 746 | 'Country' => $api->getFromResponse('admin.country'), 747 | 'Phone Number' => $api->getFromResponse('admin.phone'), 748 | 'Fax Number' => $api->getFromResponse('admin.fax'), 749 | ), 750 | ); 751 | 752 | } catch (\Exception $e) { 753 | return array( 754 | 'error' => $e->getMessage(), 755 | ); 756 | } 757 | } 758 | 759 | /** 760 | * Update the WHOIS Contact Information for a given domain. 761 | * 762 | * Called when a change of WHOIS Information is requested within WHMCS. 763 | * Receives an array matching the format provided via the `GetContactDetails` 764 | * method with the values from the users input. 765 | * 766 | * @param array $params common module parameters 767 | * 768 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 769 | * 770 | * @return array 771 | */ 772 | function registrarmodule_SaveContactDetails($params) 773 | { 774 | // user defined configuration values 775 | $userIdentifier = $params['APIUsername']; 776 | $apiKey = $params['APIKey']; 777 | $testMode = $params['TestMode']; 778 | $accountMode = $params['AccountMode']; 779 | $emailPreference = $params['EmailPreference']; 780 | 781 | // domain parameters 782 | $sld = $params['sld']; 783 | $tld = $params['tld']; 784 | 785 | // whois information 786 | $contactDetails = $params['contactdetails']; 787 | 788 | // Build post data 789 | $postfields = array( 790 | 'username' => $userIdentifier, 791 | 'password' => $apiKey, 792 | 'testmode' => $testMode, 793 | 'domain' => $sld . '.' . $tld, 794 | 'contacts' => array( 795 | 'registrant' => array( 796 | 'firstname' => $contactDetails['Registrant']['First Name'], 797 | 'lastname' => $contactDetails['Registrant']['Last Name'], 798 | 'company' => $contactDetails['Registrant']['Company Name'], 799 | 'email' => $contactDetails['Registrant']['Email Address'], 800 | // etc... 801 | ), 802 | 'tech' => array( 803 | 'firstname' => $contactDetails['Technical']['First Name'], 804 | 'lastname' => $contactDetails['Technical']['Last Name'], 805 | 'company' => $contactDetails['Technical']['Company Name'], 806 | 'email' => $contactDetails['Technical']['Email Address'], 807 | // etc... 808 | ), 809 | 'billing' => array( 810 | 'firstname' => $contactDetails['Billing']['First Name'], 811 | 'lastname' => $contactDetails['Billing']['Last Name'], 812 | 'company' => $contactDetails['Billing']['Company Name'], 813 | 'email' => $contactDetails['Billing']['Email Address'], 814 | // etc... 815 | ), 816 | 'admin' => array( 817 | 'firstname' => $contactDetails['Admin']['First Name'], 818 | 'lastname' => $contactDetails['Admin']['Last Name'], 819 | 'company' => $contactDetails['Admin']['Company Name'], 820 | 'email' => $contactDetails['Admin']['Email Address'], 821 | // etc... 822 | ), 823 | ), 824 | ); 825 | 826 | try { 827 | $api = new ApiClient(); 828 | $api->call('UpdateWhoisInformation', $postfields); 829 | 830 | return array( 831 | 'success' => true, 832 | ); 833 | 834 | } catch (\Exception $e) { 835 | return array( 836 | 'error' => $e->getMessage(), 837 | ); 838 | } 839 | } 840 | 841 | /** 842 | * Check Domain Availability. 843 | * 844 | * Determine if a domain or group of domains are available for 845 | * registration or transfer. 846 | * 847 | * @param array $params common module parameters 848 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 849 | * 850 | * @see \WHMCS\Domains\DomainLookup\SearchResult 851 | * @see \WHMCS\Domains\DomainLookup\ResultsList 852 | * 853 | * @throws Exception Upon domain availability check failure. 854 | * 855 | * @return \WHMCS\Domains\DomainLookup\ResultsList An ArrayObject based collection of \WHMCS\Domains\DomainLookup\SearchResult results 856 | */ 857 | function registrarmodule_CheckAvailability($params) 858 | { 859 | // user defined configuration values 860 | $userIdentifier = $params['APIUsername']; 861 | $apiKey = $params['APIKey']; 862 | $testMode = $params['TestMode']; 863 | $accountMode = $params['AccountMode']; 864 | $emailPreference = $params['EmailPreference']; 865 | 866 | // availability check parameters 867 | $searchTerm = $params['searchTerm']; 868 | $punyCodeSearchTerm = $params['punyCodeSearchTerm']; 869 | $tldsToInclude = $params['tldsToInclude']; 870 | $isIdnDomain = (bool) $params['isIdnDomain']; 871 | $premiumEnabled = (bool) $params['premiumEnabled']; 872 | 873 | // Build post data 874 | $postfields = array( 875 | 'username' => $userIdentifier, 876 | 'password' => $apiKey, 877 | 'testmode' => $testMode, 878 | 'domain' => $sld . '.' . $tld, 879 | 'searchTerm' => $searchTerm, 880 | 'tldsToSearch' => $tldsToInclude, 881 | 'includePremiumDomains' => $premiumEnabled, 882 | ); 883 | 884 | try { 885 | $api = new ApiClient(); 886 | $api->call('CheckAvailability', $postfields); 887 | 888 | $results = new ResultsList(); 889 | foreach ($api->getFromResponse('domains') as $domain) { 890 | 891 | // Instantiate a new domain search result object 892 | $searchResult = new SearchResult($domain['sld'], $domain['tld']); 893 | 894 | // Determine the appropriate status to return 895 | if ($domain['status'] == 'available') { 896 | $status = SearchResult::STATUS_NOT_REGISTERED; 897 | } elseif ($domain['status'] == 'registered') { 898 | $status = SearchResult::STATUS_REGISTERED; 899 | } elseif ($domain['status'] == 'reserved') { 900 | $status = SearchResult::STATUS_RESERVED; 901 | } else { 902 | $status = SearchResult::STATUS_TLD_NOT_SUPPORTED; 903 | } 904 | $searchResult->setStatus($status); 905 | 906 | // Return premium information if applicable 907 | if ($domain['isPremiumName']) { 908 | $searchResult->setPremiumDomain(true); 909 | $searchResult->setPremiumCostPricing( 910 | array( 911 | 'register' => $domain['premiumRegistrationPrice'], 912 | 'renew' => $domain['premiumRenewPrice'], 913 | 'CurrencyCode' => 'USD', 914 | ) 915 | ); 916 | } 917 | 918 | // Append to the search results list 919 | $results->append($searchResult); 920 | } 921 | 922 | return $results; 923 | 924 | } catch (\Exception $e) { 925 | return array( 926 | 'error' => $e->getMessage(), 927 | ); 928 | } 929 | } 930 | 931 | /** 932 | * Domain Suggestion Settings. 933 | * 934 | * Defines the settings relating to domain suggestions (optional). 935 | * It follows the same convention as `getConfigArray`. 936 | * 937 | * @see https://developers.whmcs.com/domain-registrars/check-availability/ 938 | * 939 | * @return array of Configuration Options 940 | */ 941 | function registrarmodule_DomainSuggestionOptions() { 942 | return array( 943 | 'includeCCTlds' => array( 944 | 'FriendlyName' => 'Include Country Level TLDs', 945 | 'Type' => 'yesno', 946 | 'Description' => 'Tick to enable', 947 | ), 948 | ); 949 | } 950 | 951 | /** 952 | * Get Domain Suggestions. 953 | * 954 | * Provide domain suggestions based on the domain lookup term provided. 955 | * 956 | * @param array $params common module parameters 957 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 958 | * 959 | * @see \WHMCS\Domains\DomainLookup\SearchResult 960 | * @see \WHMCS\Domains\DomainLookup\ResultsList 961 | * 962 | * @throws Exception Upon domain suggestions check failure. 963 | * 964 | * @return \WHMCS\Domains\DomainLookup\ResultsList An ArrayObject based collection of \WHMCS\Domains\DomainLookup\SearchResult results 965 | */ 966 | function registrarmodule_GetDomainSuggestions($params) 967 | { 968 | // user defined configuration values 969 | $userIdentifier = $params['APIUsername']; 970 | $apiKey = $params['APIKey']; 971 | $testMode = $params['TestMode']; 972 | $accountMode = $params['AccountMode']; 973 | $emailPreference = $params['EmailPreference']; 974 | 975 | // availability check parameters 976 | $searchTerm = $params['searchTerm']; 977 | $punyCodeSearchTerm = $params['punyCodeSearchTerm']; 978 | $tldsToInclude = $params['tldsToInclude']; 979 | $isIdnDomain = (bool) $params['isIdnDomain']; 980 | $premiumEnabled = (bool) $params['premiumEnabled']; 981 | $suggestionSettings = $params['suggestionSettings']; 982 | 983 | // Build post data 984 | $postfields = array( 985 | 'username' => $userIdentifier, 986 | 'password' => $apiKey, 987 | 'testmode' => $testMode, 988 | 'domain' => $sld . '.' . $tld, 989 | 'searchTerm' => $searchTerm, 990 | 'tldsToSearch' => $tldsToInclude, 991 | 'includePremiumDomains' => $premiumEnabled, 992 | 'includeCCTlds' => $suggestionSettings['includeCCTlds'], 993 | ); 994 | 995 | try { 996 | $api = new ApiClient(); 997 | $api->call('GetSuggestions', $postfields); 998 | 999 | $results = new ResultsList(); 1000 | foreach ($api->getFromResponse('domains') as $domain) { 1001 | 1002 | // Instantiate a new domain search result object 1003 | $searchResult = new SearchResult($domain['sld'], $domain['tld']); 1004 | 1005 | // All domain suggestions should be available to register 1006 | $searchResult->setStatus(SearchResult::STATUS_NOT_REGISTERED); 1007 | 1008 | // Used to weight results by relevance 1009 | $searchResult->setScore($domain['score']); 1010 | 1011 | // Return premium information if applicable 1012 | if ($domain['isPremiumName']) { 1013 | $searchResult->setPremiumDomain(true); 1014 | $searchResult->setPremiumCostPricing( 1015 | array( 1016 | 'register' => $domain['premiumRegistrationPrice'], 1017 | 'renew' => $domain['premiumRenewPrice'], 1018 | 'CurrencyCode' => 'USD', 1019 | ) 1020 | ); 1021 | } 1022 | 1023 | // Append to the search results list 1024 | $results->append($searchResult); 1025 | } 1026 | 1027 | return $results; 1028 | 1029 | } catch (\Exception $e) { 1030 | return array( 1031 | 'error' => $e->getMessage(), 1032 | ); 1033 | } 1034 | } 1035 | 1036 | /** 1037 | * Get registrar lock status. 1038 | * 1039 | * Also known as Domain Lock or Transfer Lock status. 1040 | * 1041 | * @param array $params common module parameters 1042 | * 1043 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1044 | * 1045 | * @return string|array Lock status or error message 1046 | */ 1047 | function registrarmodule_GetRegistrarLock($params) 1048 | { 1049 | // user defined configuration values 1050 | $userIdentifier = $params['APIUsername']; 1051 | $apiKey = $params['APIKey']; 1052 | $testMode = $params['TestMode']; 1053 | $accountMode = $params['AccountMode']; 1054 | $emailPreference = $params['EmailPreference']; 1055 | 1056 | 1057 | // domain parameters 1058 | $sld = $params['sld']; 1059 | $tld = $params['tld']; 1060 | 1061 | // Build post data 1062 | $postfields = array( 1063 | 'username' => $userIdentifier, 1064 | 'password' => $apiKey, 1065 | 'testmode' => $testMode, 1066 | 'domain' => $sld . '.' . $tld, 1067 | ); 1068 | 1069 | try { 1070 | $api = new ApiClient(); 1071 | $api->call('GetLockStatus', $postfields); 1072 | 1073 | if ($api->getFromResponse('lockstatus') == 'locked') { 1074 | return 'locked'; 1075 | } else { 1076 | return 'unlocked'; 1077 | } 1078 | 1079 | } catch (\Exception $e) { 1080 | return array( 1081 | 'error' => $e->getMessage(), 1082 | ); 1083 | } 1084 | } 1085 | 1086 | /** 1087 | * Set registrar lock status. 1088 | * 1089 | * @param array $params common module parameters 1090 | * 1091 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1092 | * 1093 | * @return array 1094 | */ 1095 | function registrarmodule_SaveRegistrarLock($params) 1096 | { 1097 | // user defined configuration values 1098 | $userIdentifier = $params['APIUsername']; 1099 | $apiKey = $params['APIKey']; 1100 | $testMode = $params['TestMode']; 1101 | $accountMode = $params['AccountMode']; 1102 | $emailPreference = $params['EmailPreference']; 1103 | 1104 | // domain parameters 1105 | $sld = $params['sld']; 1106 | $tld = $params['tld']; 1107 | 1108 | // lock status 1109 | $lockStatus = $params['lockenabled']; 1110 | 1111 | // Build post data 1112 | $postfields = array( 1113 | 'username' => $userIdentifier, 1114 | 'password' => $apiKey, 1115 | 'testmode' => $testMode, 1116 | 'domain' => $sld . '.' . $tld, 1117 | 'registrarlock' => ($lockStatus == 'locked') ? 1 : 0, 1118 | ); 1119 | 1120 | try { 1121 | $api = new ApiClient(); 1122 | $api->call('SetLockStatus', $postfields); 1123 | 1124 | return array( 1125 | 'success' => 'success', 1126 | ); 1127 | 1128 | } catch (\Exception $e) { 1129 | return array( 1130 | 'error' => $e->getMessage(), 1131 | ); 1132 | } 1133 | } 1134 | 1135 | /** 1136 | * Get DNS Records for DNS Host Record Management. 1137 | * 1138 | * @param array $params common module parameters 1139 | * 1140 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1141 | * 1142 | * @return array DNS Host Records 1143 | */ 1144 | function registrarmodule_GetDNS($params) 1145 | { 1146 | // user defined configuration values 1147 | $userIdentifier = $params['APIUsername']; 1148 | $apiKey = $params['APIKey']; 1149 | $testMode = $params['TestMode']; 1150 | $accountMode = $params['AccountMode']; 1151 | $emailPreference = $params['EmailPreference']; 1152 | 1153 | // domain parameters 1154 | $sld = $params['sld']; 1155 | $tld = $params['tld']; 1156 | 1157 | // Build post data 1158 | $postfields = array( 1159 | 'username' => $userIdentifier, 1160 | 'password' => $apiKey, 1161 | 'testmode' => $testMode, 1162 | 'domain' => $sld . '.' . $tld, 1163 | ); 1164 | 1165 | try { 1166 | $api = new ApiClient(); 1167 | $api->call('GetDNSHostRecords', $postfields); 1168 | 1169 | $hostRecords = array(); 1170 | foreach ($api->getFromResponse('records') as $record) { 1171 | $hostRecords[] = array( 1172 | "hostname" => $record['name'], // eg. www 1173 | "type" => $record['type'], // eg. A 1174 | "address" => $record['address'], // eg. 10.0.0.1 1175 | "priority" => $record['mxpref'], // eg. 10 (N/A for non-MX records) 1176 | ); 1177 | } 1178 | return $hostRecords; 1179 | 1180 | } catch (\Exception $e) { 1181 | return array( 1182 | 'error' => $e->getMessage(), 1183 | ); 1184 | } 1185 | } 1186 | 1187 | /** 1188 | * Update DNS Host Records. 1189 | * 1190 | * @param array $params common module parameters 1191 | * 1192 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1193 | * 1194 | * @return array 1195 | */ 1196 | function registrarmodule_SaveDNS($params) 1197 | { 1198 | // user defined configuration values 1199 | $userIdentifier = $params['APIUsername']; 1200 | $apiKey = $params['APIKey']; 1201 | $testMode = $params['TestMode']; 1202 | $accountMode = $params['AccountMode']; 1203 | $emailPreference = $params['EmailPreference']; 1204 | 1205 | // domain parameters 1206 | $sld = $params['sld']; 1207 | $tld = $params['tld']; 1208 | 1209 | // dns record parameters 1210 | $dnsrecords = $params['dnsrecords']; 1211 | 1212 | // Build post data 1213 | $postfields = array( 1214 | 'username' => $userIdentifier, 1215 | 'password' => $apiKey, 1216 | 'testmode' => $testMode, 1217 | 'domain' => $sld . '.' . $tld, 1218 | 'records' => $dnsrecords, 1219 | ); 1220 | 1221 | try { 1222 | $api = new ApiClient(); 1223 | $api->call('GetDNSHostRecords', $postfields); 1224 | 1225 | return array( 1226 | 'success' => 'success', 1227 | ); 1228 | 1229 | } catch (\Exception $e) { 1230 | return array( 1231 | 'error' => $e->getMessage(), 1232 | ); 1233 | } 1234 | } 1235 | 1236 | /** 1237 | * Enable/Disable ID Protection. 1238 | * 1239 | * @param array $params common module parameters 1240 | * 1241 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1242 | * 1243 | * @return array 1244 | */ 1245 | function registrarmodule_IDProtectToggle($params) 1246 | { 1247 | // user defined configuration values 1248 | $userIdentifier = $params['APIUsername']; 1249 | $apiKey = $params['APIKey']; 1250 | $testMode = $params['TestMode']; 1251 | $accountMode = $params['AccountMode']; 1252 | $emailPreference = $params['EmailPreference']; 1253 | 1254 | // domain parameters 1255 | $sld = $params['sld']; 1256 | $tld = $params['tld']; 1257 | 1258 | // id protection parameter 1259 | $protectEnable = (bool) $params['protectenable']; 1260 | 1261 | // Build post data 1262 | $postfields = array( 1263 | 'username' => $userIdentifier, 1264 | 'password' => $apiKey, 1265 | 'testmode' => $testMode, 1266 | 'domain' => $sld . '.' . $tld, 1267 | ); 1268 | 1269 | try { 1270 | $api = new ApiClient(); 1271 | 1272 | if ($protectEnable) { 1273 | $api->call('EnableIDProtection', $postfields); 1274 | } else { 1275 | $api->call('DisableIDProtection', $postfields); 1276 | } 1277 | 1278 | return array( 1279 | 'success' => 'success', 1280 | ); 1281 | 1282 | } catch (\Exception $e) { 1283 | return array( 1284 | 'error' => $e->getMessage(), 1285 | ); 1286 | } 1287 | } 1288 | 1289 | /** 1290 | * Request EEP Code. 1291 | * 1292 | * Supports both displaying the EPP Code directly to a user or indicating 1293 | * that the EPP Code will be emailed to the registrant. 1294 | * 1295 | * @param array $params common module parameters 1296 | * 1297 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1298 | * 1299 | * @return array 1300 | * 1301 | */ 1302 | function registrarmodule_GetEPPCode($params) 1303 | { 1304 | // user defined configuration values 1305 | $userIdentifier = $params['APIUsername']; 1306 | $apiKey = $params['APIKey']; 1307 | $testMode = $params['TestMode']; 1308 | $accountMode = $params['AccountMode']; 1309 | $emailPreference = $params['EmailPreference']; 1310 | 1311 | // domain parameters 1312 | $sld = $params['sld']; 1313 | $tld = $params['tld']; 1314 | 1315 | // Build post data 1316 | $postfields = array( 1317 | 'username' => $userIdentifier, 1318 | 'password' => $apiKey, 1319 | 'testmode' => $testMode, 1320 | 'domain' => $sld . '.' . $tld, 1321 | ); 1322 | 1323 | try { 1324 | $api = new ApiClient(); 1325 | $api->call('RequestEPPCode', $postfields); 1326 | 1327 | if ($api->getFromResponse('eppcode')) { 1328 | // If EPP Code is returned, return it for display to the end user 1329 | return array( 1330 | 'eppcode' => $api->getFromResponse('eppcode'), 1331 | ); 1332 | } else { 1333 | // If EPP Code is not returned, it was sent by email, return success 1334 | return array( 1335 | 'success' => 'success', 1336 | ); 1337 | } 1338 | 1339 | } catch (\Exception $e) { 1340 | return array( 1341 | 'error' => $e->getMessage(), 1342 | ); 1343 | } 1344 | } 1345 | 1346 | /** 1347 | * Release a Domain. 1348 | * 1349 | * Used to initiate a transfer out such as an IPSTAG change for .UK 1350 | * domain names. 1351 | * 1352 | * @param array $params common module parameters 1353 | * 1354 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1355 | * 1356 | * @return array 1357 | */ 1358 | function registrarmodule_ReleaseDomain($params) 1359 | { 1360 | // user defined configuration values 1361 | $userIdentifier = $params['APIUsername']; 1362 | $apiKey = $params['APIKey']; 1363 | $testMode = $params['TestMode']; 1364 | $accountMode = $params['AccountMode']; 1365 | $emailPreference = $params['EmailPreference']; 1366 | 1367 | // domain parameters 1368 | $sld = $params['sld']; 1369 | $tld = $params['tld']; 1370 | 1371 | // transfer tag 1372 | $transferTag = $params['transfertag']; 1373 | 1374 | // Build post data 1375 | $postfields = array( 1376 | 'username' => $userIdentifier, 1377 | 'password' => $apiKey, 1378 | 'testmode' => $testMode, 1379 | 'domain' => $sld . '.' . $tld, 1380 | 'newtag' => $transferTag, 1381 | ); 1382 | 1383 | try { 1384 | $api = new ApiClient(); 1385 | $api->call('ReleaseDomain', $postfields); 1386 | 1387 | return array( 1388 | 'success' => 'success', 1389 | ); 1390 | 1391 | } catch (\Exception $e) { 1392 | return array( 1393 | 'error' => $e->getMessage(), 1394 | ); 1395 | } 1396 | } 1397 | 1398 | /** 1399 | * Delete Domain. 1400 | * 1401 | * @param array $params common module parameters 1402 | * 1403 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1404 | * 1405 | * @return array 1406 | */ 1407 | function registrarmodule_RequestDelete($params) 1408 | { 1409 | // user defined configuration values 1410 | $userIdentifier = $params['APIUsername']; 1411 | $apiKey = $params['APIKey']; 1412 | $testMode = $params['TestMode']; 1413 | $accountMode = $params['AccountMode']; 1414 | $emailPreference = $params['EmailPreference']; 1415 | 1416 | // domain parameters 1417 | $sld = $params['sld']; 1418 | $tld = $params['tld']; 1419 | 1420 | // Build post data 1421 | $postfields = array( 1422 | 'username' => $userIdentifier, 1423 | 'password' => $apiKey, 1424 | 'testmode' => $testMode, 1425 | 'domain' => $sld . '.' . $tld, 1426 | ); 1427 | 1428 | try { 1429 | $api = new ApiClient(); 1430 | $api->call('DeleteDomain', $postfields); 1431 | 1432 | return array( 1433 | 'success' => 'success', 1434 | ); 1435 | 1436 | } catch (\Exception $e) { 1437 | return array( 1438 | 'error' => $e->getMessage(), 1439 | ); 1440 | } 1441 | } 1442 | 1443 | /** 1444 | * Register a Nameserver. 1445 | * 1446 | * Adds a child nameserver for the given domain name. 1447 | * 1448 | * @param array $params common module parameters 1449 | * 1450 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1451 | * 1452 | * @return array 1453 | */ 1454 | function registrarmodule_RegisterNameserver($params) 1455 | { 1456 | // user defined configuration values 1457 | $userIdentifier = $params['APIUsername']; 1458 | $apiKey = $params['APIKey']; 1459 | $testMode = $params['TestMode']; 1460 | $accountMode = $params['AccountMode']; 1461 | $emailPreference = $params['EmailPreference']; 1462 | 1463 | // domain parameters 1464 | $sld = $params['sld']; 1465 | $tld = $params['tld']; 1466 | 1467 | // nameserver parameters 1468 | $nameserver = $params['nameserver']; 1469 | $ipAddress = $params['ipaddress']; 1470 | 1471 | // Build post data 1472 | $postfields = array( 1473 | 'username' => $userIdentifier, 1474 | 'password' => $apiKey, 1475 | 'testmode' => $testMode, 1476 | 'domain' => $sld . '.' . $tld, 1477 | 'nameserver' => $nameserver, 1478 | 'ip' => $ipAddress, 1479 | ); 1480 | 1481 | try { 1482 | $api = new ApiClient(); 1483 | $api->call('RegisterNameserver', $postfields); 1484 | 1485 | return array( 1486 | 'success' => 'success', 1487 | ); 1488 | 1489 | } catch (\Exception $e) { 1490 | return array( 1491 | 'error' => $e->getMessage(), 1492 | ); 1493 | } 1494 | } 1495 | 1496 | /** 1497 | * Modify a Nameserver. 1498 | * 1499 | * Modifies the IP of a child nameserver. 1500 | * 1501 | * @param array $params common module parameters 1502 | * 1503 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1504 | * 1505 | * @return array 1506 | */ 1507 | function registrarmodule_ModifyNameserver($params) 1508 | { 1509 | // user defined configuration values 1510 | $userIdentifier = $params['APIUsername']; 1511 | $apiKey = $params['APIKey']; 1512 | $testMode = $params['TestMode']; 1513 | $accountMode = $params['AccountMode']; 1514 | $emailPreference = $params['EmailPreference']; 1515 | 1516 | // domain parameters 1517 | $sld = $params['sld']; 1518 | $tld = $params['tld']; 1519 | 1520 | // nameserver parameters 1521 | $nameserver = $params['nameserver']; 1522 | $currentIpAddress = $params['currentipaddress']; 1523 | $newIpAddress = $params['newipaddress']; 1524 | 1525 | // Build post data 1526 | $postfields = array( 1527 | 'username' => $userIdentifier, 1528 | 'password' => $apiKey, 1529 | 'testmode' => $testMode, 1530 | 'domain' => $sld . '.' . $tld, 1531 | 'nameserver' => $nameserver, 1532 | 'currentip' => $currentIpAddress, 1533 | 'newip' => $newIpAddress, 1534 | ); 1535 | 1536 | try { 1537 | $api = new ApiClient(); 1538 | $api->call('ModifyNameserver', $postfields); 1539 | 1540 | return array( 1541 | 'success' => 'success', 1542 | ); 1543 | 1544 | } catch (\Exception $e) { 1545 | return array( 1546 | 'error' => $e->getMessage(), 1547 | ); 1548 | } 1549 | } 1550 | 1551 | /** 1552 | * Delete a Nameserver. 1553 | * 1554 | * @param array $params common module parameters 1555 | * 1556 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1557 | * 1558 | * @return array 1559 | */ 1560 | function registrarmodule_DeleteNameserver($params) 1561 | { 1562 | // user defined configuration values 1563 | $userIdentifier = $params['APIUsername']; 1564 | $apiKey = $params['APIKey']; 1565 | $testMode = $params['TestMode']; 1566 | $accountMode = $params['AccountMode']; 1567 | $emailPreference = $params['EmailPreference']; 1568 | 1569 | // domain parameters 1570 | $sld = $params['sld']; 1571 | $tld = $params['tld']; 1572 | 1573 | // nameserver parameters 1574 | $nameserver = $params['nameserver']; 1575 | 1576 | // Build post data 1577 | $postfields = array( 1578 | 'username' => $userIdentifier, 1579 | 'password' => $apiKey, 1580 | 'testmode' => $testMode, 1581 | 'domain' => $sld . '.' . $tld, 1582 | 'nameserver' => $nameserver, 1583 | ); 1584 | 1585 | try { 1586 | $api = new ApiClient(); 1587 | $api->call('DeleteNameserver', $postfields); 1588 | 1589 | return array( 1590 | 'success' => 'success', 1591 | ); 1592 | 1593 | } catch (\Exception $e) { 1594 | return array( 1595 | 'error' => $e->getMessage(), 1596 | ); 1597 | } 1598 | } 1599 | 1600 | /** 1601 | * Sync Domain Status & Expiration Date. 1602 | * 1603 | * Domain syncing is intended to ensure domain status and expiry date 1604 | * changes made directly at the domain registrar are synced to WHMCS. 1605 | * It is called periodically for a domain. 1606 | * 1607 | * @param array $params common module parameters 1608 | * 1609 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1610 | * 1611 | * @return array 1612 | */ 1613 | function registrarmodule_Sync($params) 1614 | { 1615 | // user defined configuration values 1616 | $userIdentifier = $params['APIUsername']; 1617 | $apiKey = $params['APIKey']; 1618 | $testMode = $params['TestMode']; 1619 | $accountMode = $params['AccountMode']; 1620 | $emailPreference = $params['EmailPreference']; 1621 | 1622 | // domain parameters 1623 | $sld = $params['sld']; 1624 | $tld = $params['tld']; 1625 | 1626 | // Build post data 1627 | $postfields = array( 1628 | 'username' => $userIdentifier, 1629 | 'password' => $apiKey, 1630 | 'testmode' => $testMode, 1631 | 'domain' => $sld . '.' . $tld, 1632 | ); 1633 | 1634 | try { 1635 | $api = new ApiClient(); 1636 | $api->call('GetDomainInfo', $postfields); 1637 | 1638 | return array( 1639 | 'expirydate' => $api->getFromResponse('expirydate'), // Format: YYYY-MM-DD 1640 | 'active' => (bool) $api->getFromResponse('active'), // Return true if the domain is active 1641 | 'transferredAway' => (bool) $api->getFromResponse('transferredaway'), // Return true if the domain is transferred out 1642 | ); 1643 | 1644 | } catch (\Exception $e) { 1645 | return array( 1646 | 'error' => $e->getMessage(), 1647 | ); 1648 | } 1649 | } 1650 | 1651 | /** 1652 | * Incoming Domain Transfer Sync. 1653 | * 1654 | * Check status of incoming domain transfers and notify end-user upon 1655 | * completion. This function is called daily for incoming domains. 1656 | * 1657 | * @param array $params common module parameters 1658 | * 1659 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1660 | * 1661 | * @return array 1662 | */ 1663 | function registrarmodule_TransferSync($params) 1664 | { 1665 | // user defined configuration values 1666 | $userIdentifier = $params['APIUsername']; 1667 | $apiKey = $params['APIKey']; 1668 | $testMode = $params['TestMode']; 1669 | $accountMode = $params['AccountMode']; 1670 | $emailPreference = $params['EmailPreference']; 1671 | 1672 | // domain parameters 1673 | $sld = $params['sld']; 1674 | $tld = $params['tld']; 1675 | 1676 | // Build post data 1677 | $postfields = array( 1678 | 'username' => $userIdentifier, 1679 | 'password' => $apiKey, 1680 | 'testmode' => $testMode, 1681 | 'domain' => $sld . '.' . $tld, 1682 | ); 1683 | 1684 | try { 1685 | $api = new ApiClient(); 1686 | $api->call('CheckDomainTransfer', $postfields); 1687 | 1688 | if ($api->getFromResponse('transfercomplete')) { 1689 | return array( 1690 | 'completed' => true, 1691 | 'expirydate' => $api->getFromResponse('expirydate'), // Format: YYYY-MM-DD 1692 | ); 1693 | } elseif ($api->getFromResponse('transferfailed')) { 1694 | return array( 1695 | 'failed' => true, 1696 | 'reason' => $api->getFromResponse('failurereason'), // Reason for the transfer failure if available 1697 | ); 1698 | } else { 1699 | // No status change, return empty array 1700 | return array(); 1701 | } 1702 | 1703 | } catch (\Exception $e) { 1704 | return array( 1705 | 'error' => $e->getMessage(), 1706 | ); 1707 | } 1708 | } 1709 | 1710 | /** 1711 | * Client Area Custom Button Array. 1712 | * 1713 | * Allows you to define additional actions your module supports. 1714 | * In this example, we register a Push Domain action which triggers 1715 | * the `registrarmodule_push` function when invoked. 1716 | * 1717 | * @return array 1718 | */ 1719 | function registrarmodule_ClientAreaCustomButtonArray() 1720 | { 1721 | return array( 1722 | 'Push Domain' => 'push', 1723 | ); 1724 | } 1725 | 1726 | /** 1727 | * Client Area Allowed Functions. 1728 | * 1729 | * Only the functions defined within this function or the Client Area 1730 | * Custom Button Array can be invoked by client level users. 1731 | * 1732 | * @return array 1733 | */ 1734 | function registrarmodule_ClientAreaAllowedFunctions() 1735 | { 1736 | return array( 1737 | 'Push Domain' => 'push', 1738 | ); 1739 | } 1740 | 1741 | /** 1742 | * Example Custom Module Function: Push 1743 | * 1744 | * @param array $params common module parameters 1745 | * 1746 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1747 | * 1748 | * @return array 1749 | */ 1750 | function registrarmodule_push($params) 1751 | { 1752 | // user defined configuration values 1753 | $userIdentifier = $params['APIUsername']; 1754 | $apiKey = $params['APIKey']; 1755 | $testMode = $params['TestMode']; 1756 | $accountMode = $params['AccountMode']; 1757 | $emailPreference = $params['EmailPreference']; 1758 | 1759 | // domain parameters 1760 | $sld = $params['sld']; 1761 | $tld = $params['tld']; 1762 | 1763 | // Perform custom action here... 1764 | 1765 | return 'Not implemented'; 1766 | } 1767 | 1768 | /** 1769 | * Client Area Output. 1770 | * 1771 | * This function renders output to the domain details interface within 1772 | * the client area. The return should be the HTML to be output. 1773 | * 1774 | * @param array $params common module parameters 1775 | * 1776 | * @see https://developers.whmcs.com/domain-registrars/module-parameters/ 1777 | * 1778 | * @return string HTML Output 1779 | */ 1780 | function registrarmodule_ClientArea($params) 1781 | { 1782 | $output = ' 1783 |
1784 | Your custom HTML output goes here... 1785 |
1786 | '; 1787 | 1788 | return $output; 1789 | } 1790 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | ./tests/ 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/WHMCSSampleRegistrarModuleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(function_exists('registrarmodule_' . $moduleName)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/_bootstrap.php: -------------------------------------------------------------------------------- 1 | Logs. 14 | * 15 | * @param string $module 16 | * @param string $action 17 | * @param string|array $request 18 | * @param string|array $response 19 | * @param string|array $data 20 | * @param array $variablesToMask 21 | * 22 | * @return void|false 23 | */ 24 | function logModuleCall( 25 | $module, 26 | $action, 27 | $request, 28 | $response, 29 | $data = '', 30 | $variablesToMask = array() 31 | ) { 32 | // do nothing during tests 33 | } 34 | -------------------------------------------------------------------------------- /whmcs.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": "1.0", 3 | "type": "whmcs-registrars", 4 | "name": "sample-registrar-module", 5 | "license": "MIT", 6 | "category": "registrar", 7 | "description": { 8 | "name": "Sample Registrar Module", 9 | "tagline": "Registrar Modules allow you to create modules that allow for the registration and management of domain names in WHMCS.", 10 | "long": "The sample files here demonstrates how a registrar module for WHMCS should be structured and exercises all supported functionality.", 11 | "features": [ 12 | "Provide functionality for registering, transferring and renewing of domains" 13 | ] 14 | }, 15 | "logo": { 16 | "filename": "logo.png" 17 | }, 18 | "support": { 19 | "homepage": "https:\/\/www.whmcs.com\/", 20 | "learn_more": "https:\/\/www.whmcs.com\/tour", 21 | "email": "support@whmcs.com", 22 | "support_url": "https:\/\/support.whmcs.com\/", 23 | "docs_url": "https:\/\/developers.whmcs.com\/domain-registrars\/" 24 | }, 25 | "authors": [ 26 | { 27 | "name": "WHMCS", 28 | "homepage": "https:\/\/www.whmcs.com\/" 29 | } 30 | ] 31 | } 32 | --------------------------------------------------------------------------------