Plugin Directory

Changeset 3484580


Ignore:
Timestamp:
03/17/2026 09:02:52 AM (11 days ago)
Author:
zeicaro
Message:

v2.0.2 — License client migrado de LemonSqueezy para self-hosted (wpraiz.com.br + Hotmart)

Location:
wpraiz-content-api-tool
Files:
4 edited
11 copied

Legend:

Unmodified
Added
Removed
  • wpraiz-content-api-tool/tags/2.0.2/includes/admin/class-license.php

    r3482396 r3484580  
    55
    66/**
    7  * License management via LemonSqueezy Licensing API.
     7 * License management via WPRaiz self-hosted license server.
    88 *
    9  * LemonSqueezy exposes public endpoints — no store API key needed in the plugin.
    10  * The plugin only holds the customer's license key.
     9 * The license server runs on wpraiz.com.br (class-license-server.php).
     10 * Flow:
     11 *   1. Buyer purchases on Hotmart
     12 *   2. Hotmart webhook → license server generates key → emails buyer
     13 *   3. Buyer enters key here → plugin calls wpraiz.com.br to activate
     14 *   4. Background re-validation daily
    1115 *
    12  * Endpoints used:
    13  *   POST https://api.lemonsqueezy.com/v1/licenses/activate
    14  *   POST https://api.lemonsqueezy.com/v1/licenses/validate
    15  *   POST https://api.lemonsqueezy.com/v1/licenses/deactivate
     16 * Endpoints (on WPRAIZ_LICENSE_SERVER_URL):
     17 *   POST /wpraiz/v2/license/activate
     18 *   POST /wpraiz/v2/license/validate
     19 *   POST /wpraiz/v2/license/deactivate
    1620 */
    1721class License {
    1822
    19     const LS_ACTIVATE   = 'https://api.lemonsqueezy.com/v1/licenses/activate';
    20     const LS_VALIDATE   = 'https://api.lemonsqueezy.com/v1/licenses/validate';
    21     const LS_DEACTIVATE = 'https://api.lemonsqueezy.com/v1/licenses/deactivate';
     23    /** License server base URL. Filterable via 'wpraiz_license_server_url'. */
     24    const DEFAULT_SERVER = 'https://wpraiz.com.br';
    2225
    2326    /** How often to re-validate remotely (seconds). Default: 24h. */
     
    3336            wp_schedule_event( time(), 'daily', 'wpraiz_revalidate_license' );
    3437        }
     38    }
     39
     40    /**
     41     * Get license server URL (filterable).
     42     */
     43    private static function server_url(): string {
     44        return apply_filters( 'wpraiz_license_server_url', self::DEFAULT_SERVER );
    3545    }
    3646
     
    6878        }
    6979
    70         $key         = get_option( 'wpraiz_license_key', '' );
    71         $instance_id = get_option( 'wpraiz_license_instance_id', '' );
     80        $key = get_option( 'wpraiz_license_key', '' );
    7281
    73         if ( $key && $instance_id ) {
    74             wp_remote_post( self::LS_DEACTIVATE, [
     82        if ( $key ) {
     83            wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/deactivate', [
    7584                'timeout' => 15,
    76                 'body'    => [
     85                'headers' => [ 'Content-Type' => 'application/json' ],
     86                'body'    => wp_json_encode( [
    7787                    'license_key' => $key,
    78                     'instance_id' => $instance_id,
    79                 ],
     88                    'site_url'    => get_site_url(),
     89                ] ),
    8090            ] );
    8191        }
     
    8393        delete_option( 'wpraiz_license_key' );
    8494        delete_option( 'wpraiz_license_status' );
    85         delete_option( 'wpraiz_license_instance_id' );
    8695        delete_option( 'wpraiz_license_activated_at' );
    8796        delete_option( 'wpraiz_license_expires_at' );
    8897        delete_option( 'wpraiz_license_last_check' );
     98
     99        // Cleanup legacy LemonSqueezy option
     100        delete_option( 'wpraiz_license_instance_id' );
    89101
    90102        wp_send_json_success( [ 'message' => 'License deactivated.' ] );
     
    94106
    95107    public function revalidate() {
    96         $key         = get_option( 'wpraiz_license_key', '' );
    97         $instance_id = get_option( 'wpraiz_license_instance_id', '' );
     108        $key = get_option( 'wpraiz_license_key', '' );
     109        if ( ! $key ) return;
    98110
    99         if ( ! $key || ! $instance_id ) return;
    100 
    101         $response = wp_remote_post( self::LS_VALIDATE, [
     111        $response = wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/validate', [
    102112            'timeout' => 15,
    103             'body'    => [
     113            'headers' => [ 'Content-Type' => 'application/json' ],
     114            'body'    => wp_json_encode( [
    104115                'license_key' => $key,
    105                 'instance_id' => $instance_id,
    106             ],
     116                'site_url'    => get_site_url(),
     117            ] ),
    107118        ] );
    108119
     
    111122        $body = json_decode( wp_remote_retrieve_body( $response ), true );
    112123
    113         $valid = ! empty( $body['activated'] ) || ( isset( $body['valid'] ) && $body['valid'] === true );
     124        $valid = isset( $body['valid'] ) && $body['valid'] === true;
    114125
    115126        update_option( 'wpraiz_license_status', $valid ? 'active' : 'invalid' );
    116127        update_option( 'wpraiz_license_last_check', time() );
     128
     129        if ( ! empty( $body['expires_at'] ) ) {
     130            update_option( 'wpraiz_license_expires_at', $body['expires_at'] );
     131        }
    117132    }
    118133
     
    126141
    127142    private function remote_activate( string $key ) {
    128         $response = wp_remote_post( self::LS_ACTIVATE, [
     143        $response = wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/activate', [
    129144            'timeout' => 15,
    130             'body'    => [
    131                 'license_key'   => $key,
    132                 'instance_name' => parse_url( get_site_url(), PHP_URL_HOST ),
    133             ],
     145            'headers' => [ 'Content-Type' => 'application/json' ],
     146            'body'    => wp_json_encode( [
     147                'license_key' => $key,
     148                'site_url'    => get_site_url(),
     149            ] ),
    134150        ] );
    135151
     
    141157        $body = json_decode( wp_remote_retrieve_body( $response ), true );
    142158
    143         // 200 or 201 = activated
    144         if ( in_array( $code, [ 200, 201 ], true ) && ! empty( $body['activated'] ) ) {
     159        if ( $code === 200 && ! empty( $body['activated'] ) ) {
    145160            update_option( 'wpraiz_license_key',          $key );
    146161            update_option( 'wpraiz_license_status',       'active' );
    147             update_option( 'wpraiz_license_instance_id',  $body['instance']['id'] ?? '' );
    148162            update_option( 'wpraiz_license_activated_at', time() );
    149             update_option( 'wpraiz_license_expires_at',   $body['license_key']['expires_at'] ?? '' );
     163            update_option( 'wpraiz_license_expires_at',   $body['expires_at'] ?? '' );
    150164            update_option( 'wpraiz_license_last_check',   time() );
     165
     166            // Cleanup legacy LemonSqueezy option
     167            delete_option( 'wpraiz_license_instance_id' );
    151168
    152169            return $body;
    153170        }
    154171
    155         // Already activated on this instance
    156         if ( $code === 400 && str_contains( $body['error'] ?? '', 'already' ) ) {
    157             update_option( 'wpraiz_license_key',    $key );
    158             update_option( 'wpraiz_license_status', 'active' );
    159             update_option( 'wpraiz_license_last_check', time() );
    160             return $body;
    161         }
    162 
    163         $msg = $body['message'] ?? $body['error'] ?? 'Invalid or expired license key.';
     172        $msg = $body['error'] ?? $body['message'] ?? 'Invalid or expired license key.';
    164173        return new \WP_Error( 'ls_invalid', $msg );
    165174    }
  • wpraiz-content-api-tool/tags/2.0.2/readme.txt

    r3484578 r3484580  
    55Tested up to: 6.7
    66Requires PHP: 7.4
    7 Stable tag: 2.0.1
     7Stable tag: 2.0.2
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    148148
    149149== Changelog ==
     150
     151= 2.0.2 =
     152* Fix: License client agora aponta para license server self-hosted (wpraiz.com.br/Hotmart) em vez de LemonSqueezy
     153* Cleanup: Removidas referências a api.lemonsqueezy.com
     154* Add: URL do license server filtrável via 'wpraiz_license_server_url'
    150155
    151156= 2.0.1 =
  • wpraiz-content-api-tool/tags/2.0.2/wpraiz-content.php

    r3484578 r3484580  
    44 * Plugin URI: https://wpraiz.com.br
    55 * Description: Create WordPress posts via REST API with SEO integration, AI content generation, and MCP server for AI agents.
    6  * Version: 2.0.1
     6 * Version: 2.0.2
    77 * Author: José Ícaro – WPRaiz
    88 * Author URI: https://wpraiz.com.br
     
    2121
    2222// Plugin constants
    23 define( 'WPRAIZ_VERSION', '2.0.1' );
     23define( 'WPRAIZ_VERSION', '2.0.2' );
    2424define( 'WPRAIZ_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
    2525define( 'WPRAIZ_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
  • wpraiz-content-api-tool/trunk/includes/admin/class-license.php

    r3482396 r3484580  
    55
    66/**
    7  * License management via LemonSqueezy Licensing API.
     7 * License management via WPRaiz self-hosted license server.
    88 *
    9  * LemonSqueezy exposes public endpoints — no store API key needed in the plugin.
    10  * The plugin only holds the customer's license key.
     9 * The license server runs on wpraiz.com.br (class-license-server.php).
     10 * Flow:
     11 *   1. Buyer purchases on Hotmart
     12 *   2. Hotmart webhook → license server generates key → emails buyer
     13 *   3. Buyer enters key here → plugin calls wpraiz.com.br to activate
     14 *   4. Background re-validation daily
    1115 *
    12  * Endpoints used:
    13  *   POST https://api.lemonsqueezy.com/v1/licenses/activate
    14  *   POST https://api.lemonsqueezy.com/v1/licenses/validate
    15  *   POST https://api.lemonsqueezy.com/v1/licenses/deactivate
     16 * Endpoints (on WPRAIZ_LICENSE_SERVER_URL):
     17 *   POST /wpraiz/v2/license/activate
     18 *   POST /wpraiz/v2/license/validate
     19 *   POST /wpraiz/v2/license/deactivate
    1620 */
    1721class License {
    1822
    19     const LS_ACTIVATE   = 'https://api.lemonsqueezy.com/v1/licenses/activate';
    20     const LS_VALIDATE   = 'https://api.lemonsqueezy.com/v1/licenses/validate';
    21     const LS_DEACTIVATE = 'https://api.lemonsqueezy.com/v1/licenses/deactivate';
     23    /** License server base URL. Filterable via 'wpraiz_license_server_url'. */
     24    const DEFAULT_SERVER = 'https://wpraiz.com.br';
    2225
    2326    /** How often to re-validate remotely (seconds). Default: 24h. */
     
    3336            wp_schedule_event( time(), 'daily', 'wpraiz_revalidate_license' );
    3437        }
     38    }
     39
     40    /**
     41     * Get license server URL (filterable).
     42     */
     43    private static function server_url(): string {
     44        return apply_filters( 'wpraiz_license_server_url', self::DEFAULT_SERVER );
    3545    }
    3646
     
    6878        }
    6979
    70         $key         = get_option( 'wpraiz_license_key', '' );
    71         $instance_id = get_option( 'wpraiz_license_instance_id', '' );
     80        $key = get_option( 'wpraiz_license_key', '' );
    7281
    73         if ( $key && $instance_id ) {
    74             wp_remote_post( self::LS_DEACTIVATE, [
     82        if ( $key ) {
     83            wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/deactivate', [
    7584                'timeout' => 15,
    76                 'body'    => [
     85                'headers' => [ 'Content-Type' => 'application/json' ],
     86                'body'    => wp_json_encode( [
    7787                    'license_key' => $key,
    78                     'instance_id' => $instance_id,
    79                 ],
     88                    'site_url'    => get_site_url(),
     89                ] ),
    8090            ] );
    8191        }
     
    8393        delete_option( 'wpraiz_license_key' );
    8494        delete_option( 'wpraiz_license_status' );
    85         delete_option( 'wpraiz_license_instance_id' );
    8695        delete_option( 'wpraiz_license_activated_at' );
    8796        delete_option( 'wpraiz_license_expires_at' );
    8897        delete_option( 'wpraiz_license_last_check' );
     98
     99        // Cleanup legacy LemonSqueezy option
     100        delete_option( 'wpraiz_license_instance_id' );
    89101
    90102        wp_send_json_success( [ 'message' => 'License deactivated.' ] );
     
    94106
    95107    public function revalidate() {
    96         $key         = get_option( 'wpraiz_license_key', '' );
    97         $instance_id = get_option( 'wpraiz_license_instance_id', '' );
     108        $key = get_option( 'wpraiz_license_key', '' );
     109        if ( ! $key ) return;
    98110
    99         if ( ! $key || ! $instance_id ) return;
    100 
    101         $response = wp_remote_post( self::LS_VALIDATE, [
     111        $response = wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/validate', [
    102112            'timeout' => 15,
    103             'body'    => [
     113            'headers' => [ 'Content-Type' => 'application/json' ],
     114            'body'    => wp_json_encode( [
    104115                'license_key' => $key,
    105                 'instance_id' => $instance_id,
    106             ],
     116                'site_url'    => get_site_url(),
     117            ] ),
    107118        ] );
    108119
     
    111122        $body = json_decode( wp_remote_retrieve_body( $response ), true );
    112123
    113         $valid = ! empty( $body['activated'] ) || ( isset( $body['valid'] ) && $body['valid'] === true );
     124        $valid = isset( $body['valid'] ) && $body['valid'] === true;
    114125
    115126        update_option( 'wpraiz_license_status', $valid ? 'active' : 'invalid' );
    116127        update_option( 'wpraiz_license_last_check', time() );
     128
     129        if ( ! empty( $body['expires_at'] ) ) {
     130            update_option( 'wpraiz_license_expires_at', $body['expires_at'] );
     131        }
    117132    }
    118133
     
    126141
    127142    private function remote_activate( string $key ) {
    128         $response = wp_remote_post( self::LS_ACTIVATE, [
     143        $response = wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/activate', [
    129144            'timeout' => 15,
    130             'body'    => [
    131                 'license_key'   => $key,
    132                 'instance_name' => parse_url( get_site_url(), PHP_URL_HOST ),
    133             ],
     145            'headers' => [ 'Content-Type' => 'application/json' ],
     146            'body'    => wp_json_encode( [
     147                'license_key' => $key,
     148                'site_url'    => get_site_url(),
     149            ] ),
    134150        ] );
    135151
     
    141157        $body = json_decode( wp_remote_retrieve_body( $response ), true );
    142158
    143         // 200 or 201 = activated
    144         if ( in_array( $code, [ 200, 201 ], true ) && ! empty( $body['activated'] ) ) {
     159        if ( $code === 200 && ! empty( $body['activated'] ) ) {
    145160            update_option( 'wpraiz_license_key',          $key );
    146161            update_option( 'wpraiz_license_status',       'active' );
    147             update_option( 'wpraiz_license_instance_id',  $body['instance']['id'] ?? '' );
    148162            update_option( 'wpraiz_license_activated_at', time() );
    149             update_option( 'wpraiz_license_expires_at',   $body['license_key']['expires_at'] ?? '' );
     163            update_option( 'wpraiz_license_expires_at',   $body['expires_at'] ?? '' );
    150164            update_option( 'wpraiz_license_last_check',   time() );
     165
     166            // Cleanup legacy LemonSqueezy option
     167            delete_option( 'wpraiz_license_instance_id' );
    151168
    152169            return $body;
    153170        }
    154171
    155         // Already activated on this instance
    156         if ( $code === 400 && str_contains( $body['error'] ?? '', 'already' ) ) {
    157             update_option( 'wpraiz_license_key',    $key );
    158             update_option( 'wpraiz_license_status', 'active' );
    159             update_option( 'wpraiz_license_last_check', time() );
    160             return $body;
    161         }
    162 
    163         $msg = $body['message'] ?? $body['error'] ?? 'Invalid or expired license key.';
     172        $msg = $body['error'] ?? $body['message'] ?? 'Invalid or expired license key.';
    164173        return new \WP_Error( 'ls_invalid', $msg );
    165174    }
  • wpraiz-content-api-tool/trunk/readme.txt

    r3484578 r3484580  
    55Tested up to: 6.7
    66Requires PHP: 7.4
    7 Stable tag: 2.0.1
     7Stable tag: 2.0.2
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    148148
    149149== Changelog ==
     150
     151= 2.0.2 =
     152* Fix: License client agora aponta para license server self-hosted (wpraiz.com.br/Hotmart) em vez de LemonSqueezy
     153* Cleanup: Removidas referências a api.lemonsqueezy.com
     154* Add: URL do license server filtrável via 'wpraiz_license_server_url'
    150155
    151156= 2.0.1 =
  • wpraiz-content-api-tool/trunk/wpraiz-content.php

    r3484578 r3484580  
    44 * Plugin URI: https://wpraiz.com.br
    55 * Description: Create WordPress posts via REST API with SEO integration, AI content generation, and MCP server for AI agents.
    6  * Version: 2.0.1
     6 * Version: 2.0.2
    77 * Author: José Ícaro – WPRaiz
    88 * Author URI: https://wpraiz.com.br
     
    2121
    2222// Plugin constants
    23 define( 'WPRAIZ_VERSION', '2.0.1' );
     23define( 'WPRAIZ_VERSION', '2.0.2' );
    2424define( 'WPRAIZ_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
    2525define( 'WPRAIZ_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
Note: See TracChangeset for help on using the changeset viewer.