Commit 08c8543421 for woocommerce
commit 08c854342137340aaec7d462a5845195d4e6208e
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date: Thu May 29 16:28:28 2025 +0300
[Payments NOX] Allow payment gateway IDs with uppercase characters (#58382)
* Allow uppercase characters in provide IDs
* test: Add more unit tests for gateway order update and provider ID arg checks
* Add changelog
diff --git a/plugins/woocommerce/changelog/fix-WOOPLUG-4425-payment-gateway-with-non-standard-ids b/plugins/woocommerce/changelog/fix-WOOPLUG-4425-payment-gateway-with-non-standard-ids
new file mode 100644
index 0000000000..73d6b73a24
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-WOOPLUG-4425-payment-gateway-with-non-standard-ids
@@ -0,0 +1,5 @@
+Significance: patch
+Type: fix
+Comment: Allow gateway IDs with uppercase characters in the new Payments Settings page UX.
+
+
diff --git a/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsRestController.php b/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsRestController.php
index f919a29d4a..0fd1bb79ad 100644
--- a/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsRestController.php
+++ b/plugins/woocommerce/src/Internal/Admin/Settings/PaymentsRestController.php
@@ -414,8 +414,8 @@ class PaymentsRestController extends RestApiControllerBase {
return new WP_Error( 'rest_invalid_param', esc_html__( 'The ordering argument must be an object with provider IDs as keys and numeric values as values.', 'woocommerce' ), array( 'status' => 400 ) );
}
- if ( sanitize_key( $provider_id ) !== $provider_id ) {
- return new WP_Error( 'rest_invalid_param', esc_html__( 'The provider ID must be a valid string.', 'woocommerce' ), array( 'status' => 400 ) );
+ if ( $this->sanitize_provider_id( $provider_id ) !== $provider_id ) {
+ return new WP_Error( 'rest_invalid_param', esc_html__( 'The provider ID must be a string with only ASCII letters, digits, underscores, and dashes.', 'woocommerce' ), array( 'status' => 400 ) );
}
if ( false === filter_var( $order, FILTER_VALIDATE_INT ) ) {
@@ -436,13 +436,38 @@ class PaymentsRestController extends RestApiControllerBase {
private function sanitize_providers_order_arg( array $value ): array {
// Sanitize the ordering object to ensure that the order values are integers and the provider IDs are safe strings.
foreach ( $value as $provider_id => $order ) {
- $id = sanitize_key( $provider_id );
+ $id = $this->sanitize_provider_id( $provider_id );
$value[ $id ] = intval( $order );
}
return $value;
}
+ /**
+ * Sanitize a provider ID.
+ *
+ * This method ensures that the provider ID is a safe string by removing any unwanted characters.
+ * It strips all HTML tags, removes accents, percent-encoded characters, and HTML entities,
+ * and allows only lowercase and uppercase letters, digits, underscores, and dashes.
+ *
+ * @param string $provider_id The provider ID to sanitize.
+ *
+ * @return string The sanitized provider ID.
+ */
+ private function sanitize_provider_id( string $provider_id ): string {
+ $provider_id = wp_strip_all_tags( $provider_id );
+ $provider_id = remove_accents( $provider_id );
+ // Remove percent-encoded characters.
+ $provider_id = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $provider_id );
+ // Remove HTML entities.
+ $provider_id = preg_replace( '/&.+?;/', '', $provider_id );
+
+ // Only lowercase and uppercase ASCII letters, digits, underscores, and dashes are allowed.
+ $provider_id = preg_replace( '|[^a-z0-9_\-]|i', '', $provider_id );
+
+ return $provider_id;
+ }
+
/**
* Prepare the response for the GET payment providers request.
*
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsRestControllerTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsRestControllerTest.php
index cc1628d8ed..91340697ee 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsRestControllerTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsRestControllerTest.php
@@ -551,7 +551,18 @@ class PaymentsRestControllerTest extends WC_REST_Unit_Test_Case {
array( array( WC_Gateway_Paypal::ID => false ) ),
array( array( WC_Gateway_Paypal::ID => 'bogus' ) ),
array( array( WC_Gateway_Paypal::ID => '1.0' ) ),
- array( array( '()/paypal%#' => 1 ) ),
+ array( array( 'pay@pal' => 1 ) ), // Invalid provider ID with not allowed characters.
+ array( array( 'pay/pal' => 1 ) ), // Invalid provider ID with not allowed characters.
+ array( array( 'pay(pal' => 1 ) ), // Invalid provider ID with not allowed characters.
+ array( array( 'pay)pal' => 1 ) ), // Invalid provider ID with not allowed characters.
+ array( array( 'pay&pal' => 1 ) ), // Invalid provider ID with not allowed characters.
+ array( array( 'pay$pal' => 1 ) ), // Invalid provider ID with not allowed characters.
+ array( array( 'pay#pal' => 1 ) ), // Invalid provider ID with not allowed characters.
+ array( array( 'páypäl' => 1 ) ), // Invalid provider ID with accented characters.
+ array( array( '<script></script>paypal<a></a>' => 1 ) ), // Invalid provider ID with HTML tags.
+ array( array( ' paypal<' => 1 ) ), // Invalid provider ID with HTML entities.
+ array( array( 'pay<pal' => 1 ) ), // Invalid provider ID with HTML entities.
+ array( array( '%2Fpay%3Apal' => 1 ) ), // Invalid provider ID with percent encoded characters.
array(
array(
WC_Gateway_Paypal::ID => '1.1',
@@ -605,7 +616,7 @@ class PaymentsRestControllerTest extends WC_REST_Unit_Test_Case {
$request->set_body_params(
array(
'order_map' => array(
- 'provider1' => 1,
+ 'Provider_01-1_AHA' => 1, // uppercase characters are allowed.
),
)
);