1. Prerequisites
Before installing Author App, ensure your server meets these requirements:
- PHP: Version 7.4 or higher (8.0+ recommended)
- MySQL: Version 5.7 or higher (8.0+ recommended)
- Apache/Nginx: Web server with mod_rewrite enabled
- PHP Extensions: mysqli, mbstring, json, openssl, curl
- Composer: For dependency management
- SSL Certificate: Required for production (free via Let's Encrypt)
2. Installing Author App
Upload the Author App files to your server root directory (e.g., public_html, www, or httpdocs).
Set proper permissions for writable directories:
chmod -R 755 writable/ chmod -R 755 public/
Run Composer to install dependencies:
composer install --no-dev --optimize-autoloader
Visit your domain in a browser. You'll be automatically redirected to the installation wizard:
https://yourdomain.com/
Follow the on-screen instructions to:
- Create database connection
- Set up admin account
- Configure application settings
/install directory to prevent unauthorized access.
3. Initial Configuration
3.1 Login to Admin Panel
After installation, access the admin panel:
https://yourdomain.com/admin
Use the admin credentials you created during installation.
3.2 Add Your Envato Personal Token
Go to https://build.envato.com/create-token/
Create a token with these permissions:
- View and search Envato sites
- View your sales and purchase data
- Verify purchases
In the admin panel:
- Go to Settings → API Configuration
- Paste your Envato Personal Token
- Click Save Settings
- Test the connection using the "Test Token" button
4. Adding Your Products
In the admin panel, go to Products → Add New Product
- Product Name: Your product's name (e.g., "Turnstile - CI4 Admin Template")
- Product Slug: URL-friendly identifier (e.g., "turnstile")
- Product ID: Your Envato Item ID (found in your CodeCanyon URL)
- Current Version: Latest version number (e.g., "1.0.0")
- Description: Brief description of your product
Click Save to add the product to your Author App.
codecanyon.net/item/turnstile/12345678, your Product ID is 12345678
5. Integrating with Your Application
Follow these steps to connect your Envato product with Author App for license management and automatic updates.
5.1 Create Installation Helper File
Create a file called author_app_helper.php in your product's installation directory:
<?php
/**
* Author App Integration Helper
* Handles license registration and update checking
*/
if (!function_exists('getAuthorAppUrl')) {
/**
* Get Author App URL based on environment
*
* @return string Author App base URL
*/
function getAuthorAppUrl() {
// Production URL - Replace with your actual domain
$productionUrl = 'https://licenses.yourdomain.com';
// Development URL
$developmentUrl = 'http://localhost/taskew-author-app';
// Detect environment
$host = $_SERVER['HTTP_HOST'] ?? '';
if (strpos($host, 'localhost') !== false ||
strpos($host, '127.0.0.1') !== false ||
strpos($host, '.local') !== false) {
return $developmentUrl;
}
return $productionUrl;
}
}
if (!function_exists('registerLicense')) {
/**
* Register license with Author App
*
* @param string $purchaseCode Envato purchase code
* @param string $productSlug Product slug from Author App
* @param string $domain Customer's domain
* @param string $email Customer's email
* @return array Response from Author App
*/
function registerLicense($purchaseCode, $productSlug, $domain, $email) {
$authorAppUrl = getAuthorAppUrl();
$endpoint = $authorAppUrl . '/api/v1/license/register';
$data = [
'purchase_code' => $purchaseCode,
'product_slug' => $productSlug,
'domain' => $domain,
'email' => $email
];
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200 && $response) {
return json_decode($response, true);
}
return [
'status' => 'error',
'message' => 'Failed to connect to license server'
];
}
}
if (!function_exists('checkForUpdates')) {
/**
* Check for product updates
*
* @param string $licenseKey License key from registration
* @param string $productSlug Product slug
* @param string $currentVersion Current installed version
* @return array Update information
*/
function checkForUpdates($licenseKey, $productSlug, $currentVersion) {
$authorAppUrl = getAuthorAppUrl();
$endpoint = $authorAppUrl . '/api/v1/product/check-update';
$data = [
'license_key' => $licenseKey,
'product_slug' => $productSlug,
'current_version' => $currentVersion
];
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200 && $response) {
return json_decode($response, true);
}
return [
'update_available' => false,
'message' => 'Failed to check for updates'
];
}
}
if (!function_exists('downloadUpdate')) {
/**
* Download update package
*
* @param string $licenseKey License key
* @param string $productSlug Product slug
* @param string $version Version to download
* @param string $savePath Path to save the update file
* @return bool Success status
*/
function downloadUpdate($licenseKey, $productSlug, $version, $savePath) {
$authorAppUrl = getAuthorAppUrl();
$endpoint = $authorAppUrl . '/api/v1/product/download-update';
$data = [
'license_key' => $licenseKey,
'product_slug' => $productSlug,
'version' => $version
];
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200 && $response) {
return file_put_contents($savePath, $response) !== false;
}
return false;
}
}
?>
5.2 Integrate During Installation
In your product's installation script (e.g., do_install.php), add:
<?php
require_once 'author_app_helper.php';
// After successful database installation and configuration...
// Register with Author App
$purchaseCode = $_POST['purchase_code']; // From installation form
$email = $_POST['email']; // From installation form
$domain = $_SERVER['HTTP_HOST'];
$result = registerLicense(
$purchaseCode,
'your-product-slug', // Replace with your product slug
$domain,
$email
);
if ($result['status'] === 'success') {
// Save license key to your config file or database
$licenseKey = $result['data']['license_key'];
// Example: Save to config file
$config = [
'license_key' => $licenseKey,
'registered_domain' => $domain,
'license_status' => 'active'
];
file_put_contents(
'config/license.php',
'<?php return ' . var_export($config, true) . ';'
);
echo "License registered successfully!";
} else {
echo "License registration failed: " . $result['message'];
}
?>
5.3 Add Update Checker to Admin Panel
Create an update checker in your admin panel (e.g., admin/updates.php):
<?php
require_once '../author_app_helper.php';
// Load license configuration
$licenseConfig = require 'config/license.php';
$licenseKey = $licenseConfig['license_key'];
// Define current version
define('CURRENT_VERSION', '1.0.0');
// Check for updates
$updateInfo = checkForUpdates(
$licenseKey,
'your-product-slug', // Replace with your product slug
CURRENT_VERSION
);
if ($updateInfo['update_available']) {
$newVersion = $updateInfo['version'];
$releaseNotes = $updateInfo['release_notes'];
$publishedDate = $updateInfo['published_at'];
echo '<div class="update-notification">';
echo '<h3>Update Available: Version ' . $newVersion . '</h3>';
echo '<p>Published: ' . date('F j, Y', strtotime($publishedDate)) . '</p>';
echo '<div>' . $releaseNotes . '</div>';
echo '<button onclick="downloadUpdate(\'' . $newVersion . '\')">Download Update</button>';
echo '</div>';
} else {
echo '<p>Your application is up to date!</p>';
}
?>
5.4 Implement Update Download
Create an update handler (e.g., admin/do_update.php):
<?php
require_once '../author_app_helper.php';
// Load license configuration
$licenseConfig = require 'config/license.php';
$licenseKey = $licenseConfig['license_key'];
$version = $_POST['version'] ?? '';
if (empty($version)) {
die('Version is required');
}
// Create updates directory
$updateDir = 'writable/updates/';
if (!is_dir($updateDir)) {
mkdir($updateDir, 0755, true);
}
$updateFile = $updateDir . 'update-' . $version . '.zip';
// Download update
$success = downloadUpdate(
$licenseKey,
'your-product-slug', // Replace with your product slug
$version,
$updateFile
);
if ($success) {
echo json_encode([
'status' => 'success',
'message' => 'Update downloaded successfully',
'file' => $updateFile
]);
// Now you can extract and apply the update
// This is where you'd add your update extraction logic
} else {
echo json_encode([
'status' => 'error',
'message' => 'Failed to download update'
]);
}
?>
your-product-slug with the actual slug you created in Author App (e.g., "turnstile", "rise-crm", etc.)
6. Uploading Product Updates
Create a ZIP file containing your updated product files. Include only the files that need to be updated.
- Go to Products → Select your product
- Click Upload Update
- Select your ZIP file
- Enter the new version number (e.g., "1.1.0")
- Add release notes describing the changes
- Click Upload
After upload, verify:
- The update appears in the product's update history
- The file size is correct
- The version number is accurate
7. Testing Your Integration
7.1 Test License Registration
- Use a valid Envato purchase code
- Install your product on a test domain
- Verify the license is registered in Author App admin panel
- Check that the license key is saved in your product
7.2 Test Update System
- Upload a test update in Author App
- Access your product's admin panel
- Check for updates
- Verify the update notification appears
- Download the update
- Confirm the ZIP file downloads correctly
- License registration works
- Update check returns correct information
- Update download completes successfully
- Support expiration is enforced
- Invalid licenses are rejected
8. Troubleshooting
Q: License registration fails
A: Check that:
- Your Envato Personal Token is correctly configured
- The purchase code is valid and not already used
- Your server can make outbound HTTPS requests
- The product slug matches exactly
Q: Updates not showing
A: Verify that:
- The update was successfully uploaded
- The version number is higher than the current version
- The customer's support hasn't expired
- The license key is correct
Q: Download fails
A: Check:
- File permissions on writable/uploads/updates/ directory
- The update file exists and is accessible
- Server has enough disk space
- PHP memory_limit and max_execution_time are adequate
Q: Getting "Connection failed" errors
A: Ensure:
- Your Author App domain is accessible
- SSL certificate is valid (for production)
- Firewall isn't blocking requests
- cURL extension is installed and enabled
9. Need Help?
If you encounter any issues during installation or integration:
- Check the logs in
writable/logs/directory - Enable debug mode temporarily to see detailed error messages
- Review the CodeIgniter 4 documentation
- Verify all prerequisites are met