-
Notifications
You must be signed in to change notification settings - Fork 1
Implement Woo Payment Gateway #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…esult text placement
…y logic from Sticky Header and missing webhook parm, misc gateway text update
📝 WalkthroughWalkthroughAdds a WooCommerce gateway and Blocks integration, centralizes transaction/signature logic in a new service class, implements order-status polling with a verification overlay, refactors address validation to multi-target feedback, and introduces a sitewide sticky-header toggle with body-class control. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Browser as Customer (Browser)
participant WC as WooCommerce (Order page)
participant PayButtonJS as PayButton JS (paybutton-woo.js)
participant AJAX as WP AJAX (paybutton_check_order_status)
participant OrderDB as WooCommerce Order DB
Browser->>WC: Load order-received (renders PayButton container with data-config)
WC->>PayButtonJS: Initialize PayButton.render(config)
PayButtonJS->>Browser: Show payment UI
Browser->>PayButtonJS: Complete payment (onSuccess)
PayButtonJS->>AJAX: Start polling with order_id
loop every 3s
AJAX->>OrderDB: Query order status by ID
OrderDB-->>AJAX: Return status
alt status is paid/processing/completed
AJAX-->>PayButtonJS: Respond success -> instruct reload
else
AJAX-->>PayButtonJS: Respond still pending
end
end
Browser->>WC: Reload -> show receipt (payment confirmed)
sequenceDiagram
autonumber
participant Blocks as Woo Blocks UI
participant Registry as Payment Method Registry
participant Support as WC_PayButton_Blocks_Support
participant Gateway as WC_Gateway_PayButton
Blocks->>Registry: Request payment method registration
Registry->>Support: Register support class
Support->>Gateway: Query active gateway & settings
Gateway-->>Support: Return title, icons, description, supports
Support-->>Registry: Provide payment method data
Registry-->>Blocks: Render PayButton option in checkout UI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (7)
assets/js/addressValidator.bundle.js (1)
754-843: Consider defensive programming improvements for the multi-target validation logic.The validation logic is well-structured but could benefit from a few robustness improvements:
Line 777: After checking
if (!addressInput), the function returns early, which is good. However, consider logging or tracking which targets failed to initialize for debugging purposes.Line 804: The
querySelectorfor the save button could fail silently. Consider handling the case where the button doesn't exist more explicitly.Line 814 & 822: Using
'0px'and'3px'as string values formarginBottomis valid but inconsistent. Consider using numeric values or a consistent format.Line 817-818: When the input is empty, the save button is disabled. Verify this is the intended behavior for the WooCommerce settings page where administrators might want to clear an address.
🔎 Suggested improvements
targets.forEach(target => { const addressInput = document.getElementById(target.input); - if (!addressInput) return; + if (!addressInput) { + console.warn(`PayButton: Address input "${target.input}" not found for context "${target.context}"`); + return; + } // Create a unique span ID for this input const resultSpanId = target.input + '_validation_result'; // Find or create a span for validation feedback. let resultSpan = document.getElementById(resultSpanId); if (!resultSpan) { resultSpan = document.createElement('span'); resultSpan.id = resultSpanId; // STYLING UPDATES resultSpan.style.display = 'block'; resultSpan.style.fontWeight = 'bold'; - // Add spacing below the text so it doesn't touch the input - resultSpan.style.marginBottom = '5px'; + resultSpan.style.marginBottom = '5px'; // PLACEMENT FIX (ABOVE INPUT BOX) - // This inserts the resultSpan immediately BEFORE the addressInput element. - // On the Generator page, this will place it between the Label and the Input. addressInput.parentNode.insertBefore(resultSpan, addressInput); } // Select the "Save Changes" button if applicable let saveButton = null; if (target.btnName) { saveButton = document.querySelector(`button[name="${target.btnName}"]`); + if (!saveButton) { + console.warn(`PayButton: Save button "${target.btnName}" not found for context "${target.context}"`); + } }includes/class-paybutton-public.php (1)
384-389: Consider adding file existence check for template loading.The
output_paybutton_overlaymethod loads the template without verifying it exists first. While theload_public_templatemethod will fail if the file is missing, adding an explicit check would provide better error handling and debugging information.🔎 Suggested improvement
public function output_paybutton_overlay() { + $template_path = PAYBUTTON_PLUGIN_DIR . 'templates/public/paybutton-overlay.php'; + if ( ! file_exists( $template_path ) ) { + error_log( 'PayButton: Overlay template not found at ' . $template_path ); + return; + } $this->load_public_template( 'paybutton-overlay' ); }assets/js/paybutton-blocks.js (1)
1-76: Consider adding safety checks and extracting inline styles.The WooCommerce Blocks integration is well-structured, but could benefit from a few improvements:
Missing global checks: The IIFE assumes
window.wcandwindow.wpexist. If these scripts fail to load, this will cause a runtime error.Line 36-44: The pipe separator styling is defined inline. Consider extracting these styles to a CSS class for maintainability.
Line 70:
canMakePayment: () => truealways returns true without any validation. Consider adding checks for required settings (e.g., gateway enabled, address configured).Lines 26-33 & 47-54: Image styling is duplicated. Consider extracting to a shared style object or CSS class.
🔎 Suggested improvements
+(function( wc, wp ) { + 'use strict'; + + // Safety check for required globals + if ( typeof wc === 'undefined' || typeof wp === 'undefined' ) { + console.error( 'PayButton Blocks: Required dependencies (wc, wp) not loaded' ); + return; + } + const { registerPaymentMethod } = wc.wcBlocksRegistry; const { getSetting } = wc.wcSettings; const { decodeEntities } = wp.htmlEntities; const { createElement } = wp.element; const settings = getSetting( 'paybutton_data', {} ); const labelText = decodeEntities( settings.title || 'PayButton' ); + + // Shared image styles + const imageStyle = { maxHeight: '30px', objectFit: 'contain' }; // Create a Custom Label Component (Dual Icons) const LabelIconOnly = () => { return createElement( 'span', { style: { display: 'flex', alignItems: 'center', width: '100%', } }, // 1. The PayButton Image settings.icon ? createElement( 'img', { src: settings.icon, alt: labelText, - style: { - maxHeight: '30px', - objectFit: 'contain' - } + style: imageStyle } ) : null, - // 2. The Pipeline Separator (Only shows if BOTH icons exist) - (settings.icon && settings.icon2) ? createElement( 'span', { - style: { - margin: '0 10px', // Spacing around the pipe - color: '#ccc', // Light gray color - fontSize: '24px', // Size of the pipe - lineHeight: '1', - fontWeight: '300' - } - }, '|' ) : null, + // 2. Separator (use CSS class instead) + (settings.icon && settings.icon2) ? createElement( 'span', { + className: 'paybutton-blocks-separator' + }, '|' ) : null, // 3. The eCash Image settings.icon2 ? createElement( 'img', { src: settings.icon2, alt: 'eCash', - style: { - maxHeight: '24px', - objectFit: 'contain' - } + style: { maxHeight: '24px', objectFit: 'contain' } } ) : null, // 4. Fallback: If no icons are found, show text (!settings.icon && !settings.icon2) ? createElement( 'span', null, labelText ) : null ); }; const Content = () => { return createElement( 'div', null, decodeEntities( settings.description || '' ) ); }; registerPaymentMethod( { name: 'paybutton', label: createElement( LabelIconOnly ), content: createElement( Content ), edit: createElement( Content ), - canMakePayment: () => true, + canMakePayment: () => { + // Add validation if needed + return true; + }, ariaLabel: labelText, supports: { features: settings.supports, }, } ); })( window.wc, window.wp );includes/woocommerce/class-wc-gateway-paybutton.php (1)
176-189: Consider adding JSON encoding flags for security.When encoding the config for the data attribute, consider using
JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOTflags to prevent potential XSS through specially crafted attribute values.🔎 Proposed fix
- echo '<div class="paybutton-woo-container" data-config="' . esc_attr( json_encode( $config ) ) . '" style="margin: 20px 0;"></div>'; + echo '<div class="paybutton-woo-container" data-config="' . esc_attr( wp_json_encode( $config ) ) . '" style="margin: 20px 0;"></div>';Using
wp_json_encode()is preferred in WordPress as it handles encoding errors gracefully and applies appropriate flags.includes/woocommerce/class-paybutton-blocks-support.php (1)
36-46: Consider using dynamic versioning for cache busting.The script version is hardcoded as
'1.0.0'. Consider using the plugin version constant orfilemtime()for better cache invalidation during development and updates.🔎 Proposed fix
wp_register_script( 'wc-paybutton-blocks', PAYBUTTON_PLUGIN_URL . 'assets/js/paybutton-blocks.js', array( 'wc-blocks-registry', 'wc-settings', 'wp-element', 'wp-html-entities' ), - '1.0.0', + filemtime( PAYBUTTON_PLUGIN_DIR . 'assets/js/paybutton-blocks.js' ), true );includes/class-paybutton-ajax.php (2)
357-361: Unused variables$tx_amountand$tx_timestamp- consider removing or using.As flagged by static analysis, these variables are retrieved from POST but never used in
mark_payment_successful(). If they're not needed for this flow, remove them to avoid confusion.🔎 Proposed fix - if not needed
$post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0; $tx_hash = isset( $_POST['tx_hash'] ) ? sanitize_text_field( $_POST['tx_hash'] ) : ''; - $tx_amount = isset( $_POST['tx_amount'] ) ? (float) $_POST['tx_amount'] : 0.0; - $tx_timestamp = isset( $_POST['tx_timestamp'] ) ? sanitize_text_field( $_POST['tx_timestamp'] ) : ''; // NEW: Address passed from front-end if user is not logged in $user_address = isset( $_POST['user_address'] ) ? sanitize_text_field( $_POST['user_address'] ) : '';
626-644: Redundancy confirmed—simplify to justis_paid().The
is_paid()method already returnstruefor bothprocessingandcompletedstatuses (its default behavior viawc_get_is_paid_statuses()). The explicit status checks are indeed redundant.Simplify to:
if ( $order && $order->is_paid() ) { wp_send_json_success(); }Note: Behavior is controlled by the filterable
woocommerce_order_is_paid_statusesfilter, so verify this matches your expected order statuses if custom filters are in use.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
assets/icons/eCash.pngis excluded by!**/*.png
📒 Files selected for processing (14)
assets/css/sticky-header.cssassets/js/addressValidator.bundle.jsassets/js/paybutton-blocks.jsassets/js/paybutton-generator.jsassets/js/paybutton-woo.jsincludes/class-paybutton-admin.phpincludes/class-paybutton-ajax.phpincludes/class-paybutton-public.phpincludes/class-paybutton-transactions.phpincludes/woocommerce/class-paybutton-blocks-support.phpincludes/woocommerce/class-wc-gateway-paybutton.phppaybutton.phptemplates/admin/paywall-settings.phptemplates/public/paybutton-overlay.php
💤 Files with no reviewable changes (1)
- assets/js/paybutton-generator.js
🧰 Additional context used
🧬 Code graph analysis (4)
includes/woocommerce/class-paybutton-blocks-support.php (1)
includes/woocommerce/class-wc-gateway-paybutton.php (1)
is_available(195-201)
includes/woocommerce/class-wc-gateway-paybutton.php (3)
includes/class-paybutton-admin.php (1)
__construct(14-26)includes/class-paybutton-ajax.php (1)
__construct(29-61)includes/class-paybutton-public.php (1)
__construct(26-38)
paybutton.php (1)
includes/woocommerce/class-paybutton-blocks-support.php (1)
WC_PayButton_Blocks_Support(12-64)
includes/class-paybutton-ajax.php (1)
includes/class-paybutton-transactions.php (6)
verify_signature(19-52)record_login_tx_if_new(212-245)get_paywall_requirements(255-300)validate_price_and_unit(144-162)insert_unlock_if_new(168-205)consume_row_and_attach_token(64-137)
🪛 PHPMD (2.15.0)
includes/class-paybutton-ajax.php
357-357: Avoid unused local variables such as '$tx_amount'. (undefined)
(UnusedLocalVariable)
358-358: Avoid unused local variables such as '$tx_timestamp'. (undefined)
(UnusedLocalVariable)
🔇 Additional comments (32)
assets/css/sticky-header.css (1)
120-122: LGTM! Proper scoping of sticky header padding.Excellent change to scope the padding-top to only when the
pb-has-sticky-headerclass is present. This provides better control over the sticky header behavior and prevents unintended layout shifts when the header is disabled.templates/admin/paywall-settings.php (2)
140-157: LGTM! Properly implemented sticky header toggle.The new sticky header disable checkbox is well-implemented:
- Proper use of
esc_html_e()for translation and escaping- Correct use of
checked()helper with default value- Clear user-facing description
- Consistent with existing settings patterns
278-278: Documentation update looks good.The addition of the
"value": <value>line to the sample JSON payload improves the documentation clarity.includes/class-paybutton-public.php (2)
168-170: LGTM! Clean early return for disabled sticky header.The early return pattern when
paybutton_hide_sticky_headeris enabled is clean and prevents unnecessary processing.
390-398: LGTM! Proper body class filtering logic.The
filter_body_classesmethod correctly adds thepb-has-sticky-headerclass conditionally based on the option value, which aligns with the CSS changes insticky-header.css.includes/class-paybutton-admin.php (2)
88-88: LGTM! Security improvement with wp_safe_redirect.Excellent change from
wp_redirecttowp_safe_redirect. This prevents potential open redirect vulnerabilities by validating the redirect URL against the allowed hosts list.
347-350: LGTM! Proper option persistence.The new
paybutton_hide_sticky_headeroption is saved correctly using the checkbox pattern (isset check converts to '1' or '0').assets/js/paybutton-woo.js (2)
9-12: LGTM! Safe JSON parsing with error handling.The defensive JSON parsing with try-catch and early return is appropriate for handling potentially malformed configuration data.
50-54: Verify user experience during payment verification.When the PayButton modal closes after payment initiation, the overlay displays "Verifying Payment...". Consider the following UX improvements:
- What happens if the user navigates away or closes the tab during verification?
- Should there be a "Cancel" or "Check Status Later" option?
- Consider adding a timeout message or manual refresh option if polling takes too long.
templates/public/paybutton-overlay.php (1)
1-13: All CSS classes are properly defined and the spinner animation is complete.The classes
paybutton_overlay,paybutton_overlay_inner,paybutton_overlay_content, andpaybutton_overlay_spinnerare fully defined inassets/css/paywall-styles.csswith complete styling and animations. The.paybutton_overlay_spinnerincludes a proper animated border-based spinner with thepaybutton_spinkeyframe animation (rotating 360 degrees infinitely).The inline
style="display:none;"is intentionally placed in the template for initial state visibility, with JavaScript toggling the display property when needed. This is a valid approach and does not require changes.paybutton.php (5)
27-33: LGTM - HPOS compatibility properly declared.The High-Performance Order Storage (HPOS) compatibility declaration is correctly implemented with the
class_existsguard to prevent errors when WooCommerce is not installed.
44-48: LGTM - Conditional gateway file loading.Proper guard with
file_exists()before requiring the WooCommerce gateway file, ensuring graceful behavior when the file is missing.
79-87: LGTM - Gateway registration with class guard.The gateway registration correctly checks
class_exists('WC_Gateway_PayButton')before adding to the gateways array, preventing fatal errors when WooCommerce is not active.
89-107: LGTM - Blocks support registration with proper guards.The implementation correctly:
- Hooks into
woocommerce_blocks_payment_method_type_registration- Checks for
AbstractPaymentMethodTypeclass existence- Verifies the block support file exists before requiring
- Checks
WC_PayButton_Blocks_Supportclass exists before instantiation
114-114: Good security improvement usingwp_safe_redirect.Using
wp_safe_redirect()instead ofwp_redirect()ensures the redirect URL is validated against the allowed hosts list, preventing potential open redirect vulnerabilities.includes/woocommerce/class-wc-gateway-paybutton.php (3)
9-15: LGTM - Safe gateway initialization pattern.Hooking into
plugins_loadedand checkingclass_exists('WC_Payment_Gateway')before defining the class is the correct approach to ensure WooCommerce is fully loaded.
80-107: LGTM - Secure admin options processing.Good implementation with:
- Proper WooCommerce settings nonce verification
- Sanitization of posted address
- Preventing gateway enablement without a wallet address configured
206-232: LGTM - Admin panel rendering with proper escaping.Good use of
esc_html(),esc_attr(), andesc_html__()for output escaping. The transaction hash is properly escaped when building the explorer URL.includes/woocommerce/class-paybutton-blocks-support.php (3)
12-17: LGTM - Blocks support class structure.The class correctly extends
AbstractPaymentMethodTypewith a matching$nameproperty. The emptyinitialize()method is acceptable as no initialization is required.
23-31: LGTM - Delegated availability check.Correctly delegates the active state check to the gateway's
is_available()method, ensuring consistency between classic and blocks checkout.
51-63: LGTM - Payment method data for blocks checkout.Correctly provides fallback values when gateway is unavailable and includes both primary and secondary icon paths for the checkout UI.
includes/class-paybutton-transactions.php (6)
19-52: LGTM - Ed25519 signature verification.The implementation correctly:
- Validates inputs are non-empty
- Handles DER-wrapped public keys (44 bytes → 32 bytes)
- Converts payload encoding for consistent verification
- Uses
sodium_crypto_sign_verify_detached()for verification
59-62: LGTM - Secure token generation.Uses
random_bytes()with base64url encoding, providing cryptographically secure tokens suitable for replay protection.
144-162: LGTM - Price validation with epsilon tolerance.The implementation correctly handles floating-point comparison with a reasonable epsilon of 0.05 and performs case-insensitive unit comparison.
168-205: LGTM - Idempotent unlock insertion.Properly checks for existing transaction by
tx_hashbefore inserting, preventing duplicate records.
212-245: LGTM - Idempotent login transaction recording.Correctly prevents duplicate login records by checking both
wallet_addressandtx_hash.
255-300: LGTM - Paywall requirements parsing with fallbacks.Good implementation that:
- Parses the first
[paywalled_content]shortcode- Extracts price and unit attributes
- Falls back to plugin options when attributes are missing
- Properly sanitizes and normalizes values
includes/class-paybutton-ajax.php (5)
57-60: LGTM - Order status polling endpoint registration.Correctly registers both privileged and non-privileged AJAX actions for order status polling, consistent with the plugin's authentication model.
127-131: LGTM - Centralized signature verification.Good refactor to use
PayButton_Transactions::verify_signature()for consistent cryptographic verification across the plugin.
139-157: LGTM - Payload binding validation.Good security hardening by verifying that the OP_RETURN value and transaction hash are cryptographically bound to the signed payload, preventing payload manipulation attacks.
191-228: LGTM - WooCommerce payment processing branch.Solid implementation with:
- Idempotency check via
is_paid()- Fiat value validation with epsilon tolerance
- Informative order notes for underpayment and successful payment
- Proper meta data storage for transaction details
602-604: LGTM - Early return for hidden sticky header.Good UX consideration to return empty HTML immediately when the sticky header is configured to be hidden, avoiding unnecessary template processing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
includes/class-paybutton-admin.php (1)
119-129: Hardcoded WooCommerce screen ID may break on translated installations.The concern about
'woocommerce_page_wc-settings'potentially breaking on translated WordPress installations was already raised in a previous review. The recommended fix is to usesanitize_title( __( 'WooCommerce', 'woocommerce' ) ) . '_page_wc-settings'for the comparison.includes/woocommerce/class-wc-gateway-paybutton.php (1)
112-123: Previous concern addressed - now usingwc_reduce_stock_levels().The deprecated
$order->reduce_order_stock()has been correctly replaced withwc_reduce_stock_levels($order_id).
🧹 Nitpick comments (1)
includes/woocommerce/class-wc-gateway-paybutton.php (1)
188-189: Preferwp_json_encode()overjson_encode()for WordPress consistency.
wp_json_encode()handles encoding errors gracefully and is the WordPress-recommended approach.🔎 Proposed fix
echo '<h2>Complete your payment</h2>'; - echo '<div class="paybutton-woo-container" data-config="' . esc_attr( json_encode( $config ) ) . '" style="margin: 20px 0;"></div>'; + echo '<div class="paybutton-woo-container" data-config="' . esc_attr( wp_json_encode( $config ) ) . '" style="margin: 20px 0;"></div>';
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
includes/class-paybutton-admin.phpincludes/class-paybutton-transactions.phpincludes/woocommerce/class-wc-gateway-paybutton.php
🔇 Additional comments (16)
includes/class-paybutton-admin.php (4)
88-88: Good security improvement usingwp_safe_redirect.This is the correct function to use for admin redirects as it validates the destination against the allowed hosts list, preventing open redirect vulnerabilities.
131-143: LGTM!The refactor to use
$screen->idfor page detection is more reliable and consistent with the approach used for other pages.
145-145: LGTM!Consistent use of screen ID-based detection for the generator page.
343-347: LGTM!The new option follows the established pattern for persisting checkbox values in this file.
includes/class-paybutton-transactions.php (5)
59-62: LGTM!Secure token generation using
random_bytes()with base64url encoding is appropriate for this use case.
82-94: Column whitelist now correctly includes all required columns.The previous concern about missing
pb_paywall_user_wallet_addressandpost_idcolumns has been addressed.
151-169: LGTM!The tolerance-based price validation allowing overpayment and case-insensitive unit comparison is appropriate for cryptocurrency payment flows.
219-252: LGTM!Implementation correctly records login transactions with duplicate checking. Same TOCTOU consideration applies as noted for
insert_unlock_if_new.
262-307: LGTM!Clean implementation using
shortcode_parse_atts()for parsing and proper fallback to plugin options.includes/woocommerce/class-wc-gateway-paybutton.php (7)
17-42: LGTM!Standard WooCommerce gateway initialization with appropriate hooks for admin options, thank-you page, scripts, and admin panel rendering.
47-75: LGTM!Form fields are properly defined with appropriate types, defaults, and descriptions.
80-107: LGTM!Good defensive validation preventing gateway activation without a configured wallet address, with proper nonce verification.
128-153: LGTM!Good conditional script loading only when needed on the order-received page. Consider using a plugin version constant instead of hardcoded
'1.0'on line 145 for cache-busting consistency.
195-201: LGTM!Proper availability check ensuring the gateway only shows when enabled and configured with a wallet address.
206-232: LGTM!Clean admin panel rendering with proper escaping and useful transaction details including explorer link.
12-15: LGTM!Defining the gateway class inside the
plugins_loadedcallback is the correct pattern to ensureWC_Payment_Gatewayis available before extending it.
Klakurka
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
includes/class-paybutton-admin.php (1)
119-129: Translation-safe screen ID recommended (duplicate concern).The hardcoded
'woocommerce_page_wc-settings'screen ID can break on translated WordPress installations where the menu slug changes. The past review comment on this code suggested using a computed screen ID for better translation safety.While
get_current_screen()is correctly used here, consider the suggested approach from the previous review if you need to support multilingual admin interfaces.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
includes/class-paybutton-admin.phptemplates/admin/dashboard.php
🔇 Additional comments (3)
includes/class-paybutton-admin.php (3)
88-88: Good security improvement.Using
wp_safe_redirect()instead ofwp_redirect()ensures redirects are restricted to whitelisted hosts, preventing potential open redirect vulnerabilities.
195-196: LGTM!The WooCommerce Payments URL correctly points to the standard WooCommerce checkout settings page and properly integrates with the dashboard template changes.
345-348: The form field exists and is properly configured in the settings template. The checkbox at lines 146-150 oftemplates/admin/paywall-settings.phphas the correct name attributepaybutton_hide_sticky_headerand the option retrieval usesget_option()with the same key. The save logic at lines 345-348 correctly handles the checkbox submission.
|
@Klakurka Enabled the 'WooCommerce Payments' button in the dashboard. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
includes/class-paybutton-admin.php (1)
164-176: WooCommerce settings detection improved but could be more translation-safe.The dual-check approach (
$hook_suffixOR$screen->base) is better than relying solely on$hook_suffix. However, both checks still use the hardcoded'woocommerce_page_wc-settings'string, which can change on translated WordPress installations.A previous review comment suggested using
get_current_screen()->id === sanitize_title( __( 'WooCommerce', 'woocommerce' ) ) . '_page_wc-settings'for full translation safety. The current implementation partially addresses the concern with the fallback check but isn't fully translation-safe.Based on learnings from past review comments, consider implementing the fully translation-safe approach:
🔎 Suggested translation-safe approach
- // 3) WooCommerce → Settings → Payments (wallet address field) - if ( - $hook_suffix === 'woocommerce_page_wc-settings' - || ( $screen && $screen->base === 'woocommerce_page_wc-settings' ) - ) { + // 3) WooCommerce → Settings → Payments (wallet address field) + $wc_screen_id = $screen ? sanitize_title( __( 'WooCommerce', 'woocommerce' ) ) . '_page_wc-settings' : ''; + if ( + $hook_suffix === 'woocommerce_page_wc-settings' + || ( $screen && $screen->base === 'woocommerce_page_wc-settings' ) + || ( $screen && $screen->id === $wc_screen_id ) + ) { wp_enqueue_script( 'address-validator', PAYBUTTON_PLUGIN_URL . 'assets/js/addressValidator.bundle.js', array(), '2.0.0', true ); }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
assets/css/paybutton-admin.cssincludes/class-paybutton-admin.phptemplates/admin/dashboard.php
🚧 Files skipped from review as they are similar to previous changes (1)
- templates/admin/dashboard.php
🔇 Additional comments (5)
assets/css/paybutton-admin.css (1)
85-89: LGTM! Clean utility class for disabled states.The new
.paybutton-disabledclass provides a reusable way to indicate disabled states across the UI. The opacity and cursor values are appropriate and provide clear visual feedback to users.includes/class-paybutton-admin.php (4)
88-88: Good security improvement usingwp_safe_redirect.Switching from
wp_redirecttowp_safe_redirectadds URL validation to prevent potential open redirect vulnerabilities. This aligns with WordPress security best practices.
119-121: Good defensive programming with screen detection.The
function_existscheck prevents potential fatal errors whenget_current_screen()might not be available, such as during early admin hooks or AJAX requests.
202-204: Proper WooCommerce detection using standard approach.Using
class_exists('WooCommerce')is the recommended and standard way to detect WooCommerce installation. This aligns with WordPress and WooCommerce best practices.
352-356: LGTM! Consistent checkbox option handling.The sticky header toggle persistence follows the same pattern as other checkbox options in this function (e.g.,
paybutton_hide_comments_until_unlockedat line 286). The implementation is consistent and correct.
|
Ready for review. |



This PR implements #2 by adding WooCommerce support and some required misc refactors.
Test Plan:
Summary by CodeRabbit
New Features
Improvements
UI
✏️ Tip: You can customize this high-level summary in your review settings.