EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
whmcsService.js
Go to the documentation of this file.
1/**
2 * WHMCS API Service
3 * Integrates with WHMCS API to fetch customers, domains, products, etc.
4 *
5 * API Documentation: https://developers.whmcs.com/api/
6 */
7
8const axios = require('axios');
9
10/**
11 *
12 */
13class WHMCSService {
14 /**
15 *
16 */
17 constructor() {
18 this.baseUrl = process.env.WHMCS_URL;
19 this.identifier = process.env.WHMCS_IDENTIFIER;
20 this.secret = process.env.WHMCS_SECRET;
21
22 if (!this.baseUrl || !this.identifier || !this.secret) {
23 throw new Error('WHMCS credentials not configured in .env');
24 }
25 }
26
27 /**
28 * Make API request to WHMCS
29 * @param {string} action - WHMCS API action
30 * @param {object} params - Additional parameters
31 * @returns {Promise<object>} - API response
32 */
33 async apiRequest(action, params = {}) {
34 try {
35 const postData = {
36 action,
37 identifier: this.identifier,
38 secret: this.secret,
39 responsetype: 'json',
40 ...params
41 };
42
43 // WHMCS API endpoint is at /includes/api.php relative to admin directory
44 const apiUrl = this.baseUrl + '/includes/api.php';
45 console.log(`[WHMCS] API Request: ${action} -> ${apiUrl}`);
46
47 const response = await axios.post(
48 apiUrl,
49 new URLSearchParams(postData).toString(),
50 {
51 headers: {
52 'Content-Type': 'application/x-www-form-urlencoded'
53 }
54 }
55 );
56
57 if (response.data.result === 'error') {
58 throw new Error(response.data.message || 'WHMCS API error');
59 }
60
61 return response.data;
62 } catch (error) {
63 console.error(`[WHMCS] API Error (${action}):`, error.message);
64 throw error;
65 }
66 }
67
68 /**
69 * Get all clients from WHMCS
70 * @param {object} options - Filter options
71 * @returns {Promise<Array>} - Array of clients
72 */
73 async getClients(options = {}) {
74 const {
75 limitstart = 0,
76 limitnum = 999999,
77 search = '',
78 status = '' // Active, Inactive, Closed
79 } = options;
80
81 const response = await this.apiRequest('GetClients', {
82 limitstart,
83 limitnum,
84 search,
85 ...(status && { status })
86 });
87
88 return response.clients?.client || [];
89 }
90
91 /**
92 * Get detailed information for a specific client
93 * @param {number} clientId - WHMCS client ID
94 * @returns {Promise<object>} - Client details
95 */
96 async getClientDetails(clientId) {
97 const response = await this.apiRequest('GetClientsDetails', {
98 clientid: clientId,
99 stats: true
100 });
101
102 return response;
103 }
104
105 /**
106 * Get all domains from WHMCS
107 * @param {object} options - Filter options
108 * @returns {Promise<Array>} - Array of domains
109 */
110 async getDomains(options = {}) {
111 const {
112 limitstart = 0,
113 limitnum = 999999,
114 clientid = '',
115 domainname = ''
116 } = options;
117
118 const response = await this.apiRequest('GetClientsDomains', {
119 limitstart,
120 limitnum,
121 ...(clientid && { clientid }),
122 ...(domainname && { domainname })
123 });
124
125 return response.domains?.domain || [];
126 }
127
128 /**
129 * Get all products/services from WHMCS
130 * @param {object} options - Filter options
131 * @returns {Promise<Array>} - Array of products
132 */
133 async getProducts(options = {}) {
134 const {
135 limitstart = 0,
136 limitnum = 999999,
137 clientid = '',
138 serviceid = ''
139 } = options;
140
141 const response = await this.apiRequest('GetClientsProducts', {
142 limitstart,
143 limitnum,
144 ...(clientid && { clientid }),
145 ...(serviceid && { serviceid })
146 });
147
148 return response.products?.product || [];
149 }
150
151 /**
152 * Get all invoices from WHMCS
153 * @param {object} options - Filter options
154 * @returns {Promise<Array>} - Array of invoices
155 */
156 async getInvoices(options = {}) {
157 const {
158 limitstart = 0,
159 limitnum = 999999,
160 userid = '',
161 status = '' // Unpaid, Paid, Cancelled, Refunded
162 } = options;
163
164 const response = await this.apiRequest('GetInvoices', {
165 limitstart,
166 limitnum,
167 ...(userid && { userid }),
168 ...(status && { status })
169 });
170
171 return response.invoices?.invoice || [];
172 }
173
174 /**
175 * Get all tickets from WHMCS
176 * @param {object} options - Filter options
177 * @returns {Promise<Array>} - Array of tickets
178 */
179 async getTickets(options = {}) {
180 const {
181 limitstart = 0,
182 limitnum = 999999,
183 clientid = '',
184 status = '' // Open, Answered, Customer-Reply, Closed
185 } = options;
186
187 const response = await this.apiRequest('GetTickets', {
188 limitstart,
189 limitnum,
190 ...(clientid && { clientid }),
191 ...(status && { status })
192 });
193
194 return response.tickets?.ticket || [];
195 }
196
197 /**
198 * Get custom client fields
199 * @returns {Promise<Array>} - Array of custom fields
200 */
201 async getCustomFields() {
202 const response = await this.apiRequest('GetCustomFields', {
203 type: 'client'
204 });
205
206 return response.customfields?.customfield || [];
207 }
208
209 /**
210 * Export all clients with related data
211 * @returns {Promise<object>} - Complete export
212 */
213 async exportAllData() {
214 console.log('[WHMCS] Starting full data export...');
215
216 const clients = await this.getClients({ status: 'Active' });
217 console.log(`[WHMCS] Found ${clients.length} active clients`);
218
219 const allDomains = await this.getDomains();
220 console.log(`[WHMCS] Found ${allDomains.length} domains`);
221
222 const allProducts = await this.getProducts();
223 console.log(`[WHMCS] Found ${allProducts.length} products`);
224
225 const customFields = await this.getCustomFields();
226 console.log(`[WHMCS] Found ${customFields.length} custom fields`);
227
228 return {
229 clients,
230 domains: allDomains,
231 products: allProducts,
232 customFields,
233 exportedAt: new Date().toISOString()
234 };
235 }
236
237 /**
238 * Test API connection
239 * @returns {Promise<boolean>} - Connection status
240 */
241 async testConnection() {
242 try {
243 const response = await this.apiRequest('GetClients', {
244 limitnum: 1
245 });
246
247 console.log('[WHMCS] ✅ API connection successful');
248 return true;
249 } catch (error) {
250 console.error('[WHMCS] ❌ API connection failed:', error.message);
251 return false;
252 }
253 }
254}
255
256module.exports = WHMCSService;