124 lines
3.5 KiB
PHP
124 lines
3.5 KiB
PHP
<?php
|
||
// /public/resiliation_action.php
|
||
require_once __DIR__ . '/../includes/init_praticien.php';
|
||
|
||
|
||
if (!isset($pdo) || !($pdo instanceof PDO)) {
|
||
http_response_code(500);
|
||
exit('DB_ERROR');
|
||
}
|
||
|
||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||
|
||
$praticien_id = (int)($_SESSION['reference_id'] ?? 0);
|
||
if ($praticien_id <= 0) {
|
||
header('Location: /public/login.php');
|
||
exit;
|
||
}
|
||
|
||
// ---- Helper: colonne existe ? (évite de casser selon schéma) ----
|
||
function colExists(PDO $pdo, string $table, string $col): bool {
|
||
static $cache = [];
|
||
$k = $table.'.'.$col;
|
||
if (array_key_exists($k, $cache)) return $cache[$k];
|
||
$st = $pdo->prepare("
|
||
SELECT 1
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = DATABASE()
|
||
AND TABLE_NAME = ?
|
||
AND COLUMN_NAME = ?
|
||
LIMIT 1
|
||
");
|
||
$st->execute([$table, $col]);
|
||
$cache[$k] = (bool)$st->fetchColumn();
|
||
return $cache[$k];
|
||
}
|
||
|
||
try {
|
||
// 🔎 Récupération du billing le plus récent "utile"
|
||
// On vise l’entrée la plus récente; si elle est déjà canceled, ça reste idempotent.
|
||
$stmt = $pdo->prepare("
|
||
SELECT id, billing_mode, provider, provider_subscription_id, current_period_end, status
|
||
FROM billing_subscriptions
|
||
WHERE praticien_id = ?
|
||
ORDER BY id DESC
|
||
LIMIT 1
|
||
");
|
||
$stmt->execute([$praticien_id]);
|
||
$billing = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
|
||
|
||
// ==========================
|
||
// 1) Appel Stripe (si auto)
|
||
// ==========================
|
||
if ($billing) {
|
||
$isAutoStripe = (
|
||
(string)($billing['billing_mode'] ?? '') === 'auto'
|
||
&& (string)($billing['provider'] ?? '') === 'stripe'
|
||
&& !empty($billing['provider_subscription_id'])
|
||
);
|
||
|
||
if ($isAutoStripe) {
|
||
require_once __DIR__ . '/../../plata/lib/stripe_client.php'; // $stripe
|
||
|
||
try {
|
||
// Résiliation à fin de période
|
||
$stripe->subscriptions->update(
|
||
(string)$billing['provider_subscription_id'],
|
||
['cancel_at_period_end' => true]
|
||
);
|
||
} catch (Throwable $e) {
|
||
// On ne bloque pas la résiliation locale si Stripe échoue
|
||
@file_put_contents(
|
||
'/tmp/stripe_resiliation.log',
|
||
'['.date('c').'] '.$e->getMessage()."\n",
|
||
FILE_APPEND
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
// ==========================
|
||
// 2) Mise à jour locale (TX)
|
||
// ==========================
|
||
$pdo->beginTransaction();
|
||
|
||
// 2.1) billing_subscriptions -> canceled (+ flags si colonnes existent)
|
||
if ($billing && !empty($billing['id'])) {
|
||
$sets = ["status = 'canceled'"];
|
||
$vals = [];
|
||
|
||
if (colExists($pdo, 'billing_subscriptions', 'cancel_at_period_end')) {
|
||
$sets[] = "cancel_at_period_end = 1";
|
||
}
|
||
if (colExists($pdo, 'billing_subscriptions', 'canceled_at')) {
|
||
$sets[] = "canceled_at = NOW()";
|
||
}
|
||
|
||
$sql = "UPDATE billing_subscriptions SET ".implode(', ', $sets)." WHERE id = ?";
|
||
$vals[] = (int)$billing['id'];
|
||
|
||
$pdo->prepare($sql)->execute($vals);
|
||
}
|
||
|
||
// 2.2) praticien -> abonnement_id NULL (NE PAS toucher date_expiration)
|
||
if (colExists($pdo, 'praticien', 'abonnement_id')) {
|
||
$pdo->prepare("UPDATE praticien SET abonnement_id = NULL WHERE id = ?")
|
||
->execute([$praticien_id]);
|
||
}
|
||
|
||
$pdo->commit();
|
||
|
||
} catch (Throwable $e) {
|
||
if ($pdo->inTransaction()) $pdo->rollBack();
|
||
@file_put_contents(
|
||
'/tmp/resiliation_error.log',
|
||
'['.date('c').'] '.$e->getMessage()."\n",
|
||
FILE_APPEND
|
||
);
|
||
}
|
||
|
||
// Redirection finale
|
||
header('Location: /public/praticien/resiliation.php?ok=1');
|
||
exit;
|