Wtyczka WooCommerce

Wersja v1.0.0 · pełny, otwarty kod źródłowy poniżej.

Instalacja

  1. W WordPressie: Wtyczki → Dodaj nową → Wyślij wtyczkę, wybierz pobrany ZIP i kliknij Włącz.
  2. Ustawienia → Legalni w Sieci: wklej klucz i sekret API z panelu sklepu, ustaw liczbę dni i kliknij Testuj połączenie.
  3. Zamówienia o statusie Zrealizowane wysyłają się automatycznie (ponowienia przez WP-Cron, zgodność z HPOS).
  4. Widżet gwiazdek: shortcode [legalniwsieci_widget] w treści strony, stopce lub bloku „Shortcode”.
  5. Dodaj w polityce prywatności sklepu informację o przekazywaniu danych zamówienia do Legalni w Sieci.

Pliki

legalniwsieci-reviews/index.php (0,0 KB)

<?php
// Silence is golden.
exit;

legalniwsieci-reviews/legalniwsieci-reviews.php (8,2 KB)

<?php
/**
 * Plugin Name:       Legalni w Sieci — zweryfikowane opinie
 * Plugin URI:        https://legalniwsieci.pl/integracje/woocommerce
 * Description:       Wysyła zrealizowane zamówienia WooCommerce do Legalni w Sieci (API z podpisem HMAC), aby klienci otrzymali jednorazowy link do zweryfikowanej opinii. Widżet gwiazdek: shortcode [legalniwsieci_widget].
 * Version:           1.0.0
 * Requires at least: 6.0
 * Requires PHP:      7.4
 * Author:            Legalni w Sieci
 * Author URI:        https://legalniwsieci.pl
 * License:           GPL-2.0-or-later
 * Text Domain:       legalniwsieci-reviews
 * WC requires at least: 7.0
 */
if (!defined('ABSPATH')) { exit; }

final class LWS_Reviews {
    const VERSION = '1.0.0';
    const OPT = 'lws_reviews_settings';
    const API = 'https://legalniwsieci.pl/api/v1/';

    public static function init() {
        add_action('admin_menu', array(__CLASS__, 'menu'));
        add_action('admin_init', array(__CLASS__, 'register_settings'));
        add_action('woocommerce_order_status_completed', array(__CLASS__, 'on_completed'), 10, 1);
        add_action('lws_reviews_retry', array(__CLASS__, 'send_order'), 10, 1);
        add_shortcode('legalniwsieci_widget', array(__CLASS__, 'shortcode'));
        add_filter('plugin_action_links_' . plugin_basename(__FILE__), function ($l) { array_unshift($l, '<a href="' . esc_url(admin_url('options-general.php?page=lws-reviews')) . '">' . esc_html__('Ustawienia', 'legalniwsieci-reviews') . '</a>'); return $l; });
        add_action('before_woocommerce_init', function () { if (class_exists('\Automattic\WooCommerce\Utilities\FeaturesUtil')) { \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true); } });
    }

    public static function opt($k, $d = '') { $o = get_option(self::OPT, array()); return isset($o[$k]) && $o[$k] !== '' ? $o[$k] : $d; }

    public static function menu() {
        add_options_page('Legalni w Sieci', 'Legalni w Sieci', 'manage_woocommerce', 'lws-reviews', array(__CLASS__, 'page'));
    }

    public static function register_settings() {
        register_setting('lws_reviews', self::OPT, array('sanitize_callback' => function ($in) {
            $old = get_option(LWS_Reviews::OPT, array());
            return array(
                'api_key'    => sanitize_text_field(isset($in['api_key']) ? $in['api_key'] : ''),
                'api_secret' => !empty($in['api_secret']) ? sanitize_text_field($in['api_secret']) : (isset($old['api_secret']) ? $old['api_secret'] : ''),
                'delay_days' => max(0, min(60, (int) (isset($in['delay_days']) ? $in['delay_days'] : 7))),
                'send_phone' => empty($in['send_phone']) ? '' : '1',
                'send_name'  => empty($in['send_name']) ? '' : '1',
            );
        }));
    }

    public static function page() {
        if (!current_user_can('manage_woocommerce')) { return; }
        $test = '';
        if (isset($_POST['lws_test']) && check_admin_referer('lws_test')) {
            $r = self::request('ping', '');
            $test = is_wp_error($r) ? $r->get_error_message() : (wp_remote_retrieve_response_code($r) === 200 ? 'OK — połączenie i podpis poprawne.' : 'Błąd ' . wp_remote_retrieve_response_code($r) . ': ' . wp_remote_retrieve_body($r));
        }
        ?>
        <div class="wrap"><h1>Legalni w Sieci — zweryfikowane opinie <small>v<?php echo esc_html(self::VERSION); ?></small></h1>
        <p>Klucz i sekret API znajdziesz w <a href="https://legalniwsieci.pl/panel" target="_blank" rel="noopener">panelu sklepu</a>. Zamówienia o statusie <strong>Zrealizowane</strong> są wysyłane automatycznie.</p>
        <?php if ($test) { echo '<div class="notice notice-info"><p>' . esc_html($test) . '</p></div>'; } ?>
        <form method="post" action="options.php"><?php settings_fields('lws_reviews'); ?>
        <table class="form-table" role="presentation">
        <tr><th scope="row"><label for="lws_key">Klucz API</label></th><td><input id="lws_key" class="regular-text" name="<?php echo esc_attr(self::OPT); ?>[api_key]" value="<?php echo esc_attr(self::opt('api_key')); ?>" placeholder="lws_pk_..."></td></tr>
        <tr><th scope="row"><label for="lws_secret">Sekret API</label></th><td><input id="lws_secret" type="password" class="regular-text" name="<?php echo esc_attr(self::OPT); ?>[api_secret]" value="" placeholder="<?php echo self::opt('api_secret') ? '•••••••• (zapisany — wpisz, aby zmienić)' : 'lws_sk_...'; ?>" autocomplete="new-password"></td></tr>
        <tr><th scope="row"><label for="lws_days">Wyślij prośbę po (dniach)</label></th><td><input id="lws_days" type="number" min="0" max="60" name="<?php echo esc_attr(self::OPT); ?>[delay_days]" value="<?php echo esc_attr(self::opt('delay_days', 7)); ?>"></td></tr>
        <tr><th scope="row">Dane</th><td><label><input type="checkbox" name="<?php echo esc_attr(self::OPT); ?>[send_phone]" value="1" <?php checked(self::opt('send_phone'), '1'); ?>> Przekazuj telefon (gdy brak e-maila)</label><br><label><input type="checkbox" name="<?php echo esc_attr(self::OPT); ?>[send_name]" value="1" <?php checked(self::opt('send_name'), '1'); ?>> Przekazuj imię klienta (zwrot w e-mailu)</label>
        <p class="description">Pamiętaj o informacji w polityce prywatności sklepu, że przekazujesz dane zamówienia do Legalni w Sieci w celu zebrania opinii.</p></td></tr>
        </table><?php submit_button(); ?></form>
        <form method="post"><?php wp_nonce_field('lws_test'); ?><p><button class="button" name="lws_test" value="1">Testuj połączenie</button></p></form>
        <h2>Widżet</h2><p>Wstaw shortcode <code>[legalniwsieci_widget]</code> w stronie, stopce lub widżecie tekstowym.</p></div>
        <?php
    }

    /** Podpis: hex(HMAC-SHA256(secret, timestamp + "." + body)) */
    public static function request($endpoint, $body) {
        $key = self::opt('api_key'); $secret = self::opt('api_secret');
        if (!$key || !$secret) { return new WP_Error('lws_config', 'Uzupełnij klucz i sekret API.'); }
        $ts = (string) time();
        return wp_remote_request(self::API . $endpoint, array(
            'method'  => $body === '' ? 'GET' : 'POST',
            'timeout' => 15,
            'headers' => array('Content-Type' => 'application/json', 'X-LWS-Key' => $key, 'X-LWS-Timestamp' => $ts, 'X-LWS-Signature' => hash_hmac('sha256', $ts . '.' . $body, $secret), 'User-Agent' => 'lws-woocommerce/' . self::VERSION),
            'body'    => $body === '' ? null : $body,
        ));
    }

    public static function on_completed($order_id) { self::send_order($order_id); }

    public static function send_order($order_id) {
        $order = wc_get_order($order_id);
        if (!$order || $order->get_meta('_lws_sent')) { return; }
        $payload = array('order_id' => (string) $order->get_order_number(), 'email' => (string) $order->get_billing_email(), 'delay_days' => (int) self::opt('delay_days', 7));
        if (self::opt('send_phone') && !$payload['email']) { $payload['phone'] = (string) $order->get_billing_phone(); }
        if (self::opt('send_name')) { $payload['customer_name'] = (string) $order->get_billing_first_name(); }
        $r = self::request('orders', wp_json_encode($payload));
        $code = is_wp_error($r) ? 0 : (int) wp_remote_retrieve_response_code($r);
        if ($code === 200 || $code === 201) {
            $order->update_meta_data('_lws_sent', time()); $order->save();
            $order->add_order_note('Legalni w Sieci: zaplanowano prośbę o opinię.');
        } else {
            $tries = (int) $order->get_meta('_lws_tries') + 1; $order->update_meta_data('_lws_tries', $tries); $order->save();
            if ($tries < 5 && $code !== 401 && $code !== 422) { wp_schedule_single_event(time() + 3600 * $tries, 'lws_reviews_retry', array($order_id)); }
            $order->add_order_note('Legalni w Sieci: błąd wysyłki (' . ($code ?: (is_wp_error($r) ? $r->get_error_message() : '?')) . ').');
        }
    }

    public static function shortcode($atts) {
        $key = self::opt('api_key'); if (!$key) { return ''; }
        wp_enqueue_script('lws-widget', 'https://legalniwsieci.pl/widget.js', array(), self::VERSION, true);
        return '<div class="lws-widget" data-lws-key="' . esc_attr($key) . '"></div>';
    }
}
LWS_Reviews::init();

legalniwsieci-reviews/readme.txt (1,0 KB)

=== Legalni w Sieci — zweryfikowane opinie ===
Tags: opinie, reviews, woocommerce, zaufanie
Requires at least: 6.0
Tested up to: 6.6
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later

Zbieraj zweryfikowane opinie klientów WooCommerce przez Legalni w Sieci.

== Opis ==
* Po zmianie statusu zamówienia na "Zrealizowane" wtyczka wysyła numer zamówienia i e-mail klienta do API Legalni w Sieci (podpis HMAC-SHA256).
* Po ustalonej liczbie dni klient dostaje jednorazowy link — ocenia sklep jednym kliknięciem gwiazdki.
* Shortcode [legalniwsieci_widget] wyświetla widżet z oceną.
* Ponawianie wysyłki (do 5 prób) przez WP-Cron; zgodność z HPOS.

== Instalacja ==
1. Wtyczki → Dodaj nową → Wyślij wtyczkę → wybierz ZIP → Włącz.
2. Ustawienia → Legalni w Sieci: wklej klucz i sekret z https://legalniwsieci.pl/panel, kliknij "Testuj połączenie".
3. Dodaj w polityce prywatności sklepu informację o przekazywaniu danych zamówienia do Legalni w Sieci w celu zebrania opinii.

== Changelog ==
= 1.0.0 =
* Pierwsze wydanie.

legalniwsieci-reviews/uninstall.php (0,1 KB)

<?php
if (!defined('WP_UNINSTALL_PLUGIN')) { exit; }
delete_option('lws_reviews_settings');