turnstile

Drupal paywall plugin
Log | Files | Refs | README | LICENSE

commit 86ae19ad5c5b71400c48f0063a0ae4539d555258
parent a06c174c518b0561e44fc3c5001746bae9293c86
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 24 Jul 2025 00:14:10 +0200

add FIXMEs for TS

Diffstat:
Msrc/Service/TurnstileService.php | 92++++++++++++++++++++++++-------------------------------------------------------
1 file changed, 28 insertions(+), 64 deletions(-)

diff --git a/src/Service/TurnstileService.php b/src/Service/TurnstileService.php @@ -39,93 +39,58 @@ class Turnstile { $this->httpClient = $http_client; } - /** - * Verify payment status with the backend. - * - * @param string $node_id - * The node ID. - * @param string $user_id - * The user ID. - * - * @return bool - * TRUE if payment is verified, FALSE otherwise. - */ - public function verifyPayment($node_id, $user_id) { - $config = $this->configFactory->get('turnstile.settings'); - $backend_url = $config->get('payment_backend_url'); - $access_token = $config->get('access_token'); - - if (empty($backend_url) || empty($access_token)) { - return FALSE; - } - - try { - $response = $this->httpClient->post($backend_url . '/verify', [ - 'json' => [ - 'node_id' => $node_id, - 'user_id' => $user_id, - ], - 'headers' => [ - 'Authorization' => 'Bearer ' . $access_token, - 'Content-Type' => 'application/json', - ], - ]); - - $data = json_decode($response->getBody(), TRUE); - return isset($data['verified']) && $data['verified'] === TRUE; - } - catch (RequestException $e) { - // Log the error and return FALSE. - \Drupal::logger('turnstile')->error('Payment verification failed: @message', ['@message' => $e->getMessage()]); - return FALSE; - } - } /** * Check if user has access to content. * * @param string $node_id * The node ID. - * @param string $user_id - * The user ID. * * @return bool * TRUE if user has access, FALSE otherwise. */ - public function hasAccess($node_id, $user_id) { + public function hasAccess($node_id) { // Start session if not already started. if (session_status() == PHP_SESSION_NONE) { session_start(); } // Check if user is a subscriber. - if (isset($_SESSION['paywall_subscriber']) && $_SESSION['paywall_subscriber'] === TRUE) { + if (isset($_SESSION['turnstile_subscriber']) && $_SESSION['turnstile_subscriber'] === TRUE) { + // FIXME: should set turnstile_subscriber to *expiration* time + // of the subscription and check not for TRUE but for "greater + // current time". + // Subscribers have full access to everything return TRUE; } // Check session-based orders. - if (isset($_SESSION['paywall_orders'][$node_id])) { - $order = $_SESSION['paywall_orders'][$node_id]; - + if (isset($_SESSION['turnstile_orders'][$node_id])) { + $order = $_SESSION['turnstile_orders'][$node_id]; + // Check if order is paid and not refunded. - if (isset($order['paid']) && $order['paid'] === TRUE && + // FIXME: refunds are not really supported, do we care to + // keep support for them here? + if (isset($order['paid']) && $order['paid'] === TRUE && (!isset($order['refunded']) || $order['refunded'] === FALSE)) { return TRUE; } - + // Check order status with backend if not marked as paid. if (!$order['paid']) { $status = $this->checkOrderStatus($order['order_id']); if ($status && $status['paid']) { // Update session with new status. - $_SESSION['paywall_orders'][$node_id]['paid'] = TRUE; + // FIXME: if we keep refunds above, we should check + // for refunds here as well! + $_SESSION['turnstile_orders'][$node_id]['paid'] = TRUE; return TRUE; } } } - // Fallback to backend verification. - return $this->verifyPayment($node_id, $user_id); + // User does NOT have access, caller should create order. + return FALSE; } /** @@ -153,8 +118,12 @@ class Turnstile { ], ]); + // FIXME: check HTTP status first... $result = json_decode($response->getBody(), TRUE); - + + // FIXME: check $result['contract_terms'] to see if this is + // a valid *subscription*, and if so, return subscription status! + return [ 'order_id' => $order_id, 'paid' => isset($result['order_status']) && $result['order_status'] === 'paid', @@ -197,16 +166,9 @@ class Turnstile { 'amount' => $price, 'summary' => 'Access to: ' . $node->getTitle(), 'fulfillment_url' => $fulfillment_url, - 'products' => [ - [ - 'product_id' => 'node_' . $node->id(), - 'description' => 'Access to article: ' . $node->getTitle(), - 'quantity' => 1, - 'price' => $price, - ] ], ], - 'create_token' => TRUE, + 'create_token' => FALSE, ]; try { @@ -218,12 +180,14 @@ class Turnstile { ], ]); + // FIXME: check HTTP status first... $result = json_decode($response->getBody(), TRUE); - + if (isset($result['order_id'])) { + // FIXME: Someone must set + // $_SESSION['turnstile_orders'][$node_id]['order_id'] = $result['order_id']; return [ 'order_id' => $result['order_id'], - 'order_token' => $result['token'] ?? '', 'payment_url' => $backend_url . '/orders/' . $result['order_id'], 'paid' => FALSE, 'refunded' => FALSE,