Skip to content

Commit

Permalink
Merge branch 'develop' into add/pass-blocks-checkout-appearance-on-in…
Browse files Browse the repository at this point in the history
…it-woopay
  • Loading branch information
hsingyuc authored Jul 16, 2024
2 parents 464ade4 + 71203da commit 32bd0d3
Show file tree
Hide file tree
Showing 25 changed files with 514 additions and 42 deletions.
4 changes: 4 additions & 0 deletions changelog/2024-07-11-21-06-01-653423
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: fix

Fix payment method title for Express Checkout Element orders.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: fix

Disable ECE for non shipping products if Tax is calculated on billing address.
4 changes: 4 additions & 0 deletions changelog/dev-bump-wc-version-9-1-2
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: dev

Bump WC tested up to version to 9.1.2
4 changes: 4 additions & 0 deletions changelog/fix-8892-use-correct-customer-id-in-renewals
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: fix

Use the customer id saved in the subscription to process renewal payments.
4 changes: 4 additions & 0 deletions changelog/fix-9005-fix-ece-button-width
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: fix

Fix Express Checkout Element button width.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: fix

Allow Afterpay gateway to process payments when the state/county is optional for GB and NZ addresses.
4 changes: 4 additions & 0 deletions changelog/fix-fatal-errors-when-subscriptions-are-unavailable
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fix

Fixing fatal errors when subscription classes are not available
4 changes: 4 additions & 0 deletions changelog/fix-send-optional-fields-data-to-woopay
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fix

Send optional fields data to WooPay.
8 changes: 8 additions & 0 deletions client/checkout/express-checkout-buttons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
}
}

// This fixes width calculation issues inside the iframe for blocks and shortcode pages.
.wcpay-payment-request-wrapper,
.wc-block-components-express-payment__event-buttons {
.StripeElement iframe {
max-width: unset;
}
}

.woocommerce-checkout .wcpay-payment-request-wrapper {
margin-bottom: 1.5em;
}
Expand Down
1 change: 1 addition & 0 deletions client/express-checkout/utils/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const normalizePayForOrderData = ( event, paymentMethodId ) => {
payment_method: 'woocommerce_payments',
'wcpay-payment-method': paymentMethodId,
express_payment_type: event?.expressPaymentType,
'wcpay-fraud-prevention-token': window.wcpayFraudPreventionToken ?? '',
};
};

Expand Down
2 changes: 2 additions & 0 deletions client/express-checkout/utils/test/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ describe( 'Express checkout normalization', () => {
expect( normalizePayForOrderData( event, 'pm_123456' ) ).toEqual( {
payment_method: 'woocommerce_payments',
'wcpay-payment-method': 'pm_123456',
'wcpay-fraud-prevention-token': 'token123',
express_payment_type: 'express',
} );
} );
Expand All @@ -315,6 +316,7 @@ describe( 'Express checkout normalization', () => {
).toEqual( {
payment_method: 'woocommerce_payments',
'wcpay-payment-method': '',
'wcpay-fraud-prevention-token': 'token123',
express_payment_type: undefined,
} );
} );
Expand Down
21 changes: 20 additions & 1 deletion includes/class-payment-information.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ class Payment_Information {
*/
private $payment_method_stripe_id;

/**
* The WCPay Customer ID that owns the payment token.
*
* @var string
*/
private $customer_id;

/**
* Payment information constructor.
*
Expand All @@ -117,6 +124,7 @@ class Payment_Information {
* @param string $cvc_confirmation The CVC confirmation for this payment method.
* @param string $fingerprint The attached fingerprint.
* @param string $payment_method_stripe_id The Stripe ID of the payment method used for this payment.
* @param string $customer_id The WCPay Customer ID that owns the payment token.
*
* @throws Invalid_Payment_Method_Exception When no payment method is found in the provided request.
*/
Expand All @@ -129,7 +137,8 @@ public function __construct(
Payment_Capture_Type $manual_capture = null,
string $cvc_confirmation = null,
string $fingerprint = '',
string $payment_method_stripe_id = null
string $payment_method_stripe_id = null,
string $customer_id = null
) {
if ( empty( $payment_method ) && empty( $token ) && ! \WC_Payments::is_network_saved_cards_enabled() ) {
// If network-wide cards are enabled, a payment method or token may not be specified and the platform default one will be used.
Expand All @@ -147,6 +156,7 @@ public function __construct(
$this->cvc_confirmation = $cvc_confirmation;
$this->fingerprint = $fingerprint;
$this->payment_method_stripe_id = $payment_method_stripe_id;
$this->customer_id = $customer_id;
}

/**
Expand Down Expand Up @@ -436,4 +446,13 @@ public function get_fingerprint() {
public function get_payment_method_stripe_id() {
return $this->payment_method_stripe_id;
}

/**
* Returns the WCPay Customer ID that owns the payment token.
*
* @return string The WCPay Customer ID.
*/
public function get_customer_id() {
return $this->customer_id;
}
}
38 changes: 35 additions & 3 deletions includes/class-wc-payment-gateway-wcpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -1475,10 +1475,16 @@ public function process_payment_for_order( $cart, $payment_information, $schedul
$amount = $order->get_total();
$metadata = $this->get_metadata_from_order( $order, $payment_information->get_payment_type() );

$customer_details_options = [
$customer_details_options = [
'is_woopay' => filter_var( $metadata['paid_on_woopay'] ?? false, FILTER_VALIDATE_BOOLEAN ),
];
list( $user, $customer_id ) = $this->manage_customer_details_for_order( $order, $customer_details_options );

if ( $payment_information->get_customer_id() ) {
$user = $order->get_user();
$customer_id = $payment_information->get_customer_id();
} else {
list( $user, $customer_id ) = $this->manage_customer_details_for_order( $order, $customer_details_options );
}

$intent_failed = false;
$payment_needed = $amount > 0;
Expand Down Expand Up @@ -4495,7 +4501,33 @@ private function upe_needs_redirection( $payment_methods ) {
* @return void
*/
private function handle_afterpay_shipping_requirement( WC_Order $order, Create_And_Confirm_Intention $request ): void {
$check_if_usable = function ( array $address ): bool {
$wc_locale_data = WC()->countries->get_country_locale();

$check_if_usable = function ( array $address ) use ( $wc_locale_data ): bool {
if ( $address['country'] && isset( $wc_locale_data[ $address['country'] ] ) ) {
$country_locale_data = $wc_locale_data[ $address['country'] ];
$fields_to_check = [
'state' => 'state',
'city' => 'city',
'postcode' => 'postal_code',
'address_1' => 'line1',
];

foreach ( $fields_to_check as $locale_field => $address_field ) {
$is_field_required = (
! isset( $country_locale_data[ $locale_field ] ) ||
! isset( $country_locale_data[ $locale_field ]['required'] ) ||
$country_locale_data[ $locale_field ]['required']
);

if ( $is_field_required && ! $address[ $address_field ] ) {
return false;
}
}

return true;
}

return $address['country'] && $address['state'] && $address['city'] && $address['postal_code'] && $address['line1'];
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,10 @@ public function scheduled_subscription_payment( $amount, $renewal_order ) {
return;
}

$customer_id = $this->order_service->get_customer_id_for_order( $renewal_order );

try {
$payment_information = new Payment_Information( '', $renewal_order, Payment_Type::RECURRING(), $token, Payment_Initiated_By::MERCHANT(), null, null, '', $this->get_payment_method_to_use_for_intent() );
$payment_information = new Payment_Information( '', $renewal_order, Payment_Type::RECURRING(), $token, Payment_Initiated_By::MERCHANT(), null, null, '', $this->get_payment_method_to_use_for_intent(), $customer_id );
$this->process_payment_for_order( null, $payment_information, true );
} catch ( API_Exception $e ) {
Logger::error( 'Error processing subscription renewal: ' . $e->getMessage() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public function ajax_pay_for_order() {
throw new Exception( __( 'This order does not require payment!', 'woocommerce-payments' ) );
}

$this->add_order_meta( $order_id );
$this->express_checkout_button_helper->add_order_payment_method_title( $order_id );

// Load the gateway.
$all_gateways = WC()->payment_gateways->get_available_payment_gateways();
Expand Down Expand Up @@ -431,35 +431,4 @@ public function ajax_empty_cart() {

wp_send_json( [ 'result' => 'success' ] );
}

/**
* Add needed order meta
*
* @param integer $order_id The order ID.
*
* @return void
*/
public function add_order_meta( $order_id ) {
if ( empty( $_POST['express_payment_type'] ) || ! isset( $_POST['payment_method'] ) || 'woocommerce_payments' !== $_POST['payment_method'] ) { // phpcs:ignore WordPress.Security.NonceVerification
return;
}

$order = wc_get_order( $order_id );

$express_payment_type = wc_clean( wp_unslash( $_POST['express_payment_type'] ) ); // phpcs:ignore WordPress.Security.NonceVerification

$express_payment_titles = [
'apple_pay' => 'Apple Pay',
'google_pay' => 'Google Pay',
];

$suffix = apply_filters( 'wcpay_payment_request_payment_method_title_suffix', 'WooPayments' );
if ( ! empty( $suffix ) ) {
$suffix = " ($suffix)";
}

$payment_method_title = isset( $express_payment_titles[ $express_payment_type ] ) ? $express_payment_titles[ $express_payment_type ] : 'Express Payment';
$order->set_payment_method_title( $payment_method_title . $suffix );
$order->save();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public function init() {
add_filter( 'woocommerce_registration_redirect', [ $this, 'get_login_redirect_url' ], 10, 3 );
add_action( 'wp_enqueue_scripts', [ $this, 'scripts' ] );
add_action( 'before_woocommerce_pay_form', [ $this, 'display_pay_for_order_page_html' ], 1 );
add_filter( 'woocommerce_gateway_title', [ $this, 'filter_gateway_title' ], 10, 2 );
add_action( 'woocommerce_checkout_order_processed', [ $this->express_checkout_helper, 'add_order_payment_method_title' ], 10, 2 );

$this->express_checkout_ajax_handler->init();
}
Expand Down Expand Up @@ -402,4 +404,31 @@ public function get_login_redirect_url( $redirect ) {

return $url;
}

/**
* Filters the gateway title to reflect the button type used.
*
* @param string $title Gateway title.
* @param string $id Gateway ID.
*/
public function filter_gateway_title( $title, $id ) {
if ( 'woocommerce_payments' !== $id || ! is_admin() ) {
return $title;
}

$order = $this->express_checkout_helper->get_current_order();
$method_title = is_object( $order ) ? $order->get_payment_method_title() : '';

if ( ! empty( $method_title ) ) {
if (
strpos( $method_title, 'Apple Pay' ) === 0
|| strpos( $method_title, 'Google Pay' ) === 0
|| strpos( $method_title, 'Payment Request' ) === 0 // Legacy PRB title.
) {
return $method_title;
}
}

return $title;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,26 @@ public function get_product() {
return null;
}

/**
* Used to get the order in admin edit page.
*
* @return WC_Order|WC_Order_Refund|bool
*/
public function get_current_order() {
global $theorder;
global $post;

if ( is_object( $theorder ) ) {
return $theorder;
}

if ( is_object( $post ) ) {
return wc_get_order( $post->ID );
}

return false;
}

/**
* Returns true if the provided WC_Product is a subscription, false otherwise.
*
Expand Down Expand Up @@ -397,6 +417,23 @@ public function should_show_express_checkout_button() {
return true;
}

// Non-shipping product and billing is calculated based on shopper billing addres. Excludes Pay for Order page.
if (
// If the product doesn't needs shipping.
(
// on the product page.
( $this->is_product() && ! $this->product_needs_shipping( $this->get_product() ) ) ||

// on the cart or checkout page.
( ( $this->is_cart() || $this->is_checkout() ) && ! WC()->cart->needs_shipping() )
)

// ...and billing is calculated based on billing address.
&& 'billing' === get_option( 'woocommerce_tax_based_on' )
) {
return false;
}

// Cart total is 0 or is on product page and product price is 0.
// Exclude pay-for-order pages from this check.
if (
Expand All @@ -411,6 +448,21 @@ public function should_show_express_checkout_button() {
return true;
}

/**
* Check if the passed product needs to be shipped.
*
* @param WC_Product $product The product to check.
*
* @return bool Returns true if the product requires shipping; otherwise, returns false.
*/
public function product_needs_shipping( WC_Product $product ) {
if ( ! $product ) {
return false;
}

return wc_shipping_enabled() && 0 !== wc_get_shipping_method_count( true ) && $product->needs_shipping();
}

/**
* Checks to make sure product type is supported.
*
Expand Down Expand Up @@ -1033,6 +1085,39 @@ public function update_shipping_method( $shipping_methods ) {
WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods );
}

/**
* Add express checkout payment method title to the order.
*
* @param integer $order_id The order ID.
*
* @return void
*/
public function add_order_payment_method_title( $order_id ) {
if ( empty( $_POST['express_payment_type'] ) || ! isset( $_POST['payment_method'] ) || 'woocommerce_payments' !== $_POST['payment_method'] ) { // phpcs:ignore WordPress.Security.NonceVerification
return;
}

$express_payment_type = wc_clean( wp_unslash( $_POST['express_payment_type'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
$express_payment_titles = [
'apple_pay' => 'Apple Pay',
'google_pay' => 'Google Pay',
];
$payment_method_title = $express_payment_titles[ $express_payment_type ] ?? false;

if ( ! $payment_method_title ) {
return;
}

$suffix = apply_filters( 'wcpay_payment_request_payment_method_title_suffix', 'WooPayments' );
if ( ! empty( $suffix ) ) {
$suffix = " ($suffix)";
}

$order = wc_get_order( $order_id );
$order->set_payment_method_title( $payment_method_title . $suffix );
$order->save();
}

/**
* Calculate and set shipping method.
*
Expand Down
Loading

0 comments on commit 32bd0d3

Please sign in to comment.