mirror of
https://gitlab.com/ArkHost/WP-WHMCS-Pricing.git
synced 2026-07-23 23:45:52 +02:00
v1.0-release
This commit is contained in:
@@ -0,0 +1,160 @@
|
|||||||
|
# WHMCS Pricing
|
||||||
|
|
||||||
|
Display WHMCS product prices on WordPress using shortcodes. Lightweight, cached, works with Elementor.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Upload ZIP via `Plugins > Add New > Upload Plugin`
|
||||||
|
2. Activate
|
||||||
|
3. Go to `Settings > WHMCS Pricing`
|
||||||
|
4. Enter your WHMCS credentials
|
||||||
|
|
||||||
|
## WHMCS Setup
|
||||||
|
|
||||||
|
**Step 1: Allow API Access by IP**
|
||||||
|
|
||||||
|
1. Go to `General Settings > Security` tab in WHMCS
|
||||||
|
2. Find **API IP Access Restriction**
|
||||||
|
3. Add your WordPress server IP address
|
||||||
|
4. Save changes
|
||||||
|
|
||||||
|
**Step 2: Generate API Credentials**
|
||||||
|
|
||||||
|
1. Go to `System Settings > API Credentials`
|
||||||
|
2. Click `Generate New API Credential`
|
||||||
|
3. Set Access Type to `Allowed`
|
||||||
|
4. Copy Identifier and Secret
|
||||||
|
|
||||||
|
Enter these in WordPress plugin settings along with your WHMCS URL.
|
||||||
|
|
||||||
|
**Security Note:** Without adding your WordPress server IP to API IP Access Restriction, the API calls will be blocked by WHMCS.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Basic shortcode:
|
||||||
|
```
|
||||||
|
[whmcs_price product_id="123" billing_cycle="annually"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
- `product_id` - WHMCS product ID (required)
|
||||||
|
- `billing_cycle` - monthly, quarterly, semiannually, annually, biennially, triennially (default: monthly)
|
||||||
|
- `currency` - EUR, USD, GBP, etc. (uses plugin default if not specified)
|
||||||
|
- `format` - `default` or `no_decimals`
|
||||||
|
- `show_cycle` - `true` or `false` (default: true)
|
||||||
|
- `lang` - Language: `english`, `spanish`, `portuguese-pt`, `dutch`, `french`, `german`, `russian` (default: english)
|
||||||
|
- `class` - Custom CSS class
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
[whmcs_price product_id="5" billing_cycle="annually"]
|
||||||
|
Output: €24.00 per year
|
||||||
|
|
||||||
|
[whmcs_price product_id="5" billing_cycle="monthly" format="no_decimals"]
|
||||||
|
Output: €3 per month
|
||||||
|
|
||||||
|
[whmcs_price product_id="5" currency="USD" show_cycle="false"]
|
||||||
|
Output: $3.50
|
||||||
|
|
||||||
|
[whmcs_price product_id="5" billing_cycle="annually" lang="spanish"]
|
||||||
|
Output: €24.00 por año
|
||||||
|
|
||||||
|
[whmcs_price product_id="5" billing_cycle="monthly" lang="dutch"]
|
||||||
|
Output: €3.00 per maand
|
||||||
|
```
|
||||||
|
|
||||||
|
### Translations
|
||||||
|
|
||||||
|
Billing cycle text is translated via `languages.json`. Supported languages:
|
||||||
|
- `english`
|
||||||
|
- `spanish`
|
||||||
|
- `portuguese-pt`
|
||||||
|
- `dutch`
|
||||||
|
- `french`
|
||||||
|
- `german`
|
||||||
|
- `russian`
|
||||||
|
|
||||||
|
Add more languages by editing `languages.json` in the plugin folder (uses WHMCS language naming).
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"italian": {
|
||||||
|
"monthly": "al mese",
|
||||||
|
"annually": "all'anno"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Find Product IDs
|
||||||
|
|
||||||
|
In WHMCS admin:
|
||||||
|
1. `System Settings > Products/Services`
|
||||||
|
2. Click a product
|
||||||
|
3. ID is in URL: `?id=123`
|
||||||
|
|
||||||
|
## HTML Output
|
||||||
|
|
||||||
|
```html
|
||||||
|
<span class="whmcs-price" data-product-id="123" data-cycle="annually">
|
||||||
|
<span class="currency-symbol">€</span>
|
||||||
|
<span class="price-amount">24.00</span>
|
||||||
|
<span class="billing-cycle">per year</span>
|
||||||
|
</span>
|
||||||
|
```
|
||||||
|
|
||||||
|
Style it with CSS:
|
||||||
|
|
||||||
|
```css
|
||||||
|
.whmcs-price { font-weight: bold; }
|
||||||
|
.price-amount { font-size: 24px; }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
**WHMCS uses `-1.00` for unavailable billing cycles.** If a product doesn't have monthly pricing in WHMCS, don't use `billing_cycle="monthly"` in the shortcode. Check your WHMCS product configuration first.
|
||||||
|
|
||||||
|
**Caching:** Prices are cached for 1 hour by default. Change this in plugin settings. Click "Clear All Cache" after updating prices in WHMCS.
|
||||||
|
|
||||||
|
**Errors:** Only administrators see error messages. Regular visitors see nothing if a price can't be loaded.
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
- **WHMCS URL** - Your WHMCS installation URL (https://billing.yourdomain.com)
|
||||||
|
- **API Identifier** - From WHMCS API credentials
|
||||||
|
- **API Secret** - From WHMCS API credentials
|
||||||
|
- **Default Currency** - Fallback currency (EUR, USD, etc.)
|
||||||
|
- **Show Decimals** - Toggle decimal places globally
|
||||||
|
- **Cache Duration** - How long to cache API responses (seconds)
|
||||||
|
- **Debug Mode** - Enable logging, disable cache
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Price shows as -1.00:**
|
||||||
|
- That billing cycle isn't available for this product in WHMCS
|
||||||
|
- Use a different `billing_cycle` parameter
|
||||||
|
|
||||||
|
**No price displays:**
|
||||||
|
- Check product ID exists in WHMCS
|
||||||
|
- Verify API credentials are correct
|
||||||
|
- Enable Debug Mode and check `/wp-content/debug.log`
|
||||||
|
- Clear plugin cache
|
||||||
|
|
||||||
|
**Wrong price:**
|
||||||
|
- Clear cache (prices are cached)
|
||||||
|
- Check currency matches WHMCS configuration
|
||||||
|
- Verify billing cycle is available
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- WordPress 5.0+
|
||||||
|
- PHP 7.4+
|
||||||
|
- WHMCS 8.x with API access
|
||||||
|
- SSL recommended
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
**By:** ArkHost
|
||||||
|
**Sponsored by:** Duplika.com
|
||||||
|
**License:** GPL v2+
|
||||||
@@ -137,6 +137,46 @@ class WHMCS_Pricing_Admin {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'decimal_separator',
|
||||||
|
__('Decimal Separator', 'whmcs-pricing'),
|
||||||
|
array($this, 'render_select_field'),
|
||||||
|
'whmcs-pricing',
|
||||||
|
'whmcs_pricing_display_section',
|
||||||
|
array(
|
||||||
|
'name' => 'decimal_separator',
|
||||||
|
'options' => array(
|
||||||
|
'.' => __('Period (.) - Example: 1,234.56', 'whmcs-pricing'),
|
||||||
|
',' => __('Comma (,) - Example: 1.234,56', 'whmcs-pricing')
|
||||||
|
),
|
||||||
|
'description' => __('Choose the character to use as decimal separator', 'whmcs-pricing')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'hide_currency_symbol',
|
||||||
|
__('Hide Currency Symbol', 'whmcs-pricing'),
|
||||||
|
array($this, 'render_checkbox_field'),
|
||||||
|
'whmcs-pricing',
|
||||||
|
'whmcs_pricing_display_section',
|
||||||
|
array(
|
||||||
|
'name' => 'hide_currency_symbol',
|
||||||
|
'label' => __('Hide currency symbol/prefix from prices', 'whmcs-pricing')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'hide_billing_cycle',
|
||||||
|
__('Hide Billing Cycle', 'whmcs-pricing'),
|
||||||
|
array($this, 'render_checkbox_field'),
|
||||||
|
'whmcs-pricing',
|
||||||
|
'whmcs_pricing_display_section',
|
||||||
|
array(
|
||||||
|
'name' => 'hide_billing_cycle',
|
||||||
|
'label' => __('Hide billing cycle text (e.g., "per month") from prices', 'whmcs-pricing')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Performance Settings Section
|
// Performance Settings Section
|
||||||
add_settings_section(
|
add_settings_section(
|
||||||
'whmcs_pricing_performance_section',
|
'whmcs_pricing_performance_section',
|
||||||
@@ -439,6 +479,28 @@ class WHMCS_Pricing_Admin {
|
|||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function render_select_field($args) {
|
||||||
|
$settings = get_option('whmcs_pricing_settings', array());
|
||||||
|
$value = isset($settings[$args['name']]) ? $settings[$args['name']] : '';
|
||||||
|
|
||||||
|
// Set default value if not set
|
||||||
|
if (empty($value) && isset($args['default'])) {
|
||||||
|
$value = $args['default'];
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<select name="whmcs_pricing_settings[<?php echo esc_attr($args['name']); ?>]" class="regular-text">
|
||||||
|
<?php foreach ($args['options'] as $option_value => $option_label): ?>
|
||||||
|
<option value="<?php echo esc_attr($option_value); ?>" <?php selected($value, $option_value); ?>>
|
||||||
|
<?php echo esc_html($option_label); ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
<?php if (isset($args['description'])): ?>
|
||||||
|
<p class="description"><?php echo esc_html($args['description']); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
public function render_currency_field($args) {
|
public function render_currency_field($args) {
|
||||||
$settings = get_option('whmcs_pricing_settings', array());
|
$settings = get_option('whmcs_pricing_settings', array());
|
||||||
$value = isset($settings[$args['name']]) ? $settings[$args['name']] : 'USD';
|
$value = isset($settings[$args['name']]) ? $settings[$args['name']] : 'USD';
|
||||||
@@ -464,7 +526,8 @@ class WHMCS_Pricing_Admin {
|
|||||||
'SGD' => 'SGD - Singapore Dollar (S$)',
|
'SGD' => 'SGD - Singapore Dollar (S$)',
|
||||||
'NZD' => 'NZD - New Zealand Dollar (NZ$)',
|
'NZD' => 'NZD - New Zealand Dollar (NZ$)',
|
||||||
'MXN' => 'MXN - Mexican Peso (Mex$)',
|
'MXN' => 'MXN - Mexican Peso (Mex$)',
|
||||||
'ZAR' => 'ZAR - South African Rand (R)'
|
'ZAR' => 'ZAR - South African Rand (R)',
|
||||||
|
'ARS' => 'ARS - Argentine Peso ($)'
|
||||||
);
|
);
|
||||||
?>
|
?>
|
||||||
<select name="whmcs_pricing_settings[<?php echo esc_attr($args['name']); ?>]" class="regular-text">
|
<select name="whmcs_pricing_settings[<?php echo esc_attr($args['name']); ?>]" class="regular-text">
|
||||||
@@ -492,7 +555,7 @@ class WHMCS_Pricing_Admin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sanitize text fields
|
// Sanitize text fields
|
||||||
$text_fields = array('api_identifier', 'api_secret', 'default_currency');
|
$text_fields = array('api_identifier', 'api_secret', 'default_currency', 'decimal_separator');
|
||||||
foreach ($text_fields as $field) {
|
foreach ($text_fields as $field) {
|
||||||
if (isset($input[$field])) {
|
if (isset($input[$field])) {
|
||||||
$sanitized[$field] = sanitize_text_field($input[$field]);
|
$sanitized[$field] = sanitize_text_field($input[$field]);
|
||||||
@@ -506,6 +569,8 @@ class WHMCS_Pricing_Admin {
|
|||||||
|
|
||||||
// Sanitize checkboxes
|
// Sanitize checkboxes
|
||||||
$sanitized['show_decimals'] = isset($input['show_decimals']) ? true : false;
|
$sanitized['show_decimals'] = isset($input['show_decimals']) ? true : false;
|
||||||
|
$sanitized['hide_currency_symbol'] = isset($input['hide_currency_symbol']) ? true : false;
|
||||||
|
$sanitized['hide_billing_cycle'] = isset($input['hide_billing_cycle']) ? true : false;
|
||||||
$sanitized['debug_mode'] = isset($input['debug_mode']) ? true : false;
|
$sanitized['debug_mode'] = isset($input['debug_mode']) ? true : false;
|
||||||
|
|
||||||
return $sanitized;
|
return $sanitized;
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ class WHMCS_Pricing_API {
|
|||||||
'cache_duration' => 3600,
|
'cache_duration' => 3600,
|
||||||
'default_currency' => 'USD',
|
'default_currency' => 'USD',
|
||||||
'show_decimals' => true,
|
'show_decimals' => true,
|
||||||
|
'decimal_separator' => '.',
|
||||||
|
'hide_currency_symbol' => false,
|
||||||
|
'hide_billing_cycle' => false,
|
||||||
'debug_mode' => false
|
'debug_mode' => false
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -227,12 +230,16 @@ class WHMCS_Pricing_API {
|
|||||||
private static function format_price($price, $currency, $format) {
|
private static function format_price($price, $currency, $format) {
|
||||||
$settings = self::get_settings();
|
$settings = self::get_settings();
|
||||||
|
|
||||||
|
// Get decimal separator from settings (default to '.')
|
||||||
|
$decimal_sep = isset($settings['decimal_separator']) ? $settings['decimal_separator'] : '.';
|
||||||
|
$thousands_sep = ($decimal_sep === '.') ? ',' : '.';
|
||||||
|
|
||||||
// Apply decimal formatting
|
// Apply decimal formatting
|
||||||
if ($format === 'no_decimals' || !$settings['show_decimals']) {
|
if ($format === 'no_decimals' || !$settings['show_decimals']) {
|
||||||
$price = round($price);
|
$price = round($price);
|
||||||
$formatted_price = number_format($price, 0);
|
$formatted_price = number_format($price, 0, $decimal_sep, $thousands_sep);
|
||||||
} else {
|
} else {
|
||||||
$formatted_price = number_format($price, 2);
|
$formatted_price = number_format($price, 2, $decimal_sep, $thousands_sep);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get currency symbol
|
// Get currency symbol
|
||||||
@@ -271,7 +278,8 @@ class WHMCS_Pricing_API {
|
|||||||
'SGD' => 'S$',
|
'SGD' => 'S$',
|
||||||
'NZD' => 'NZ$',
|
'NZD' => 'NZ$',
|
||||||
'MXN' => 'Mex$',
|
'MXN' => 'Mex$',
|
||||||
'ZAR' => 'R'
|
'ZAR' => 'R',
|
||||||
|
'ARS' => '$'
|
||||||
);
|
);
|
||||||
|
|
||||||
return isset($symbols[$currency]) ? $symbols[$currency] : $currency;
|
return isset($symbols[$currency]) ? $symbols[$currency] : $currency;
|
||||||
|
|||||||
@@ -130,6 +130,16 @@ class WHMCS_Pricing_Shortcodes {
|
|||||||
$classes[] = $custom_class;
|
$classes[] = $custom_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get global settings
|
||||||
|
$settings = get_option('whmcs_pricing_settings', array());
|
||||||
|
$hide_currency_symbol = isset($settings['hide_currency_symbol']) && $settings['hide_currency_symbol'];
|
||||||
|
$hide_billing_cycle = isset($settings['hide_billing_cycle']) && $settings['hide_billing_cycle'];
|
||||||
|
|
||||||
|
// Override billing cycle display based on global setting
|
||||||
|
if ($hide_billing_cycle) {
|
||||||
|
$show_cycle = false;
|
||||||
|
}
|
||||||
|
|
||||||
$cycle_text = $show_cycle ? $this->get_cycle_text($billing_cycle, $lang) : '';
|
$cycle_text = $show_cycle ? $this->get_cycle_text($billing_cycle, $lang) : '';
|
||||||
|
|
||||||
$html = sprintf(
|
$html = sprintf(
|
||||||
@@ -139,10 +149,13 @@ class WHMCS_Pricing_Shortcodes {
|
|||||||
esc_attr($billing_cycle)
|
esc_attr($billing_cycle)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Only show currency symbol if not hidden
|
||||||
|
if (!$hide_currency_symbol) {
|
||||||
$html .= sprintf(
|
$html .= sprintf(
|
||||||
'<span class="currency-symbol">%s</span>',
|
'<span class="currency-symbol">%s</span>',
|
||||||
esc_html($price_data['symbol'])
|
esc_html($price_data['symbol'])
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$html .= sprintf(
|
$html .= sprintf(
|
||||||
'<span class="price-amount">%s</span>',
|
'<span class="price-amount">%s</span>',
|
||||||
|
|||||||
@@ -128,6 +128,9 @@ class WHMCS_Pricing_Plugin {
|
|||||||
'cache_duration' => 3600, // 1 hour
|
'cache_duration' => 3600, // 1 hour
|
||||||
'default_currency' => 'USD',
|
'default_currency' => 'USD',
|
||||||
'show_decimals' => true,
|
'show_decimals' => true,
|
||||||
|
'decimal_separator' => '.',
|
||||||
|
'hide_currency_symbol' => false,
|
||||||
|
'hide_billing_cycle' => false,
|
||||||
'debug_mode' => false
|
'debug_mode' => false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 240 KiB |
Reference in New Issue
Block a user