Skip to content

Commit 1caf146

Browse files
majikandywjrosa
andauthored
feat: For Shipping Zones Zip Regex - Correctly handle UK postcodes redacted by Apple Pay (#3592)
* Correctly handle UK postcodes redacted by Apple Pay * Same change added to class-wc-stripe-express-checkout-helper.php * Update includes/payment-methods/class-wc-stripe-express-checkout-helper.php * Update includes/payment-methods/class-wc-stripe-express-checkout-helper.php * Update includes/payment-methods/class-wc-stripe-payment-request.php * Update includes/payment-methods/class-wc-stripe-payment-request.php * Removing unnecessary early return * Readme and changelog entries * Specific unit tests --------- Co-authored-by: Wesley Rosa <[email protected]>
1 parent ddcceba commit 1caf146

File tree

5 files changed

+95
-7
lines changed

5 files changed

+95
-7
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*** Changelog ***
22

33
= 9.1.0 - xxxx-xx-xx =
4+
* Fix - Correctly handles UK postcodes redacted by Apple Pay.
45
* Tweak - Avoid re-sending Processing Order customer email when merchant wins dispute.
56
* Fix - Allow the saving of iDEAL tokens when SEPA is disabled.
67
* Fix - Fixes the incompatibility notice in editor due missing style property when instantiating Stripe payment methods.

includes/payment-methods/class-wc-stripe-express-checkout-helper.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,34 @@ private function get_default_shipping_option() {
322322
public function get_normalized_postal_code( $postcode, $country ) {
323323
/**
324324
* Currently, Apple Pay truncates the UK and Canadian postal codes to the first 4 and 3 characters respectively
325+
* Apple Pay also truncates Canadian postal codes to the first 4 characters.
325326
* when passing it back from the shippingcontactselected object. This causes WC to invalidate
326327
* the postal code and not calculate shipping zones correctly.
327328
*/
328329
if ( 'GB' === $country ) {
329-
// Replaces a redacted string with something like LN10***.
330-
return str_pad( preg_replace( '/\s+/', '', $postcode ), 7, '*' );
330+
// UK Postcodes returned from Apple Pay can be alpha numeric 2 chars, 3 chars, or 4 chars long will optionally have a trailing space,
331+
// depending on whether the customer put a space in their postcode between the outcode and incode part.
332+
// See https://assets.publishing.service.gov.uk/media/5a7b997d40f0b62826a049e0/ILRSpecification2013_14Appendix_C_Dec2012_v1.pdf for more details.
333+
334+
// Here is a table showing the functionality by example:
335+
// Original | Apple Pay | Normalized
336+
// 'LN10 1AA' | 'LN10 ' | 'LN10 ***'
337+
// 'LN101AA' | 'LN10' | 'LN10 ***'
338+
// 'W10 2AA' | 'W10 ' | 'W10 ***'
339+
// 'W102AA' | 'W10' | 'W10 ***'
340+
// 'N2 3AA | 'N2 ' | 'N2 ***'
341+
// 'N23AA | 'N2' | 'N2 ***'
342+
343+
$spaceless_postcode = preg_replace( '/\s+/', '', $postcode );
344+
345+
if ( strlen( $spaceless_postcode ) < 5 ) {
346+
// Always reintroduce the space so that Shipping Zones regex like 'N1 *' work to match N1 postcodes like N1 1AA, but don't match N10 postcodes like N10 1AA
347+
return $spaceless_postcode . ' ***';
348+
}
349+
350+
return $postcode; // 5 or more chars means it probably wasn't redacted and will likely validate unchanged.
331351
}
352+
332353
if ( 'CA' === $country ) {
333354
// Replaces a redacted string with something like L4Y***.
334355
return str_pad( preg_replace( '/\s+/', '', $postcode ), 6, '*' );

includes/payment-methods/class-wc-stripe-payment-request.php

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -512,14 +512,35 @@ public function filter_gateway_title( $title, $id ) {
512512
*/
513513
public function get_normalized_postal_code( $postcode, $country ) {
514514
/**
515-
* Currently, Apple Pay truncates the UK and Canadian postal codes to the first 4 and 3 characters respectively
516-
* when passing it back from the shippingcontactselected object. This causes WC to invalidate
515+
* Currently, Apple Pay truncates the UK postcodes by removing the "inward" (last 3 chars) of the postcode.
516+
* Apple Pay also truncates Canadian postal codes to the first 4 characters.
517+
* When either of these are passed back from the shippingcontactselected object. This causes WC to invalidate
517518
* the postal code and not calculate shipping zones correctly.
518519
*/
519520
if ( 'GB' === $country ) {
520-
// Replaces a redacted string with something like LN10***.
521-
return str_pad( preg_replace( '/\s+/', '', $postcode ), 7, '*' );
521+
// UK Postcodes returned from Apple Pay can be alpha numeric 2 chars, 3 chars, or 4 chars long will optionally have a trailing space,
522+
// depending on whether the customer put a space in their postcode between the outcode and incode part.
523+
// See https://assets.publishing.service.gov.uk/media/5a7b997d40f0b62826a049e0/ILRSpecification2013_14Appendix_C_Dec2012_v1.pdf for more details.
524+
525+
// Here is a table showing the functionality by example:
526+
// Original | Apple Pay | Normalized
527+
// 'LN10 1AA' | 'LN10 ' | 'LN10 ***'
528+
// 'LN101AA' | 'LN10' | 'LN10 ***'
529+
// 'W10 2AA' | 'W10 ' | 'W10 ***'
530+
// 'W102AA' | 'W10' | 'W10 ***'
531+
// 'N2 3AA | 'N2 ' | 'N2 ***'
532+
// 'N23AA | 'N2' | 'N2 ***'
533+
534+
$spaceless_postcode = preg_replace( '/\s+/', '', $postcode );
535+
536+
if ( strlen( $spaceless_postcode ) < 5 ) {
537+
// Always reintroduce the space so that Shipping Zones regex like 'N1 *' work to match N1 postcodes like N1 1AA, but don't match N10 postcodes like N10 1AA
538+
return $spaceless_postcode . ' ***';
539+
}
540+
541+
return $postcode; // 5 or more chars means it probably wasn't redacted and will likely validate unchanged.
522542
}
543+
523544
if ( 'CA' === $country ) {
524545
// Replaces a redacted string with something like L4Y***.
525546
return str_pad( preg_replace( '/\s+/', '', $postcode ), 6, '*' );

readme.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o
111111
== Changelog ==
112112

113113
= 9.1.0 - xxxx-xx-xx =
114+
* Fix - Correctly handles UK postcodes redacted by Apple Pay.
114115
* Tweak - Avoid re-sending Processing Order customer email when merchant wins dispute.
115116
* Fix - Allow the saving of iDEAL tokens when SEPA is disabled.
116117
* Fix - Fixes the incompatibility notice in editor due missing style property when instantiating Stripe payment methods.

tests/phpunit/test-wc-stripe-express-checkout-helper.php

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public function test_hides_ece_if_cannot_compute_taxes() {
7272
if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
7373
define( 'WOOCOMMERCE_CHECKOUT', true );
7474
}
75-
$original_gateways = WC()->payment_gateways()->payment_gateways;
75+
$original_gateways = WC()->payment_gateways()->payment_gateways;
7676
WC()->payment_gateways()->payment_gateways = [
7777
'stripe' => new WC_Gateway_Stripe(),
7878
];
@@ -267,4 +267,48 @@ public function test_is_account_creation_possible() {
267267
update_option( 'woocommerce_enable_signup_from_checkout_for_subscriptions', 'yes' );
268268
$this->assertTrue( $wc_stripe_ece_helper_mock2->is_account_creation_possible() );
269269
}
270+
271+
/**
272+
* Test for `get_normalized_postal_code`.
273+
*
274+
* @param string $postal_code Postal code.
275+
* @param string $country Country code.
276+
* @param string $expected Expected normalized postal code.
277+
* @return void
278+
* @dataProvider provide_test_get_normalized_postal_code
279+
*/
280+
public function test_get_normalized_postal_code( $postal_code, $country, $expected ) {
281+
$wc_stripe_ece_helper = new WC_Stripe_Express_Checkout_Helper();
282+
$this->assertEquals( $expected, $wc_stripe_ece_helper->get_normalized_postal_code( $postal_code, $country ) );
283+
}
284+
285+
/**
286+
* Provider for `test_get_normalized_postal_code`.
287+
*
288+
* @return array
289+
*/
290+
public function provide_test_get_normalized_postal_code() {
291+
return [
292+
'GB country' => [
293+
'postal code' => 'SW1A 1AA',
294+
'country' => 'GB',
295+
'expected' => 'SW1A 1AA',
296+
],
297+
'GB country, redacted' => [
298+
'postal code' => 'SW1A',
299+
'country' => 'GB',
300+
'expected' => 'SW1A ***',
301+
],
302+
'CA country' => [
303+
'postal code' => 'K1A ',
304+
'country' => 'CA',
305+
'expected' => 'K1A***',
306+
],
307+
'US country' => [
308+
'postal code' => '12345',
309+
'country' => 'US',
310+
'expected' => '12345',
311+
],
312+
];
313+
}
270314
}

0 commit comments

Comments
 (0)