Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches:
- develop
- master
- tests

jobs:
prepare:
Expand Down Expand Up @@ -79,6 +80,9 @@ jobs:
- wc_version: ${{needs.prepare.outputs.max_woo}}
php_version: 8.2
run_block_tests: 1
- wc_version: ${{needs.prepare.outputs.max_woo}}
php_version: 8.4
run_block_tests: 1
env:
PHP_VERSION: ${{ matrix.php_version }}
WOO_VERSION: ${{ matrix.wc_version }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ For more information, please check our [plugin page](https://wordpress.org/plugi

- WordPress 4.5+
- WooCommerce 6.9+
- [TaxCloud account](https://app.taxcloud.com/register?utm_campaign=22917502-woocommerce-marketplace&utm_source=readme.md)
- [TaxCloud account](https://app.taxcloud.com/register)

## Getting Started

Expand Down
19 changes: 1 addition & 18 deletions assets/css/admin.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* TaxCloud for WooCommerce - admin CSS
*
* @version 8.3.4
* @version 8.3.7
*/
.toplevel .form-error {
border-color: #be0636 !important;
Expand Down Expand Up @@ -211,21 +211,4 @@ p[class*="variable_tax_class"] {
.woocommerce-message ul.sst-address-list {
list-style: disc;
padding-left: 1.5rem;
}

/* Admin Notice */
.taxcloud-notice {
display: flex;
align-items: center;
padding-top: 10px !important;
padding-bottom: 10px !important;
}

.txc-notice-icon {
margin-right: 10px;
height: 50px;
}

.txc-notice-message p{
margin-top: 0;
}
115 changes: 84 additions & 31 deletions assets/js/admin.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,85 @@
/* global SST */
(function(data) {
jQuery( function() {
// Verify TaxCloud settings
jQuery( '#verifySettings' ).on( 'click', function( e ) {
e.preventDefault();

var apiID = jQuery( '#woocommerce_wootax_tc_id' ).val();
var apiKey = jQuery( '#woocommerce_wootax_tc_key' ).val();

if ( ! apiID || ! apiKey ) {
alert( data.strings.enter_id_and_key );
} else {
jQuery.post(
ajaxurl,
{
action: 'sst_verify_taxcloud',
wootax_tc_id: apiID,
wootax_tc_key: apiKey
},
function( resp ) {
if ( resp.success ) {
alert( data.strings.settings_valid );
} else {
alert( data.strings.verify_failed + ' ' + resp.data + '.' );
}
}
);
}
} );
} );
})(SST);
(function (data) {
jQuery(function ($) {

// Verify TaxCloud settings
jQuery('#verifySettings').on('click', function (e) {
e.preventDefault();

var apiID = jQuery('#woocommerce_wootax_tc_id').val();
var apiKey = jQuery('#woocommerce_wootax_tc_key').val();
var nonce = jQuery(this).data('nonce');

if (!apiID || !apiKey) {
alert(data.strings.enter_id_and_key);
return;
}

// Disable button while verifying
var $btn = jQuery(this).prop('disabled', true).text(data.strings.verifying);

// Send AJAX request to verify credentials
jQuery.post(ajaxurl, {
action: 'sst_verify_taxcloud',
wootax_tc_id: apiID,
wootax_tc_key: apiKey,
_wpnonce: nonce,
})
.done(function (resp) {
if (resp.success) {
alert(data.strings.settings_valid);
} else {
alert(data.strings.verify_failed + ' ' + resp.data + '.');
}
})
.fail(function (xhr, status, error) {
// Handle network/server/timeouts
console.error('AJAX POST failed:', xhr, status, error);
let message = 'Request failed (' + status + ')';
if (xhr.status >= 400) {
message += ' - HTTP ' + xhr.status;
}
alert(data.strings.verify_failed + '\n\n' + message);
})
.always(function () {
// Re-enable button after request
$btn.prop('disabled', false).text(data.strings.verify_btn);
});
});

// View Order Debug Log
jQuery(document).on('click', '.sst-debug-order', function (e) {
e.preventDefault();
var orderID = jQuery(this).data('order-id');
if (!orderID) {
return;
}
var nonce = jQuery(this).data('nonce');
var redirect = jQuery(this).data('redirect');

// Disable button while fetching log
var $btn = jQuery(this).prop('disabled', true);

// Fetch log via AJAX
jQuery.post(ajaxurl, {
action: 'sst_get_order_log',
order_id: orderID,
_wpnonce: nonce,
})
.done(function (resp) {
if (resp.success) {
// Open redirect link in new tab
window.open(redirect, '_blank');
}
})
.fail(function (xhr, status, error) {
console.error('AJAX POST failed:', xhr, status, error);
alert(data.strings.went_wrong);
})
.always(function () {
// Re-enable button after request
$btn.prop('disabled', false);
});
});
});
})(SST);
24 changes: 24 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
Changelog for Simple Sales Tax

Format based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

- [8.3.7] - 2025-10-24 =

Fixed:
- DEV-6055: Multivendor plugins tax calculation fails.

- [8.3.6] - 2025-10-16 =

Changed:
- Shipping method required message

Added:
- TaxCloud Settings Verification with AJAX Error Handling and Nonce Verification
- Order debug log: add wootax metadata

- [8.3.5] - 2025-10-02 =

Fixed:
- DEV-5715: Stripe Express Checkout

Added:
- DEV-5767: Admin warning messages


- [8.3.4] - 2025-09-15 =

Fixed:
Expand Down
17 changes: 16 additions & 1 deletion includes/abstracts/class-sst-abstract-cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ protected function do_lookup() {
__(
'Failed to calculate sales tax: Shipping origin address is invalid.',
'simple-sales-tax'
)
),
$package
);
continue;
}
Expand Down Expand Up @@ -465,6 +466,20 @@ protected function get_origin_for_product( $item, $destination ) {
* @since 7.0.2
*/
protected function is_origin_valid( $package ) {
// Debug: Check if valid origin
SST_Logger::add(
__(
'Checking package origin address validity',
'simple-sales-tax'
),
array(
'isset' => isset( $package['origin'] ),
'type' => is_a( $package['origin'], 'TaxCloud\Address' ),
'instanceof' => isset( $package['origin'] ) && $package['origin'] instanceof TaxCloud\Address,
)
);

// Return
return (
isset( $package['origin'] ) &&
$package['origin'] instanceof TaxCloud\Address
Expand Down
16 changes: 16 additions & 0 deletions includes/abstracts/class-sst-marketplace-integration.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,4 +302,20 @@ abstract public function is_user_seller( $user_id );
*/
abstract public function get_seller_address( $seller_id );

/**
* Validates whether the given address has the required fields
* to be used as an origin address.
*
* @param array $address Address components.
*
* @return bool
* @see https://github.com/FedTax/simplesalestax/pull/388
*/
public function is_valid_origin( $address ) {
return ! empty( $address['address'] ) &&
! empty( $address['city'] ) &&
! empty( $address['state'] ) &&
! empty( $address['postcode'] );
}

}
59 changes: 55 additions & 4 deletions includes/admin/class-sst-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ public static function output_tax_metabox( $post_or_order ) {
: $post_or_order->get_id();
$order = new SST_Order( $order_id );

// JS Enqueue.
wp_enqueue_script( 'sst-admin-js' );

do_action( 'sst_output_tax_meta_box', $order );
}

Expand Down Expand Up @@ -349,13 +352,29 @@ public static function render_user_certificates( $user ) {
* @since 8.3.5
*/
public static function render_admin_notice( $args ) {
// Parse args
$args = wp_parse_args( $args, array(
'id' => '',
'message' => '',
'type' => 'warning',
'button' => '',
))
));

// Check args
if ( empty( $args['id'] ) || empty( $args['message'] ) ) {
return;
}

// Check if notice has been dismissed
$dismissed_notices = SST_Settings::get( 'dismissed_notices', [] );
if ( in_array( $args['id'], $dismissed_notices, true ) ) {
return;
}

// Notice ID
$notice_id = 'txc-notice-' . sanitize_title( $args['id'] );
?>
<div class="taxcloud-notice notice notice-<?php echo esc_attr( $args['type'] ); ?> is-dismissible">
<div id="<?php echo esc_attr( $notice_id ); ?>" class="taxcloud-notice notice notice-<?php echo esc_attr( $args['type'] ); ?> is-dismissible" data-id="<?php echo esc_attr( $args['id'] ); ?>">
<?php // phpcs:ignore PluginCheck.CodeAnalysis.Offloading.OffloadedContent ?>
<img class="txc-notice-icon" srcset="https://ps.w.org/simple-sales-tax/assets/icon-128x128.png?rev=3326417, https://ps.w.org/simple-sales-tax/assets/icon-256x256.png?rev=3326417 2x" src="https://ps.w.org/simple-sales-tax/assets/icon-256x256.png?rev=3326417" alt="<?php esc_attr_e( 'TaxCloud for WooCommerce', 'simple-sales-tax' ); ?>">
<div class="txc-notice-message">
Expand All @@ -365,6 +384,35 @@ public static function render_admin_notice( $args ) {
<?php endif; ?>
</div>
</div>
<script type="text/javascript">
// Dismiss notices
jQuery( document ).ready( function() {
jQuery(document).on('click', '#<?php echo esc_attr( $notice_id ); ?> .notice-dismiss', function () {
const notice = jQuery(this).closest('.taxcloud-notice');
const noticeId = notice.data('id');
jQuery.post(ajaxurl, {
action: 'sst_dismiss_taxcloud_notice',
notice_id: noticeId,
nonce: '<?php echo esc_js( wp_create_nonce( 'dismiss_taxcloud_notice' ) ); ?>'
});
});
});
</script>
<style>
.taxcloud-notice {
display: flex;
align-items: center;
padding-top: 10px !important;
padding-bottom: 10px !important;
}
.txc-notice-icon {
margin-right: 10px;
height: 50px;
}
.txc-notice-message p{
margin-top: 0;
}
</style>
<?php
}

Expand All @@ -378,7 +426,9 @@ public static function display_admin_notices() {
if ( ! wc_tax_enabled() ) {
// phpcs:ignore WordPress.Security.EscapeOutput
self::render_admin_notice( array(
'message' => __( 'Taxes are not enabled in WooCommerce. TaxCloud for WooCommerce will not calculate taxes for any orders. Please enable taxes from WooCommerce > Settings > General.', 'simple-sales-tax' )
'id' => 'taxes-not-enabled',
'message' => __( 'Taxes are not enabled in WooCommerce. TaxCloud for WooCommerce will not calculate taxes for any orders. Please enable taxes from WooCommerce > Settings > General.', 'simple-sales-tax' ),
'type' => 'error'
));
}

Expand All @@ -387,7 +437,8 @@ public static function display_admin_notices() {
if ( 0 === $method_count ) {
// phpcs:ignore WordPress.Security.EscapeOutput
self::render_admin_notice( array(
'message' => __( 'No shipping method is set in WooCommerce. TaxCloud for WooCommerce will not calculate taxes for any orders.', 'simple-sales-tax' ),
'id' => 'no-shipping-methods',
'message' => __( 'No shipping methods are configured in WooCommerce. TaxCloud will not calculate taxes for orders that require shipping.', 'simple-sales-tax' ),
'button' => '<a class="button" href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=shipping' ) ) . '">' . __( 'Add a shipping method', 'simple-sales-tax' ) . '</a>',
));
}
Expand Down
2 changes: 1 addition & 1 deletion includes/admin/class-sst-integration.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function generate_button_html( $key, $data ) {
<legend class="screen-reader-text">
<span><?php echo wp_kses_post( $data['title'] ); ?></span>
</legend>
<button class="wp-core-ui button button-secondary" type="button" id="<?php echo esc_attr( $data['id'] ); ?>">
<button class="wp-core-ui button button-secondary" type="button" id="<?php echo esc_attr( $data['id'] ); ?>" <?php if( $key == 'verify_settings' ): ?>data-nonce="<?php echo esc_attr( wp_create_nonce( 'sst_verify_taxcloud_nonce' ) ); ?>"<?php endif; ?>>
<?php echo wp_kses_post( $data['label'] ); ?>
</button>
<?php echo wp_kses_post( $this->get_description_html( $data ) ); ?>
Expand Down
2 changes: 1 addition & 1 deletion includes/class-simplesalestax.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ final class SimpleSalesTax {
*
* @var string
*/
public $version = '8.3.4';
public $version = '8.3.7';

/**
* The singleton plugin instance.
Expand Down
Loading
Loading