MEDPOVDeveloper Center
Google Extension Integration

MEDPOV lisans sistemini Google eklentine bağla.

Bu sayfa Manifest V3 tabanlı Chrome/Chromium eklentilerinde lisans anahtarı alma, sunucuya aktivasyon gönderme, cihaz kimliğini sabit tutma, lisans sonucunu saklama ve belirli aralıklarla yeniden doğrulama akışını anlatır.

Activation Endpointhttps://license.medpov.com/api/medpov-extension/license/activate
Product Slugmedpov-google-extension
Free License URLhttps://license.medpov.com/free-license
01

Çalışma mantığı

Eklenti kullanıcıdan lisans anahtarını alır ve bu sunucunun Activation Endpoint adresine gönderir. Sunucu lisans anahtarını, ürün kodunu, bitiş tarihini, durumunu ve aktivasyon limitini kontrol eder. Aynı kurulum için sabit bir install_id kullanıldığı sürece tekrar kontrol yapmak yeni cihaz slotu tüketmez.

Kullanıcı lisans anahtarıEklentiMEDPOV APIDoğrulamaAktif / Hata
Önemli: Eklentide gönderilen product değeri paneldeki Default product slug ile birebir aynı olmalıdır: medpov-google-extension.
02

Manifest V3 izinlerini ekle

chrome.storage.local kullanabilmek için storage izni; lisans sunucusuna istek gönderebilmek için de sunucu origin'i host_permissions altında tanımlanmalıdır.

{
    "manifest_version": 3,
    "name": "My MEDPOV Extension",
    "version": "1.0.0",
    "permissions": [
        "storage"
    ],
    "host_permissions": [
        "https://license.medpov.com/*"
    ],
    "background": {
        "service_worker": "background.js"
    }
}

Mevcut manifest dosyana yalnızca eksik alanları ekle. Var olan permissions, background veya host_permissions alanlarını silme.

03

Ortak aktivasyon modülünü oluştur

Aşağıdaki kodu örneğin license.js dosyasına koyabilirsin. Buradaki install_id ilk çalıştırmada bir kez üretilir ve Chrome local storage içinde saklanır. Bu değer silinmediği sürece aynı bilgisayar aynı aktivasyon olarak görülür.

const LICENSE_ENDPOINT = "https://license.medpov.com/api/medpov-extension/license/activate";
const PRODUCT_SLUG = "medpov-google-extension";

async function getInstallId() {
  const { medpovInstallId } = await chrome.storage.local.get('medpovInstallId');
  if (medpovInstallId) return medpovInstallId;

  const id = crypto.randomUUID();
  await chrome.storage.local.set({ medpovInstallId: id });
  return id;
}

async function activateLicense(licenseKey) {
  const installId = await getInstallId();
  const manifest = chrome.runtime.getManifest();

  const response = await fetch(LICENSE_ENDPOINT, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    },
    body: JSON.stringify({
      license_key: licenseKey.trim(),
      product: PRODUCT_SLUG,
      install_id: installId,
      extension_id: chrome.runtime.id,
      extension_name: manifest.name,
      extension_version: manifest.version,
      browser: navigator.userAgent,
      platform: navigator.platform
    })
  });

  const data = await response.json();
  if (!response.ok || !data.ok) {
    throw new Error(data.message || 'License activation failed.');
  }

  await chrome.storage.local.set({
    medpovLicenseKey: licenseKey.trim(),
    medpovLicenseToken: data.license_token,
    medpovLicenseExpiresAt: data.expires_at,
    medpovLicenseStatus: data.status,
    medpovLicensedProduct: data.product,
    medpovDataKey: data.data_key,
    medpovLastLicenseCheck: Date.now()
  });

  return data;
}
Data Key: data_key yalnızca geçerli bir lisans doğrulandığında API cevabında gelir. Bunu kaynak koda sabit yazmak yerine aktivasyondan sonra kullan.
04

Aktivasyon ekranına bağla

Popup, options veya onboarding ekranındaki lisans kutusunu activateLicense() fonksiyonuna bağlayabilirsin. Basit bir kullanım örneği:

const input = document.querySelector('#licenseKey');
const button = document.querySelector('#activateLicense');
const status = document.querySelector('#licenseStatus');

button.addEventListener('click', async () => {
  status.textContent = 'Checking license...';
  button.disabled = true;

  try {
    const result = await activateLicense(input.value);
    status.textContent = `Active · expires: ${result.expires_at || 'lifetime'}`;
  } catch (error) {
    status.textContent = error.message;
  } finally {
    button.disabled = false;
  }
});

Birden fazla JS dosyası kullanıyorsan Manifest V3 yapına göre modül import/export veya tek bundle tercih edebilirsin.

05

Başarılı API cevabı

Aktivasyon başarılı olduğunda sunucu aşağıdaki alanları döndürür. Eklentinin özelliklerini açarken en az ok, status, product ve gerekiyorsa expires_at alanlarını dikkate al.

{
  "ok": true,
  "message": "License activated.",
  "license_token": "...",
  "data_key": "...",
  "customer_name": "Customer Name",
  "product": "medpov-google-extension",
  "expires_at": "2027-08-15",
  "max_activations": 3,
  "status": "active"
}
license_tokenBaşarılı aktivasyonda üretilen oturum/aktivasyon tokenı.
data_keyLisans başarılıysa teslim edilen eklenti veri anahtarı.
expires_atnull ise lisansın bitiş tarihi yoktur.
max_activationsLisansın izin verdiği toplam kurulum sayısıdır.
06

Lisansı belirli aralıklarla yeniden doğrula

Lisansı yalnızca ilk kurulumda kontrol etmek yerine eklenti açılışında cache kullanıp örneğin 24 saatte bir sunucuya yeniden doğrulama göndermek daha sağlıklı olur. Sabit install_id sayesinde bu istek yeni aktivasyon oluşturmaz.

async function ensureLicenseIsFresh() {
  const state = await chrome.storage.local.get([
    'medpovLicenseKey',
    'medpovLastLicenseCheck'
  ]);

  if (!state.medpovLicenseKey) return { ok: false, reason: 'missing-license' };

  const ONE_DAY = 24 * 60 * 60 * 1000;
  const lastCheck = Number(state.medpovLastLicenseCheck || 0);

  if (Date.now() - lastCheck < ONE_DAY) {
    return { ok: true, cached: true };
  }

  try {
    const data = await activateLicense(state.medpovLicenseKey);
    return { ok: true, cached: false, data };
  } catch (error) {
    await chrome.storage.local.set({ medpovLicenseStatus: 'invalid' });
    return { ok: false, reason: error.message };
  }
}

Kontrol sıklığını API rate limit değerine göre seç. Her sayfa açılışında tekrar tekrar aktivasyon isteği göndermek yerine cache kullan.

07

Hata ve durum yönetimi

403Lisans pasif, süresi dolmuş, ürün uyuşmuyor veya aktivasyon limiti dolmuş olabilir.
404Lisans anahtarı bulunamadı.
422Lisans anahtarı veya product gibi zorunlu alanlar geçersiz/eksik.
429Çok fazla istek gönderildi; kullanıcıya daha sonra tekrar denemesini söyle.
500Sunucu yapılandırması eksik olabilir. Kullanıcı tarafında sınırsız retry döngüsü oluşturma.

Lisans geçersiz olduğunda premium/korunan özelliği kapat; ancak kullanıcı arayüzünde lisans anahtarını düzeltmesi veya yenilemesi için anlaşılır bir yol bırak.

08

Güvenlik kuralları

  • Admin e-posta/şifresini, private config dosyasını veya sunucu gizli değerlerini eklentiye koyma.
  • install_id her aktivasyon denemesinde yeniden üretilmemeli; aksi halde aynı kullanıcı aktivasyon limitini tüketir.
  • Lisans anahtarını loglara, analytics eventlerine veya hata raporlarına düz metin olarak gönderme.
  • chrome.storage.local şifreli kasa değildir. Hassas verileri gereğinden uzun süre saklama ve kaynak kodda gerçek secret tutma.
  • Eklentinin sadece local cache değerine güvenip sonsuza kadar çalışmasına izin verme; periyodik sunucu kontrolü yap.
  • Endpoint ve product slug public olabilir; yönetim erişimi ve private server config kesinlikle public olmamalıdır.
09

Yayınlamadan önce test checklist