Developer Guide

Integrate your web application with the GTS License API for subscription-based licensing.

Overview

Connect your application (PHP, WordPress, Laravel, or any language) to verify licenses in real-time. The API validates license keys, domain binding, and subscription status.

API Endpoints

Method Endpoint Description
GET/api/statusAPI health check
GET/api/applicationsList applications (get app slugs)
GET/api/applications/{slug}Get app integration info
POST/api/verify-licenseVerify license key
POST/api/license-renewal-linkCreate a signed renewal link from an activated installation
POST/api/check-updateCheck for a published update package
GET/api/download-update/{token}Download signed temporary update ZIP

Verify License Request

POST https://gtsappstore.com/api/verify-license

{
  "license_key": "GTS-XXXXX-XXXXX-XXXXX-XXXXX",
  "domain": "yourdomain.com",
  "app_id": "gts-pos",
  "secret_token": "required-if-present-on-license"
}

Response (Active)

{
  "data": {
    "status": "active",
    "message": "License is valid",
    "expires_at": "2026-03-28T00:00:00.000000Z",
    "in_grace_period": false,
    "renewal_url": "https://example.com/license-renewals/1?expires=..."
  },
  "signature": "hmac-sha256",
  "valid": true
}

Renew From Installed System

An activated installation can request a short-lived renewal URL and send the user to the hosted renewal payment page. The submitted domain must already be bound to the license, so renewal links cannot be created from a different installation.

POST https://gtsappstore.com/api/license-renewal-link

{
  "license_key": "GTS-XXXXX-XXXXX-XXXXX-XXXXX",
  "domain": "yourdomain.com",
  "app_id": "gts-pos",
  "secret_token": "required-if-present-on-license"
}
{
  "success": true,
  "renewal_url": "https://example.com/license-renewals/1?expires=...",
  "expires_in_minutes": 60,
  "license": {
    "status": "active",
    "expires_at": "2026-03-28T00:00:00.000000Z",
    "in_grace_period": false,
    "application": "GTS POS",
    "plan": "Monthly"
  }
}

Use the renewal_url as the target for a Renew License button inside the installed application. The hosted page shows the license, plan, optional add-ons, and starts payment through the configured gateway.

Check Update Request

POST https://gtsappstore.com/api/check-update

Send form POST fields. The domain should be the POS domain without protocol; the API also normalizes it by lowercasing, removing http:// or https://, and trimming path or trailing slash data.

license_key=GTS-XXXXX-XXXXX-XXXXX-XXXXX
domain=store.example.com
app_id=gts-pos-retail
current_version=3.4.1
php_version=8.2.12
secret_token=required-if-present-on-license

Update Response

The POS-compatible response keys are fixed. Do not rename these keys in client integrations.

{
  "success": true,
  "data": {
    "update_available": true,
    "latest_version": "3.4.2",
    "package_url": "https://example.com/api/download-update/SIGNED_TOKEN",
    "checksum_sha256": "SHA256_OF_UPDATE_ZIP",
    "release_notes": "Bug fixes and compatibility updates."
  }
}

When no update is available, update_available is false, latest_version echoes the submitted current version, and package_url, checksum_sha256, and release_notes are empty strings.

{
  "success": true,
  "data": {
    "update_available": false,
    "latest_version": "3.4.1",
    "package_url": "",
    "checksum_sha256": "",
    "release_notes": ""
  }
}

Update Validation

  • license_key, domain, app_id, and current_version are required.
  • The license must match the submitted application slug, be active, not expired, and include the submitted domain in its allowed domains.
  • If the license has a stored secret_token, the submitted token is required and must match.
  • Missing fields return HTTP 422. Invalid, inactive, expired, unauthorized domain, or bad token checks return HTTP 403.
{
  "success": false,
  "message": "License is not active."
}

Publishing Update Packages

Create an update-safe POS ZIP from the POS project, then store it on the server and create a published release record.

php build_package.php --optimize --update-safe --version=3.4.2

Release records are stored in update_releases and should include app_id, version, package_type=update, package_path, checksum_sha256, optional min_php_version, release_notes, status=published, and published_at.

The download URL contains a signed temporary token with release_id, license_id, expiry, and an HMAC-SHA256 signature. Tokens expire after about 15 minutes. Production URLs are served as HTTPS, and the download endpoint only serves update ZIP files.

POS Auto Updater

Install sdk/GtsUpdateClient.php in the POS project and run it from a protected admin action, cron job, or login-time background check. It checks for updates, downloads the signed ZIP, verifies checksum_sha256, backs up overwritten files, applies the package, and rolls back if copying fails.

$client = new GtsUpdateClient(
    'https://gtsappstore.com',
    'GTS-XXXXX-XXXXX-XXXXX-XXXXX',
    'gts-pos-retail',
    '3.4.1',
    dirname(__DIR__),
    'required-token-when-present-on-license'
);

$result = $client->run();

PHP SDK

Copy sdk/GtsLicenseClient.php into your project:

$client = new GtsLicenseClient(
    'https://gtsappstore.com',
    'GTS-XXXXX-XXXXX-XXXXX-XXXXX',
    'gts-pos'
);
$result = $client->verify();
if ($result['valid']) {
    // License active
} else {
    // Show: $result['message']
}

Status Values

  • active — License valid, grant access
  • expired — Subscription ended, show renewal
  • suspended — Admin suspended, show support message
  • invalid_domain — Domain not authorized

Full Documentation

For the complete integration guide including WordPress, Node.js, Python examples, and best practices, see docs/DEVELOPER_GUIDE.md in the repository. Contact us for integration support.