Files
dewemoji-api/app/controllers/License.php

161 lines
5.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// app/controllers/License.php
require_once __DIR__ . '/../helpers/cors.php';
require_once __DIR__ . '/../helpers/http.php';
require_once __DIR__ . '/../models/license_store.php';
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$path = $_GET['_action'] ?? 'verify'; // e.g., routed as /license/verify
if ($method === 'OPTIONS') { cors_preflight(); exit; }
switch ($path) {
case 'verify':
handle_verify();
break;
// You likely already have activate/deactivate; leaving them out here.
default:
json_error(404, 'not_found');
}
function handle_verify() {
cors_allow();
$input = json_decode(file_get_contents('php://input'), true) ?: [];
$key = trim((string)($input['key'] ?? ''));
$acct = trim((string)($input['account_id'] ?? ''));
if ($key === '') { json_error(400, 'missing_key'); }
$mode = cfg('gateway_mode', 'sandbox');
// Sandbox: accept anything
if ($mode !== 'live') {
$norm = [
'key' => $key,
'source' => preg_match('/^G|^GMR|^GUM/i', $key) ? 'gumroad' : (preg_match('/^M|^MYR/i',$key) ? 'mayar' : 'sandbox'),
'plan' => 'pro', // treat as Pro
'product_id' => null,
'valid' => true,
'expires_at' => null,
'meta' => ['mode'=>'sandbox']
];
$row = license_upsert_from_verification($norm);
json_ok(['source'=>$norm['source'],'plan'=>$norm['plan'],'license'=>$row]);
}
// LIVE mode: try Gumroad first, then Mayar
$gum = verify_gumroad($key);
if ($gum['ok']) {
$row = license_upsert_from_verification($gum['norm']);
json_ok(['source'=>'gumroad','plan'=>$gum['norm']['plan'],'license'=>$row]);
}
$may = verify_mayar($key);
if ($may['ok']) {
$row = license_upsert_from_verification($may['norm']);
json_ok(['source'=>'mayar','plan'=>$may['norm']['plan'],'license'=>$row]);
}
json_error(401, 'invalid_license', ['details'=>['gumroad'=>$gum['err']??null,'mayar'=>$may['err']??null]]);
}
// --- Providers ---
function verify_gumroad($licenseKey) {
$cfg = cfg('gumroad', []);
$url = $cfg['verify_url'] ?? 'https://api.gumroad.com/v2/licenses/verify';
$pids = $cfg['product_ids'] ?? [];
// Gumroad expects POST form with license_key (+ product_id if you want to restrict)
$fields = ['license_key' => $licenseKey];
if (!empty($pids)) {
// If you have multiple products, you can loop; for simplicity, try them in order
foreach ($pids as $pid) {
$try = $fields + ['product_id' => $pid];
[$code,$body,$err] = http_post_form($url, $try);
if ($code >= 200 && $code < 300) {
$json = json_decode($body, true);
if (isset($json['success']) && $json['success'] === true) {
// Normalize
$p = $json['purchase'] ?? [];
$isRecurring = !empty($p['recurrence']);
$plan = $isRecurring ? 'subscription' : 'lifetime';
$expires = null; // Gumroad verify doesnt usually return expiry for subs; optional to compute
return ['ok'=>true,'norm'=>[
'key' => $licenseKey,
'source' => 'gumroad',
'plan' => 'pro', // Your product => Pro features; if you want to store type, add meta
'product_id' => $pid,
'valid' => true,
'expires_at' => $expires,
'meta' => ['raw'=>$json,'plan_type'=>$plan]
]];
}
}
}
return ['ok'=>false,'err'=>'gumroad_no_match'];
} else {
// No product restriction
[$code,$body,$err] = http_post_form($url, $fields);
if ($code >= 200 && $code < 300) {
$json = json_decode($body, true);
if (isset($json['success']) && $json['success'] === true) {
$p = $json['purchase'] ?? [];
$isRecurring = !empty($p['recurrence']);
$plan = $isRecurring ? 'subscription' : 'lifetime';
return ['ok'=>true,'norm'=>[
'key' => $licenseKey,
'source' => 'gumroad',
'plan' => 'pro',
'product_id' => $p['product_id'] ?? null,
'valid' => true,
'expires_at' => null,
'meta' => ['raw'=>$json,'plan_type'=>$plan]
]];
}
}
return ['ok'=>false,'err'=>'gumroad_verify_failed'];
}
}
function verify_mayar($licenseKey) {
$cfg = cfg('mayar', []);
$base = rtrim($cfg['api_base'] ?? '', '/');
$ep = $cfg['endpoint_verify'] ?? '/v1/license/verify';
$url = $base . $ep;
// Most vendors use JSON body; adjust per your doc.
// If Mayar requires Authorization, add it here.
$headers = [];
if (!empty($cfg['secret_key'])) {
$headers[] = 'Authorization: Bearer ' . $cfg['secret_key'];
}
[$code,$body,$err] = http_post_json($url, ['license_key'=>$licenseKey], $headers);
if (!($code >= 200 && $code < 300)) {
return ['ok'=>false,'err'=>'mayar_http_'.$code];
}
$json = json_decode($body, true);
// Normalize based on Mayars response shape
// Expect something like: { success:true, data:{ valid:true, product_id:'...', type:'lifetime|subscription', expires_at: '...' } }
$valid = (bool)($json['success'] ?? false);
if (!$valid) return ['ok'=>false,'err'=>'mayar_invalid'];
$data = $json['data'] ?? [];
$planType = strtolower((string)($data['type'] ?? 'lifetime')); // lifetime or subscription
$expiresAt = $data['expires_at'] ?? null;
return ['ok'=>true,'norm'=>[
'key' => $licenseKey,
'source' => 'mayar',
'plan' => 'pro',
'product_id' => $data['product_id'] ?? null,
'valid' => true,
'expires_at' => $expiresAt,
'meta' => ['raw'=>$json,'plan_type'=>$planType]
]];
}