From 6edf9f9ca87c256269492ccebfd7e2ffe05ac19d Mon Sep 17 00:00:00 2001 From: ManiruzzamanAkash Date: Mon, 14 Sep 2026 15:55:45 +0600 Subject: [PATCH 1/7] Fix: Licensing SDK deletes stored licence key on temporary API errors --- src/Settings.php | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Settings.php b/src/Settings.php index 8e32a5e..f02d4e4 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -293,18 +293,32 @@ public function print_css() { /** * Get the activation. * + * Only a 404 proves the activation is gone. Any other failure (timeout, 5xx, + * rate limit, auth) is transient, so the stored key must survive it. + * * @return Object|false */ public function get_activation() { - $activation = false; - if ( $this->activation_id ) { - $activation = $this->client->activation()->get( $this->activation_id ); - if ( is_wp_error( $activation ) ) { - $this->add_error( 'deactivaed', $this->client->__( 'Your license has been deactivated for this site.', 'surecart' ) ); - $this->clear_options(); - } + if ( ! $this->activation_id ) { + return false; + } + + $activation = $this->client->activation()->get( $this->activation_id ); + + if ( ! is_wp_error( $activation ) ) { + return $activation; } - return $activation; + + if ( 'not_found' === $activation->get_error_code() ) { + $this->add_error( 'deactivated', $this->client->__( 'Your license has been deactivated for this site.' ) ); + $this->clear_options(); + return false; + } + + $this->add_error( 'unverified', $this->client->__( 'Could not verify your license right now. Your license key has been kept; please try again later.' ) ); + + // Keep the form in "activated" state so the user is not asked to re-enter the key. + return (object) array( 'id' => $this->activation_id ); } /** From 7d2a92525df9fa052305ed362159179848b11767 Mon Sep 17 00:00:00 2001 From: ManiruzzamanAkash Date: Mon, 14 Sep 2026 20:08:39 +0600 Subject: [PATCH 2/7] Fixed don't forcefully clear the option but let the merchant do that --- src/Settings.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Settings.php b/src/Settings.php index f02d4e4..8bac9d9 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -293,8 +293,9 @@ public function print_css() { /** * Get the activation. * - * Only a 404 proves the activation is gone. Any other failure (timeout, 5xx, - * rate limit, auth) is transient, so the stored key must survive it. + * A read never deletes the license key; only an explicit deactivate does. A 404 + * means the activation is gone, so drop just the activation id and let the user + * re-activate with the key pre-filled. Any other failure is transient: keep everything. * * @return Object|false */ @@ -310,8 +311,8 @@ public function get_activation() { } if ( 'not_found' === $activation->get_error_code() ) { - $this->add_error( 'deactivated', $this->client->__( 'Your license has been deactivated for this site.' ) ); - $this->clear_options(); + $this->activation_id = null; + $this->add_error( 'activation_removed', $this->client->__( 'The activation for this site was removed. Click Activate License to reconnect it.' ) ); return false; } From 551932a83bd9e2ec4cfdec0bebdab4f4d449620e Mon Sep 17 00:00:00 2001 From: ManiruzzamanAkash Date: Wed, 16 Sep 2026 17:07:12 +0600 Subject: [PATCH 3/7] Bump version to 1.2.1 Patch release for the licensing SDK fix that keeps the stored license key on temporary API errors instead of clearing it. Co-Authored-By: Claude Sonnet 5 --- src/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index 0a7f4ff..fd2ad0b 100644 --- a/src/Client.php +++ b/src/Client.php @@ -12,7 +12,7 @@ class Client { * * @var string */ - public $version = '1.2.0'; + public $version = '1.2.1'; /** * Name of the plugin From 6e24238d9b46dacf8be54096fbbf10a2df1d5855 Mon Sep 17 00:00:00 2001 From: ManiruzzamanAkash Date: Wed, 16 Sep 2026 17:43:13 +0600 Subject: [PATCH 4/7] Update SDK example plugin and theme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 27b2e74..ce3688a 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ $client->set_textdomain( 'your-project-textdomain' ); ``` ## Example Plugin -[surecart-plugin-license.zip](https://d.pr/f/DVzMC0) +[surecart-plugin-license.zip](https://d.pr/f/VRK01i) ## Example Theme -[surecart-theme-license.zip](https://d.pr/f/m51Tt5) +[surecart-theme-license.zip](https://d.pr/f/x1pyrs) From 56397965a580db44053f5492f10891090a792dce Mon Sep 17 00:00:00 2001 From: ManiruzzamanAkash Date: Wed, 16 Sep 2026 18:48:50 +0600 Subject: [PATCH 5/7] add official doc link in the readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ce3688a..6fc5773 100644 --- a/README.md +++ b/README.md @@ -152,3 +152,5 @@ $client->set_textdomain( 'your-project-textdomain' ); ## Example Theme [surecart-theme-license.zip](https://d.pr/f/x1pyrs) + +For full setup and functionality details, see the official documentation: [Licensing Setup and Functionality](https://surecart.com/docs/licensing-setup-and-functionality/). From 9ba73ad1d78a672d3d0370c1ad2994c85facac61 Mon Sep 17 00:00:00 2001 From: ManiruzzamanAkash Date: Wed, 16 Sep 2026 18:49:03 +0600 Subject: [PATCH 6/7] A read never writes to stored options --- src/Settings.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Settings.php b/src/Settings.php index 8bac9d9..2d6d04f 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -293,9 +293,10 @@ public function print_css() { /** * Get the activation. * - * A read never deletes the license key; only an explicit deactivate does. A 404 - * means the activation is gone, so drop just the activation id and let the user - * re-activate with the key pre-filled. Any other failure is transient: keep everything. + * A read never writes to stored options; it only surfaces an error message. + * On a 404 the stale activation_id is left in the database (it gets overwritten + * on reactivation), but this still returns false so the page shows "Activate + * License" instead of a "Deactivate License" button that would just keep failing. * * @return Object|false */ @@ -311,7 +312,6 @@ public function get_activation() { } if ( 'not_found' === $activation->get_error_code() ) { - $this->activation_id = null; $this->add_error( 'activation_removed', $this->client->__( 'The activation for this site was removed. Click Activate License to reconnect it.' ) ); return false; } From d92960cccdf465b12e2bdde8e86cfa2fdbd4ccf7 Mon Sep 17 00:00:00 2001 From: ManiruzzamanAkash Date: Wed, 16 Sep 2026 18:51:57 +0600 Subject: [PATCH 7/7] updated example plugins --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6fc5773..8404f73 100644 --- a/README.md +++ b/README.md @@ -148,9 +148,9 @@ $client->set_textdomain( 'your-project-textdomain' ); ``` ## Example Plugin -[surecart-plugin-license.zip](https://d.pr/f/VRK01i) +[surecart-plugin-license.zip](https://d.pr/f/6ZyfAS) ## Example Theme -[surecart-theme-license.zip](https://d.pr/f/x1pyrs) +[surecart-theme-license.zip](https://d.pr/f/RK8NFS) For full setup and functionality details, see the official documentation: [Licensing Setup and Functionality](https://surecart.com/docs/licensing-setup-and-functionality/).