From 931516deb774b56969f97e597f9361b31e06f635 Mon Sep 17 00:00:00 2001 From: Harris Wong Date: Thu, 1 Sep 2022 17:08:25 -0600 Subject: [PATCH 01/20] Use 'card' for the default block UPE checkout --- client/checkout/blocks/upe-fields.js | 15 +++++++++++---- client/checkout/blocks/upe.js | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/client/checkout/blocks/upe-fields.js b/client/checkout/blocks/upe-fields.js index 233c7b145c9..d26e55bdd3d 100644 --- a/client/checkout/blocks/upe-fields.js +++ b/client/checkout/blocks/upe-fields.js @@ -376,9 +376,9 @@ const ConsumableWCPayFields = ( { api, ...props } ) => { return; } - async function createIntent() { + async function createIntent( paymentMethodId ) { try { - const response = await api.createIntent(); + const response = await api.createIntent( paymentMethodId ); setPaymentIntentId( response.id ); setClientSecret( response.client_secret ); } catch ( error ) { @@ -390,8 +390,15 @@ const ConsumableWCPayFields = ( { api, ...props } ) => { } } setHasRequestedIntent( true ); - createIntent(); - }, [ paymentIntentId, hasRequestedIntent, api, errorMessage, appearance ] ); + createIntent( props.paymentMethodId ); + }, [ + props.paymentMethodId, + paymentIntentId, + hasRequestedIntent, + api, + errorMessage, + appearance, + ] ); if ( ! clientSecret ) { if ( errorMessage ) { diff --git a/client/checkout/blocks/upe.js b/client/checkout/blocks/upe.js index e78a1be4cce..1359ac9355e 100644 --- a/client/checkout/blocks/upe.js +++ b/client/checkout/blocks/upe.js @@ -42,8 +42,8 @@ const api = new WCPayAPI( registerPaymentMethod( { name: PAYMENT_METHOD_NAME_CARD, - content: , - edit: , + content: , + edit: , savedTokenComponent: , canMakePayment: () => !! api.getStripe(), paymentMethodId: PAYMENT_METHOD_NAME_CARD, From 46d4297df7617e76292b630c802651ba09213ae5 Mon Sep 17 00:00:00 2001 From: Harris Wong Date: Wed, 7 Sep 2022 17:03:49 -0600 Subject: [PATCH 02/20] Attempt to load multiple payment methods for blocks (draft) --- client/checkout/api/index.js | 1 + client/checkout/blocks/upe.js | 78 ++++++++++++------- client/checkout/constants.js | 1 - includes/class-wc-payment-gateway-wcpay.php | 3 +- ...lass-wc-payments-blocks-payment-method.php | 17 +++- ...s-upe-blocks-bancontact-payment-method.php | 26 +++++++ ...ayments-upe-blocks-card-payment-method.php | 24 ++++++ ...ents-upe-blocks-giropay-payment-method.php | 26 +++++++ ...ayments-upe-blocks-sepa-payment-method.php | 26 +++++++ includes/class-wc-payments.php | 9 ++- .../class-wc-payments-api-client.php | 2 +- 11 files changed, 180 insertions(+), 33 deletions(-) create mode 100644 includes/class-wc-payments-upe-blocks-bancontact-payment-method.php create mode 100644 includes/class-wc-payments-upe-blocks-card-payment-method.php create mode 100644 includes/class-wc-payments-upe-blocks-giropay-payment-method.php create mode 100644 includes/class-wc-payments-upe-blocks-sepa-payment-method.php diff --git a/client/checkout/api/index.js b/client/checkout/api/index.js index 16d2b406440..fced2c03f9f 100644 --- a/client/checkout/api/index.js +++ b/client/checkout/api/index.js @@ -388,6 +388,7 @@ export default class WCPayAPI { * @return {Promise} The final promise for the request to the server. */ createIntent( paymentMethodType, orderId ) { + console.log( paymentMethodType ); return this.request( buildAjaxURL( getConfig( 'wcAjaxUrl' ), diff --git a/client/checkout/blocks/upe.js b/client/checkout/blocks/upe.js index 1359ac9355e..fc6c8754549 100644 --- a/client/checkout/blocks/upe.js +++ b/client/checkout/blocks/upe.js @@ -13,16 +13,38 @@ import { /** * Internal dependencies */ -import { PAYMENT_METHOD_NAME_CARD } from '../constants.js'; -import { getConfig } from 'utils/checkout'; +import { getUPEConfig } from 'utils/checkout'; import WCPayAPI from './../api'; import WCPayUPEFields from './upe-fields.js'; import { SavedTokenHandler } from './saved-token-handler'; import request from '../utils/request'; import enqueueFraudScripts from 'fraud-scripts'; import paymentRequestPaymentMethod from '../../payment-request/blocks'; +import { + PAYMENT_METHOD_NAME_CARD, + PAYMENT_METHOD_NAME_BANCONTACT, + PAYMENT_METHOD_NAME_BECS, + PAYMENT_METHOD_NAME_EPS, + PAYMENT_METHOD_NAME_GIROPAY, + PAYMENT_METHOD_NAME_IDEAL, + PAYMENT_METHOD_NAME_P24, + PAYMENT_METHOD_NAME_SEPA, + PAYMENT_METHOD_NAME_SOFORT, +} from '../constants.js'; + +const upeMethods = { + card: PAYMENT_METHOD_NAME_CARD, + bancontact: PAYMENT_METHOD_NAME_BANCONTACT, + au_becs_debit: PAYMENT_METHOD_NAME_BECS, + eps: PAYMENT_METHOD_NAME_EPS, + giropay: PAYMENT_METHOD_NAME_GIROPAY, + ideal: PAYMENT_METHOD_NAME_IDEAL, + p24: PAYMENT_METHOD_NAME_P24, + sepa_debit: PAYMENT_METHOD_NAME_SEPA, + sofort: PAYMENT_METHOD_NAME_SOFORT, +}; -const paymentMethodsConfig = getConfig( 'paymentMethodsConfig' ); +const paymentMethodsConfig = getUPEConfig( 'paymentMethodsConfig' ); const isStripeLinkEnabled = paymentMethodsConfig.link !== undefined && paymentMethodsConfig.card !== undefined; @@ -30,36 +52,38 @@ const isStripeLinkEnabled = // Create an API object, which will be used throughout the checkout. const api = new WCPayAPI( { - publishableKey: getConfig( 'publishableKey' ), - accountId: getConfig( 'accountId' ), - forceNetworkSavedCards: getConfig( 'forceNetworkSavedCards' ), - locale: getConfig( 'locale' ), - isUPEEnabled: getConfig( 'isUPEEnabled' ), + publishableKey: getUPEConfig( 'publishableKey' ), + accountId: getUPEConfig( 'accountId' ), + forceNetworkSavedCards: getUPEConfig( 'forceNetworkSavedCards' ), + locale: getUPEConfig( 'locale' ), + isUPEEnabled: getUPEConfig( 'isUPEEnabled' ), isStripeLinkEnabled, }, request ); -registerPaymentMethod( { - name: PAYMENT_METHOD_NAME_CARD, - content: , - edit: , - savedTokenComponent: , - canMakePayment: () => !! api.getStripe(), - paymentMethodId: PAYMENT_METHOD_NAME_CARD, - label: getConfig( 'checkoutTitle' ), - ariaLabel: __( 'WooCommerce Payments', 'woocommerce-payments' ), - supports: { - showSavedCards: getConfig( 'isSavedCardsEnabled' ) ?? false, - showSaveOption: - ( getConfig( 'isSavedCardsEnabled' ) && - ! getConfig( 'cartContainsSubscription' ) ) ?? - false, - features: getConfig( 'features' ), - }, -} ); +Object.entries( upeMethods ).map( ( [ upeName, upePaymentMethodId ] ) => + registerPaymentMethod( { + name: upeName, + content: , + edit: , + savedTokenComponent: , + canMakePayment: () => !! api.getStripe(), + paymentMethodId: upeName, + label: getUPEConfig( 'checkoutTitle' ), + ariaLabel: __( 'WooCommerce Payments', 'woocommerce-payments' ), + supports: { + showSavedCards: getUPEConfig( 'isSavedCardsEnabled' ) ?? false, + showSaveOption: + ( getUPEConfig( 'isSavedCardsEnabled' ) && + ! getUPEConfig( 'cartContainsSubscription' ) ) ?? + false, + features: getUPEConfig( 'features' ), + }, + } ) +); registerExpressPaymentMethod( paymentRequestPaymentMethod( api ) ); window.addEventListener( 'load', () => { - enqueueFraudScripts( getConfig( 'fraudServices' ) ); + enqueueFraudScripts( getUPEConfig( 'fraudServices' ) ); } ); diff --git a/client/checkout/constants.js b/client/checkout/constants.js index 6e10ac456ad..d9a71f96861 100644 --- a/client/checkout/constants.js +++ b/client/checkout/constants.js @@ -7,7 +7,6 @@ export const PAYMENT_METHOD_NAME_IDEAL = 'woocommerce_payments_ideal'; export const PAYMENT_METHOD_NAME_P24 = 'woocommerce_payments_p24'; export const PAYMENT_METHOD_NAME_SEPA = 'woocommerce_payments_sepa_debit'; export const PAYMENT_METHOD_NAME_SOFORT = 'woocommerce_payments_sofort'; -export const PAYMENT_METHOD_NAME_UPE = 'woocommerce_payments_upe'; export const PAYMENT_METHOD_NAME_PAYMENT_REQUEST = 'woocommerce_payments_payment_request'; export const WC_STORE_CART = 'wc/store/cart'; diff --git a/includes/class-wc-payment-gateway-wcpay.php b/includes/class-wc-payment-gateway-wcpay.php index a9fa18db898..cb238a0504b 100644 --- a/includes/class-wc-payment-gateway-wcpay.php +++ b/includes/class-wc-payment-gateway-wcpay.php @@ -1286,7 +1286,7 @@ public function process_payment_for_order( $cart, $payment_information, $additio $intent = $this->payments_api_client->get_intent( $platform_checkout_intent_id ); $intent_meta_order_id_raw = $intent->get_metadata()['order_id'] ?? ''; $intent_meta_order_id = is_numeric( $intent_meta_order_id_raw ) ? intval( $intent_meta_order_id_raw ) : 0; - + Logger::info( 'harris debug: ' . $intent_meta_order_id . "---" . $order_id); if ( $intent_meta_order_id !== $order_id ) { throw new Intent_Authentication_Exception( __( "We're not able to process this payment. Please try again later.", 'woocommerce-payments' ), @@ -1345,6 +1345,7 @@ public function process_payment_for_order( $cart, $payment_information, $additio $intent_meta_order_id = is_numeric( $intent_meta_order_id_raw ) ? intval( $intent_meta_order_id_raw ) : 0; if ( $intent_meta_order_id !== $order_id ) { + throw new Intent_Authentication_Exception( __( "We're not able to process this payment. Please try again later.", 'woocommerce-payments' ), 'order_id_mismatch' diff --git a/includes/class-wc-payments-blocks-payment-method.php b/includes/class-wc-payments-blocks-payment-method.php index c2fc77e08fd..acc80df8aa7 100644 --- a/includes/class-wc-payments-blocks-payment-method.php +++ b/includes/class-wc-payments-blocks-payment-method.php @@ -16,7 +16,7 @@ class WC_Payments_Blocks_Payment_Method extends AbstractPaymentMethodType { * * @var WC_Payment_Gateway_WCPay */ - private $gateway; + protected $gateway; /** * Initializes the class. @@ -83,7 +83,19 @@ public function get_payment_method_data() { ]; } - return array_merge( + // return array_merge( + // [ + // 'title' => $this->gateway->get_option( 'title', '' ), + // 'description' => $this->gateway->get_option( 'description', '' ), + // 'is_admin' => is_admin(), // Used to display payment method preview in wp-admin. + // ], + // $platform_checkout_config, + // $this->gateway->get_payment_fields_js_config() + // ); +//harris TODO: revert this change after debugging + $config = $this->gateway->get_payment_fields_js_config(); + + $result = array_merge( [ 'title' => $this->gateway->get_option( 'title', '' ), 'description' => $this->gateway->get_option( 'description', '' ), @@ -92,5 +104,6 @@ public function get_payment_method_data() { $platform_checkout_config, $this->gateway->get_payment_fields_js_config() ); + return $result; } } diff --git a/includes/class-wc-payments-upe-blocks-bancontact-payment-method.php b/includes/class-wc-payments-upe-blocks-bancontact-payment-method.php new file mode 100644 index 00000000000..37b8d74435f --- /dev/null +++ b/includes/class-wc-payments-upe-blocks-bancontact-payment-method.php @@ -0,0 +1,26 @@ +initialize(); + } + + /** + * Initializes the class. + */ + public function initialize() { + $this->name = Bancontact_Payment_Method::PAYMENT_METHOD_STRIPE_ID; + $this->gateway = WC_Payments::get_payment_gateway_by_id($this->name); + } +} diff --git a/includes/class-wc-payments-upe-blocks-card-payment-method.php b/includes/class-wc-payments-upe-blocks-card-payment-method.php new file mode 100644 index 00000000000..e501afe727f --- /dev/null +++ b/includes/class-wc-payments-upe-blocks-card-payment-method.php @@ -0,0 +1,24 @@ +initialize(); + } + + /** + * Initializes the class. + */ + public function initialize() { + $this->name = WC_Payment_Gateway_WCPay::GATEWAY_ID; + $this->gateway = WC_Payments::get_gateway(); + } +} diff --git a/includes/class-wc-payments-upe-blocks-giropay-payment-method.php b/includes/class-wc-payments-upe-blocks-giropay-payment-method.php new file mode 100644 index 00000000000..774fd56e3a7 --- /dev/null +++ b/includes/class-wc-payments-upe-blocks-giropay-payment-method.php @@ -0,0 +1,26 @@ +initialize(); + } + + /** + * Initializes the class. + */ + public function initialize() { + $this->name = Giropay_Payment_Method::PAYMENT_METHOD_STRIPE_ID; + $this->gateway = WC_Payments::get_payment_gateway_by_id($this->name); + } +} diff --git a/includes/class-wc-payments-upe-blocks-sepa-payment-method.php b/includes/class-wc-payments-upe-blocks-sepa-payment-method.php new file mode 100644 index 00000000000..534ee7b3e39 --- /dev/null +++ b/includes/class-wc-payments-upe-blocks-sepa-payment-method.php @@ -0,0 +1,26 @@ +initialize(); + } + + /** + * Initializes the class. + */ + public function initialize() { + $this->name = Sepa_Payment_Method::PAYMENT_METHOD_STRIPE_ID; + $this->gateway = WC_Payments::get_payment_gateway_by_id($this->name); + } +} diff --git a/includes/class-wc-payments.php b/includes/class-wc-payments.php index 83ffa6893a5..faf1a0673f2 100644 --- a/includes/class-wc-payments.php +++ b/includes/class-wc-payments.php @@ -945,7 +945,14 @@ public static function register_checkout_gateway( $payment_method_registry ) { require_once __DIR__ . '/class-wc-payments-blocks-payment-method.php'; if ( WC_Payments_Features::is_upe_enabled() ) { require_once __DIR__ . '/class-wc-payments-upe-blocks-payment-method.php'; - $payment_method_registry->register( new WC_Payments_UPE_Blocks_Payment_Method() ); + require_once __DIR__ . '/class-wc-payments-upe-blocks-card-payment-method.php'; + require_once __DIR__ . '/class-wc-payments-upe-blocks-bancontact-payment-method.php'; + require_once __DIR__ . '/class-wc-payments-upe-blocks-sepa-payment-method.php'; + require_once __DIR__ . '/class-wc-payments-upe-blocks-giropay-payment-method.php'; + $payment_method_registry->register( new WC_Payments_UPE_Blocks_Card_Payment_Method() ); + $payment_method_registry->register( new WC_Payments_UPE_Blocks_Bancontact_Payment_Method() ); + $payment_method_registry->register( new WC_Payments_UPE_Blocks_Sepa_Payment_Method() ); + $payment_method_registry->register( new WC_Payments_UPE_Blocks_Giropay_Payment_Method() ); } else { $payment_method_registry->register( new WC_Payments_Blocks_Payment_Method() ); } diff --git a/includes/wc-payment-api/class-wc-payments-api-client.php b/includes/wc-payment-api/class-wc-payments-api-client.php index ec581b4d289..17a01e3be50 100644 --- a/includes/wc-payment-api/class-wc-payments-api-client.php +++ b/includes/wc-payment-api/class-wc-payments-api-client.php @@ -246,7 +246,6 @@ public function create_and_confirm_intention( if ( ! empty( $cvc_confirmation ) ) { $request['cvc_confirmation'] = $cvc_confirmation; } - $response_array = $this->request_with_level3_data( $request, self::INTENTIONS_API, self::POST ); return $this->deserialize_intention_object_from_array( $response_array ); @@ -2109,6 +2108,7 @@ protected function request( $params, $api, $method, $is_site_specific = true, $u */ private function request_with_level3_data( $params, $api, $method, $is_site_specific = true ) { // If level3 data is not present for some reason, simply proceed normally. + Logger::error('harris debug' . json_encode($params)); if ( empty( $params['level3'] ) || ! is_array( $params['level3'] ) ) { return $this->request( $params, $api, $method, $is_site_specific ); } From 3ea4122d39694033d3a529cb1abeec5f18a52a89 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Mon, 10 Oct 2022 14:22:28 +0200 Subject: [PATCH 03/20] Display only enabled UPE payment methods --- client/checkout/blocks/upe.js | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/client/checkout/blocks/upe.js b/client/checkout/blocks/upe.js index fc6c8754549..6560c35ff79 100644 --- a/client/checkout/blocks/upe.js +++ b/client/checkout/blocks/upe.js @@ -20,34 +20,11 @@ import { SavedTokenHandler } from './saved-token-handler'; import request from '../utils/request'; import enqueueFraudScripts from 'fraud-scripts'; import paymentRequestPaymentMethod from '../../payment-request/blocks'; -import { - PAYMENT_METHOD_NAME_CARD, - PAYMENT_METHOD_NAME_BANCONTACT, - PAYMENT_METHOD_NAME_BECS, - PAYMENT_METHOD_NAME_EPS, - PAYMENT_METHOD_NAME_GIROPAY, - PAYMENT_METHOD_NAME_IDEAL, - PAYMENT_METHOD_NAME_P24, - PAYMENT_METHOD_NAME_SEPA, - PAYMENT_METHOD_NAME_SOFORT, -} from '../constants.js'; - -const upeMethods = { - card: PAYMENT_METHOD_NAME_CARD, - bancontact: PAYMENT_METHOD_NAME_BANCONTACT, - au_becs_debit: PAYMENT_METHOD_NAME_BECS, - eps: PAYMENT_METHOD_NAME_EPS, - giropay: PAYMENT_METHOD_NAME_GIROPAY, - ideal: PAYMENT_METHOD_NAME_IDEAL, - p24: PAYMENT_METHOD_NAME_P24, - sepa_debit: PAYMENT_METHOD_NAME_SEPA, - sofort: PAYMENT_METHOD_NAME_SOFORT, -}; -const paymentMethodsConfig = getUPEConfig( 'paymentMethodsConfig' ); +const enabledPaymentMethodsConfig = getUPEConfig( 'paymentMethodsConfig' ); const isStripeLinkEnabled = - paymentMethodsConfig.link !== undefined && - paymentMethodsConfig.card !== undefined; + enabledPaymentMethodsConfig.link !== undefined && + enabledPaymentMethodsConfig.card !== undefined; // Create an API object, which will be used throughout the checkout. const api = new WCPayAPI( @@ -62,7 +39,7 @@ const api = new WCPayAPI( request ); -Object.entries( upeMethods ).map( ( [ upeName, upePaymentMethodId ] ) => +Object.entries( enabledPaymentMethodsConfig ).map( ( [ upeName ] ) => registerPaymentMethod( { name: upeName, content: , From 080a1f8ef246b979751f9c2c2af50e5ff00f9c69 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Mon, 10 Oct 2022 14:24:31 +0200 Subject: [PATCH 04/20] Display corresponding payment method titles --- client/checkout/blocks/upe.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/checkout/blocks/upe.js b/client/checkout/blocks/upe.js index 6560c35ff79..76677d13e60 100644 --- a/client/checkout/blocks/upe.js +++ b/client/checkout/blocks/upe.js @@ -39,7 +39,7 @@ const api = new WCPayAPI( request ); -Object.entries( enabledPaymentMethodsConfig ).map( ( [ upeName ] ) => +Object.entries( enabledPaymentMethodsConfig ).map( ( [ upeName, upeConfig ] ) => registerPaymentMethod( { name: upeName, content: , @@ -47,7 +47,7 @@ Object.entries( enabledPaymentMethodsConfig ).map( ( [ upeName ] ) => savedTokenComponent: , canMakePayment: () => !! api.getStripe(), paymentMethodId: upeName, - label: getUPEConfig( 'checkoutTitle' ), + label: upeConfig.title, ariaLabel: __( 'WooCommerce Payments', 'woocommerce-payments' ), supports: { showSavedCards: getUPEConfig( 'isSavedCardsEnabled' ) ?? false, From 0711a8004fd900637b9f5ecb5df74fb92b9d76ad Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Tue, 11 Oct 2022 16:41:29 +0200 Subject: [PATCH 05/20] Render specific testing instructions whenever appropriate --- client/checkout/blocks/upe-fields.js | 19 ++++++++++--------- client/checkout/blocks/upe.js | 8 +++++++- .../class-upe-payment-gateway.php | 8 ++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/client/checkout/blocks/upe-fields.js b/client/checkout/blocks/upe-fields.js index d26e55bdd3d..d14e82d85a2 100644 --- a/client/checkout/blocks/upe-fields.js +++ b/client/checkout/blocks/upe-fields.js @@ -57,6 +57,7 @@ const useCustomerData = () => { const WCPayUPEFields = ( { api, activePaymentMethod, + testingInstructions, billing: { billingData }, eventRegistration: { onPaymentProcessing, @@ -77,14 +78,9 @@ const WCPayUPEFields = ( { const [ paymentCountry, setPaymentCountry ] = useState( null ); const paymentMethodsConfig = getConfig( 'paymentMethodsConfig' ); - const testMode = getConfig( 'testMode' ); - const testCopy = ( -

- Test mode: use the test VISA card 4242424242424242 - with any expiry date and CVC. -

- ); - + const isTestMode = getConfig( 'testMode' ); + const testingInstructionsIfAppropriate = + isTestMode && false !== testingInstructions ? testingInstructions : ''; const gatewayConfig = getPaymentMethods()[ PAYMENT_METHOD_NAME_CARD ]; const customerData = useCustomerData(); @@ -332,7 +328,12 @@ const WCPayUPEFields = ( { return ( <> - { testMode ? testCopy : '' } +

registerPaymentMethod( { name: upeName, - content: , + content: ( + + ), edit: , savedTokenComponent: , canMakePayment: () => !! api.getStripe(), diff --git a/includes/payment-methods/class-upe-payment-gateway.php b/includes/payment-methods/class-upe-payment-gateway.php index 798d3187992..17f4ee55ebc 100644 --- a/includes/payment-methods/class-upe-payment-gateway.php +++ b/includes/payment-methods/class-upe-payment-gateway.php @@ -1077,6 +1077,14 @@ private function get_enabled_payment_method_config() { 'title' => $payment_method->get_title(), 'upePaymentIntentData' => $this->get_payment_intent_data_from_session( $payment_method_id ), 'upeSetupIntentData' => $this->get_setup_intent_data_from_session( $payment_method_id ), + 'testingInstructions' => WC_Payments_Utils::esc_interpolated_html( + /* translators: link to Stripe testing page */ + $payment_method->get_testing_instructions(), + [ + 'strong' => '', + 'a' => '', + ] + ), ]; } From 90a38296f5923ed3c439c071f5b6c54a7bce6022 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Wed, 12 Oct 2022 22:42:00 +0200 Subject: [PATCH 06/20] Provide the right gatewayConfig for each payment method --- client/checkout/blocks/confirm-upe-payment.js | 1 + client/checkout/blocks/upe-fields.js | 10 ++++---- client/checkout/blocks/upe.js | 25 ++++++++++++++++++- includes/class-payment-information.php | 1 - 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/client/checkout/blocks/confirm-upe-payment.js b/client/checkout/blocks/confirm-upe-payment.js index aeaff54750c..fa155346e8e 100644 --- a/client/checkout/blocks/confirm-upe-payment.js +++ b/client/checkout/blocks/confirm-upe-payment.js @@ -17,6 +17,7 @@ export default async function confirmUPEPayment( billingData, emitResponse ) { + console.log( 'we are confirming the UPE payment right now' ); const name = `${ billingData.first_name } ${ billingData.last_name }`.trim() || '-'; diff --git a/client/checkout/blocks/upe-fields.js b/client/checkout/blocks/upe-fields.js index d14e82d85a2..c29ca12afce 100644 --- a/client/checkout/blocks/upe-fields.js +++ b/client/checkout/blocks/upe-fields.js @@ -22,7 +22,7 @@ import './style.scss'; import confirmUPEPayment from './confirm-upe-payment.js'; import { getConfig } from 'utils/checkout'; import { getTerms } from '../utils/upe'; -import { PAYMENT_METHOD_NAME_CARD, WC_STORE_CART } from '../constants.js'; +import { WC_STORE_CART } from '../constants.js'; import enableStripeLinkPaymentMethod from 'wcpay/checkout/stripe-link'; import { useDispatch, useSelect } from '@wordpress/data'; import { getAppearance, getFontRulesFromPage } from '../upe-styles'; @@ -64,6 +64,7 @@ const WCPayUPEFields = ( { onCheckoutAfterProcessingWithSuccess, }, emitResponse, + paymentMethodId, paymentIntentId, errorMessage, shouldSavePayment, @@ -81,7 +82,7 @@ const WCPayUPEFields = ( { const isTestMode = getConfig( 'testMode' ); const testingInstructionsIfAppropriate = isTestMode && false !== testingInstructions ? testingInstructions : ''; - const gatewayConfig = getPaymentMethods()[ PAYMENT_METHOD_NAME_CARD ]; + const gatewayConfig = getPaymentMethods()[ paymentMethodId ]; const customerData = useCustomerData(); useEffect( () => { @@ -191,7 +192,7 @@ const WCPayUPEFields = ( { useEffect( () => onPaymentProcessing( () => { - if ( PAYMENT_METHOD_NAME_CARD !== activePaymentMethod ) { + if ( paymentMethodId !== activePaymentMethod ) { return; } @@ -225,7 +226,7 @@ const WCPayUPEFields = ( { type: 'success', meta: { paymentMethodData: { - paymentMethod: PAYMENT_METHOD_NAME_CARD, + paymentMethod: paymentMethodId, wc_payment_intent_id: paymentIntentId, wcpay_selected_upe_payment_type: selectedUPEPaymentType, }, @@ -376,7 +377,6 @@ const ConsumableWCPayFields = ( { api, ...props } ) => { if ( paymentIntentId || hasRequestedIntent ) { return; } - async function createIntent( paymentMethodId ) { try { const response = await api.createIntent( paymentMethodId ); diff --git a/client/checkout/blocks/upe.js b/client/checkout/blocks/upe.js index be662d60313..7fb729c1569 100644 --- a/client/checkout/blocks/upe.js +++ b/client/checkout/blocks/upe.js @@ -20,6 +20,29 @@ import { SavedTokenHandler } from './saved-token-handler'; import request from '../utils/request'; import enqueueFraudScripts from 'fraud-scripts'; import paymentRequestPaymentMethod from '../../payment-request/blocks'; +import { + PAYMENT_METHOD_NAME_CARD, + PAYMENT_METHOD_NAME_BANCONTACT, + PAYMENT_METHOD_NAME_BECS, + PAYMENT_METHOD_NAME_EPS, + PAYMENT_METHOD_NAME_GIROPAY, + PAYMENT_METHOD_NAME_IDEAL, + PAYMENT_METHOD_NAME_P24, + PAYMENT_METHOD_NAME_SEPA, + PAYMENT_METHOD_NAME_SOFORT, +} from '../constants.js'; + +const upeMethods = { + card: PAYMENT_METHOD_NAME_CARD, + bancontact: PAYMENT_METHOD_NAME_BANCONTACT, + au_becs_debit: PAYMENT_METHOD_NAME_BECS, + eps: PAYMENT_METHOD_NAME_EPS, + giropay: PAYMENT_METHOD_NAME_GIROPAY, + ideal: PAYMENT_METHOD_NAME_IDEAL, + p24: PAYMENT_METHOD_NAME_P24, + sepa_debit: PAYMENT_METHOD_NAME_SEPA, + sofort: PAYMENT_METHOD_NAME_SOFORT, +}; const enabledPaymentMethodsConfig = getUPEConfig( 'paymentMethodsConfig' ); const isStripeLinkEnabled = @@ -52,7 +75,7 @@ Object.entries( enabledPaymentMethodsConfig ).map( ( [ upeName, upeConfig ] ) => edit: , savedTokenComponent: , canMakePayment: () => !! api.getStripe(), - paymentMethodId: upeName, + paymentMethodId: upeMethods[ upeName ], label: upeConfig.title, ariaLabel: __( 'WooCommerce Payments', 'woocommerce-payments' ), supports: { diff --git a/includes/class-payment-information.php b/includes/class-payment-information.php index 25d1c3fa84b..44558fc7704 100644 --- a/includes/class-payment-information.php +++ b/includes/class-payment-information.php @@ -227,7 +227,6 @@ public static function from_payment_request( $order->add_meta_data( 'is_woopay', true, true ); $order->save_meta_data(); } - return new Payment_Information( $payment_method, $order, $payment_type, $token, $payment_initiated_by, $manual_capture, $cvc_confirmation ); } From e85f6cf5eb656c25b8a03f2827f7746ba8ee8245 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Thu, 13 Oct 2022 13:58:21 +0200 Subject: [PATCH 07/20] Fix the action of updating a payment intent with AJAX request --- client/checkout/api/index.js | 6 ++++-- client/checkout/blocks/confirm-upe-payment.js | 1 - includes/class-wc-payment-gateway-wcpay.php | 1 - includes/payment-methods/class-upe-payment-gateway.php | 2 +- includes/wc-payment-api/class-wc-payments-api-client.php | 1 - 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/client/checkout/api/index.js b/client/checkout/api/index.js index e149ee2dcf3..bda8cde9a81 100644 --- a/client/checkout/api/index.js +++ b/client/checkout/api/index.js @@ -392,7 +392,6 @@ export default class WCPayAPI { * @return {Promise} The final promise for the request to the server. */ createIntent( paymentMethodType, orderId ) { - console.log( paymentMethodType ); return this.request( buildAjaxURL( getConfig( 'wcAjaxUrl' ), @@ -438,7 +437,10 @@ export default class WCPayAPI { paymentCountry ) { return this.request( - buildAjaxURL( getConfig( 'wcAjaxUrl' ), 'update_payment_intent' ), + buildAjaxURL( + getConfig( 'wcAjaxUrl' ), + `update_payment_intent_${ selectedUPEPaymentType }` + ), { wcpay_order_id: orderId, wc_payment_intent_id: paymentIntentId, diff --git a/client/checkout/blocks/confirm-upe-payment.js b/client/checkout/blocks/confirm-upe-payment.js index fa155346e8e..aeaff54750c 100644 --- a/client/checkout/blocks/confirm-upe-payment.js +++ b/client/checkout/blocks/confirm-upe-payment.js @@ -17,7 +17,6 @@ export default async function confirmUPEPayment( billingData, emitResponse ) { - console.log( 'we are confirming the UPE payment right now' ); const name = `${ billingData.first_name } ${ billingData.last_name }`.trim() || '-'; diff --git a/includes/class-wc-payment-gateway-wcpay.php b/includes/class-wc-payment-gateway-wcpay.php index f2f72cad41a..b12caef8f9a 100644 --- a/includes/class-wc-payment-gateway-wcpay.php +++ b/includes/class-wc-payment-gateway-wcpay.php @@ -1299,7 +1299,6 @@ public function process_payment_for_order( $cart, $payment_information, $additio $intent = $this->payments_api_client->get_intent( $platform_checkout_intent_id ); $intent_meta_order_id_raw = $intent->get_metadata()['order_id'] ?? ''; $intent_meta_order_id = is_numeric( $intent_meta_order_id_raw ) ? intval( $intent_meta_order_id_raw ) : 0; - Logger::info( 'harris debug: ' . $intent_meta_order_id . "---" . $order_id); if ( $intent_meta_order_id !== $order_id ) { throw new Intent_Authentication_Exception( __( "We're not able to process this payment. Please try again later.", 'woocommerce-payments' ), diff --git a/includes/payment-methods/class-upe-payment-gateway.php b/includes/payment-methods/class-upe-payment-gateway.php index 17f4ee55ebc..cb4142d3e15 100644 --- a/includes/payment-methods/class-upe-payment-gateway.php +++ b/includes/payment-methods/class-upe-payment-gateway.php @@ -98,7 +98,7 @@ public function __construct( $this->title = $payment_method->get_title(); add_action( "wc_ajax_wcpay_create_payment_intent_$this->stripe_id", [ $this, 'create_payment_intent_ajax' ] ); - add_action( "wc_ajax_wcpay_update_payment_inten_ $this->stripe_id", [ $this, 'update_payment_intent_ajax' ] ); + add_action( "wc_ajax_wcpay_update_payment_intent_$this->stripe_id", [ $this, 'update_payment_intent_ajax' ] ); add_action( "wc_ajax_wcpay_init_setup_intent_$this->stripe_id", [ $this, 'init_setup_intent_ajax' ] ); if ( 'card' !== $this->stripe_id ) { diff --git a/includes/wc-payment-api/class-wc-payments-api-client.php b/includes/wc-payment-api/class-wc-payments-api-client.php index 17a01e3be50..de3e672b8a6 100644 --- a/includes/wc-payment-api/class-wc-payments-api-client.php +++ b/includes/wc-payment-api/class-wc-payments-api-client.php @@ -2108,7 +2108,6 @@ protected function request( $params, $api, $method, $is_site_specific = true, $u */ private function request_with_level3_data( $params, $api, $method, $is_site_specific = true ) { // If level3 data is not present for some reason, simply proceed normally. - Logger::error('harris debug' . json_encode($params)); if ( empty( $params['level3'] ) || ! is_array( $params['level3'] ) ) { return $this->request( $params, $api, $method, $is_site_specific ); } From 2b40054308c68c479f4c874a869ae809762e0ed5 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Fri, 14 Oct 2022 17:03:47 +0200 Subject: [PATCH 08/20] Fix tests --- tests/unit/payment-methods/test-class-upe-payment-gateway.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/payment-methods/test-class-upe-payment-gateway.php b/tests/unit/payment-methods/test-class-upe-payment-gateway.php index 70329321087..8a4536454fc 100644 --- a/tests/unit/payment-methods/test-class-upe-payment-gateway.php +++ b/tests/unit/payment-methods/test-class-upe-payment-gateway.php @@ -1556,12 +1556,14 @@ public function test_link_payment_method_if_card_enabled() { 'title' => 'Credit card / debit card', 'upePaymentIntentData' => null, 'upeSetupIntentData' => null, + 'testingInstructions' => 'Test mode: use the test VISA card 4242424242424242 with any expiry date and CVC. Other payment methods may redirect to a Stripe test page to authorize payment. More test card numbers are listed here.', ], 'link' => [ 'isReusable' => true, 'title' => 'Link', 'upePaymentIntentData' => null, 'upeSetupIntentData' => null, + 'testingInstructions' => '', ], ] ); From 6a10a657adb0a1349ed93d153dedc42c356c9586 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Mon, 17 Oct 2022 00:17:35 +0200 Subject: [PATCH 09/20] Supply the Card Element instead of the Card from Stripe Payment Elements --- client/checkout/blocks/fields.js | 27 ++++++++++++++----- ...lass-wc-payments-blocks-payment-method.php | 15 +---------- ...-wc-payments-upe-blocks-payment-method.php | 5 ++-- includes/class-wc-payments.php | 9 +------ .../class-upe-payment-gateway.php | 3 +++ .../test-class-upe-payment-gateway.php | 7 ----- 6 files changed, 29 insertions(+), 37 deletions(-) diff --git a/client/checkout/blocks/fields.js b/client/checkout/blocks/fields.js index 08a0f08a808..d0c0f9e5d9a 100644 --- a/client/checkout/blocks/fields.js +++ b/client/checkout/blocks/fields.js @@ -7,6 +7,7 @@ import { CardElement, } from '@stripe/react-stripe-js'; import { useEffect, useState } from '@wordpress/element'; +import { getConfig } from 'utils/checkout'; /** * Internal dependencies @@ -30,6 +31,17 @@ const WCPayFields = ( { shouldSavePayment, } ) => { const [ errorMessage, setErrorMessage ] = useState( null ); + const testMode = getConfig( 'testMode' ); + const testCopy = ( +

+ Test mode: use the test VISA card 4242424242424242 + with any expiry date and CVC, or any test card numbers listed{ ' ' } + + here + + . +

+ ); // When it's time to process the payment, generate a Stripe payment method object. useEffect( @@ -86,12 +98,15 @@ const WCPayFields = ( { }; return ( -
- -
+ <> + { testMode ? testCopy : '' } +
+ +
+ ); }; diff --git a/includes/class-wc-payments-blocks-payment-method.php b/includes/class-wc-payments-blocks-payment-method.php index acc80df8aa7..b5fcf81fa35 100644 --- a/includes/class-wc-payments-blocks-payment-method.php +++ b/includes/class-wc-payments-blocks-payment-method.php @@ -83,19 +83,7 @@ public function get_payment_method_data() { ]; } - // return array_merge( - // [ - // 'title' => $this->gateway->get_option( 'title', '' ), - // 'description' => $this->gateway->get_option( 'description', '' ), - // 'is_admin' => is_admin(), // Used to display payment method preview in wp-admin. - // ], - // $platform_checkout_config, - // $this->gateway->get_payment_fields_js_config() - // ); -//harris TODO: revert this change after debugging - $config = $this->gateway->get_payment_fields_js_config(); - - $result = array_merge( + return array_merge( [ 'title' => $this->gateway->get_option( 'title', '' ), 'description' => $this->gateway->get_option( 'description', '' ), @@ -104,6 +92,5 @@ public function get_payment_method_data() { $platform_checkout_config, $this->gateway->get_payment_fields_js_config() ); - return $result; } } diff --git a/includes/class-wc-payments-upe-blocks-payment-method.php b/includes/class-wc-payments-upe-blocks-payment-method.php index 0a5ebcbd4c0..91466dbf875 100644 --- a/includes/class-wc-payments-upe-blocks-payment-method.php +++ b/includes/class-wc-payments-upe-blocks-payment-method.php @@ -15,6 +15,7 @@ class WC_Payments_UPE_Blocks_Payment_Method extends WC_Payments_Blocks_Payment_M * @return string[] A list of script handles. */ public function get_payment_method_script_handles() { + $classic_blocks_scripts = parent::get_payment_method_script_handles(); wp_enqueue_style( 'wc-blocks-checkout-style', plugins_url( 'dist/upe-blocks-checkout.css', WCPAY_PLUGIN_FILE ), @@ -31,7 +32,7 @@ public function get_payment_method_script_handles() { ); wp_register_script( - 'WCPAY_BLOCKS_CHECKOUT', + 'WCPAY_BLOCKS_UPE_CHECKOUT', plugins_url( 'dist/upe-blocks-checkout.js', WCPAY_PLUGIN_FILE ), [ 'stripe' ], '1.0.1', @@ -39,6 +40,6 @@ public function get_payment_method_script_handles() { ); wp_set_script_translations( 'WCPAY_BLOCKS_CHECKOUT', 'woocommerce-payments' ); - return [ 'WCPAY_BLOCKS_CHECKOUT' ]; + return array_merge( $classic_blocks_scripts, [ 'WCPAY_BLOCKS_UPE_CHECKOUT' ] ); } } diff --git a/includes/class-wc-payments.php b/includes/class-wc-payments.php index f90c19fa6b0..50b256d11b5 100644 --- a/includes/class-wc-payments.php +++ b/includes/class-wc-payments.php @@ -948,14 +948,7 @@ public static function register_checkout_gateway( $payment_method_registry ) { require_once __DIR__ . '/class-wc-payments-blocks-payment-method.php'; if ( WC_Payments_Features::is_upe_enabled() ) { require_once __DIR__ . '/class-wc-payments-upe-blocks-payment-method.php'; - require_once __DIR__ . '/class-wc-payments-upe-blocks-card-payment-method.php'; - require_once __DIR__ . '/class-wc-payments-upe-blocks-bancontact-payment-method.php'; - require_once __DIR__ . '/class-wc-payments-upe-blocks-sepa-payment-method.php'; - require_once __DIR__ . '/class-wc-payments-upe-blocks-giropay-payment-method.php'; - $payment_method_registry->register( new WC_Payments_UPE_Blocks_Card_Payment_Method() ); - $payment_method_registry->register( new WC_Payments_UPE_Blocks_Bancontact_Payment_Method() ); - $payment_method_registry->register( new WC_Payments_UPE_Blocks_Sepa_Payment_Method() ); - $payment_method_registry->register( new WC_Payments_UPE_Blocks_Giropay_Payment_Method() ); + $payment_method_registry->register( new WC_Payments_UPE_Blocks_Payment_Method() ); } else { $payment_method_registry->register( new WC_Payments_Blocks_Payment_Method() ); } diff --git a/includes/payment-methods/class-upe-payment-gateway.php b/includes/payment-methods/class-upe-payment-gateway.php index 6abb337aad0..f23adbfbced 100644 --- a/includes/payment-methods/class-upe-payment-gateway.php +++ b/includes/payment-methods/class-upe-payment-gateway.php @@ -1068,6 +1068,9 @@ private function get_enabled_payment_method_config() { $enabled_payment_methods = $this->get_payment_method_ids_enabled_at_checkout(); foreach ( $enabled_payment_methods as $payment_method_id ) { + if ( 'card' === $payment_method_id ) { + continue; + } $payment_method = $this->wc_payments_get_payment_method_by_id( $payment_method_id ); $settings[ $payment_method_id ] = [ 'isReusable' => $payment_method->is_reusable(), diff --git a/tests/unit/payment-methods/test-class-upe-payment-gateway.php b/tests/unit/payment-methods/test-class-upe-payment-gateway.php index 8a4536454fc..93588150657 100644 --- a/tests/unit/payment-methods/test-class-upe-payment-gateway.php +++ b/tests/unit/payment-methods/test-class-upe-payment-gateway.php @@ -1551,13 +1551,6 @@ public function test_link_payment_method_if_card_enabled() { $this->assertSame( $mock_upe_gateway->get_payment_fields_js_config()['paymentMethodsConfig'], [ - 'card' => [ - 'isReusable' => true, - 'title' => 'Credit card / debit card', - 'upePaymentIntentData' => null, - 'upeSetupIntentData' => null, - 'testingInstructions' => 'Test mode: use the test VISA card 4242424242424242 with any expiry date and CVC. Other payment methods may redirect to a Stripe test page to authorize payment. More test card numbers are listed here.', - ], 'link' => [ 'isReusable' => true, 'title' => 'Link', From 959d0b489176295138a674626c66b705a6bd1e87 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Mon, 17 Oct 2022 00:33:59 +0200 Subject: [PATCH 10/20] Eliminate unnecessary upe payment methods for blocks --- ...s-upe-blocks-bancontact-payment-method.php | 26 ------------------- ...ayments-upe-blocks-card-payment-method.php | 24 ----------------- ...ents-upe-blocks-giropay-payment-method.php | 26 ------------------- ...ayments-upe-blocks-sepa-payment-method.php | 26 ------------------- 4 files changed, 102 deletions(-) delete mode 100644 includes/class-wc-payments-upe-blocks-bancontact-payment-method.php delete mode 100644 includes/class-wc-payments-upe-blocks-card-payment-method.php delete mode 100644 includes/class-wc-payments-upe-blocks-giropay-payment-method.php delete mode 100644 includes/class-wc-payments-upe-blocks-sepa-payment-method.php diff --git a/includes/class-wc-payments-upe-blocks-bancontact-payment-method.php b/includes/class-wc-payments-upe-blocks-bancontact-payment-method.php deleted file mode 100644 index 37b8d74435f..00000000000 --- a/includes/class-wc-payments-upe-blocks-bancontact-payment-method.php +++ /dev/null @@ -1,26 +0,0 @@ -initialize(); - } - - /** - * Initializes the class. - */ - public function initialize() { - $this->name = Bancontact_Payment_Method::PAYMENT_METHOD_STRIPE_ID; - $this->gateway = WC_Payments::get_payment_gateway_by_id($this->name); - } -} diff --git a/includes/class-wc-payments-upe-blocks-card-payment-method.php b/includes/class-wc-payments-upe-blocks-card-payment-method.php deleted file mode 100644 index e501afe727f..00000000000 --- a/includes/class-wc-payments-upe-blocks-card-payment-method.php +++ /dev/null @@ -1,24 +0,0 @@ -initialize(); - } - - /** - * Initializes the class. - */ - public function initialize() { - $this->name = WC_Payment_Gateway_WCPay::GATEWAY_ID; - $this->gateway = WC_Payments::get_gateway(); - } -} diff --git a/includes/class-wc-payments-upe-blocks-giropay-payment-method.php b/includes/class-wc-payments-upe-blocks-giropay-payment-method.php deleted file mode 100644 index 774fd56e3a7..00000000000 --- a/includes/class-wc-payments-upe-blocks-giropay-payment-method.php +++ /dev/null @@ -1,26 +0,0 @@ -initialize(); - } - - /** - * Initializes the class. - */ - public function initialize() { - $this->name = Giropay_Payment_Method::PAYMENT_METHOD_STRIPE_ID; - $this->gateway = WC_Payments::get_payment_gateway_by_id($this->name); - } -} diff --git a/includes/class-wc-payments-upe-blocks-sepa-payment-method.php b/includes/class-wc-payments-upe-blocks-sepa-payment-method.php deleted file mode 100644 index 534ee7b3e39..00000000000 --- a/includes/class-wc-payments-upe-blocks-sepa-payment-method.php +++ /dev/null @@ -1,26 +0,0 @@ -initialize(); - } - - /** - * Initializes the class. - */ - public function initialize() { - $this->name = Sepa_Payment_Method::PAYMENT_METHOD_STRIPE_ID; - $this->gateway = WC_Payments::get_payment_gateway_by_id($this->name); - } -} From f1c08931deaae6336073e2364a740e7d35c02341 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Thu, 27 Oct 2022 14:43:53 +0200 Subject: [PATCH 11/20] Avoid enqueuing identical scripts and styles twice --- ...ass-wc-payments-upe-blocks-payment-method.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/includes/class-wc-payments-upe-blocks-payment-method.php b/includes/class-wc-payments-upe-blocks-payment-method.php index 91466dbf875..f65be6b9ff1 100644 --- a/includes/class-wc-payments-upe-blocks-payment-method.php +++ b/includes/class-wc-payments-upe-blocks-payment-method.php @@ -16,20 +16,6 @@ class WC_Payments_UPE_Blocks_Payment_Method extends WC_Payments_Blocks_Payment_M */ public function get_payment_method_script_handles() { $classic_blocks_scripts = parent::get_payment_method_script_handles(); - wp_enqueue_style( - 'wc-blocks-checkout-style', - plugins_url( 'dist/upe-blocks-checkout.css', WCPAY_PLUGIN_FILE ), - [], - '1.0' - ); - - wp_register_script( - 'stripe', - 'https://js.stripe.com/v3/', - [], - '3.0', - true - ); wp_register_script( 'WCPAY_BLOCKS_UPE_CHECKOUT', @@ -38,7 +24,7 @@ public function get_payment_method_script_handles() { '1.0.1', true ); - wp_set_script_translations( 'WCPAY_BLOCKS_CHECKOUT', 'woocommerce-payments' ); + wp_set_script_translations( 'WCPAY_BLOCKS_UPE_CHECKOUT', 'woocommerce-payments' ); return array_merge( $classic_blocks_scripts, [ 'WCPAY_BLOCKS_UPE_CHECKOUT' ] ); } From 4993981765686f1f9c6ce046e04cfb814a75774c Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Fri, 28 Oct 2022 12:07:51 +0200 Subject: [PATCH 12/20] Create a changelog file --- changelog/fix-4603-block-split-upe | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelog/fix-4603-block-split-upe diff --git a/changelog/fix-4603-block-split-upe b/changelog/fix-4603-block-split-upe new file mode 100644 index 00000000000..0e77a4db08e --- /dev/null +++ b/changelog/fix-4603-block-split-upe @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Integrate split UPE payments with WooCommerce Blocks From 53e37c973707d8b084153655c4d393439c1ec091 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Fri, 28 Oct 2022 13:46:17 +0200 Subject: [PATCH 13/20] Align a react node responsible for the preview of the method in the editor with the main payment method UI --- client/checkout/blocks/upe.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/checkout/blocks/upe.js b/client/checkout/blocks/upe.js index 7fb729c1569..79d3aa618b0 100644 --- a/client/checkout/blocks/upe.js +++ b/client/checkout/blocks/upe.js @@ -72,7 +72,13 @@ Object.entries( enabledPaymentMethodsConfig ).map( ( [ upeName, upeConfig ] ) => testingInstructions={ upeConfig.testingInstructions } /> ), - edit: , + edit: ( + + ), savedTokenComponent: , canMakePayment: () => !! api.getStripe(), paymentMethodId: upeMethods[ upeName ], From 6304292236505d3f5dd27d040c09250ce00ef989 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Fri, 28 Oct 2022 16:14:35 +0200 Subject: [PATCH 14/20] Apply cosmetic changes to variable names and scopes --- client/checkout/blocks/fields.js | 6 +++--- includes/class-wc-payment-gateway-wcpay.php | 1 - includes/class-wc-payments-blocks-payment-method.php | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/client/checkout/blocks/fields.js b/client/checkout/blocks/fields.js index d0c0f9e5d9a..8e4b0884f7a 100644 --- a/client/checkout/blocks/fields.js +++ b/client/checkout/blocks/fields.js @@ -31,8 +31,8 @@ const WCPayFields = ( { shouldSavePayment, } ) => { const [ errorMessage, setErrorMessage ] = useState( null ); - const testMode = getConfig( 'testMode' ); - const testCopy = ( + const isTestMode = getConfig( 'testMode' ); + const testingInstructions = (

Test mode: use the test VISA card 4242424242424242 with any expiry date and CVC, or any test card numbers listed{ ' ' } @@ -99,7 +99,7 @@ const WCPayFields = ( { return ( <> - { testMode ? testCopy : '' } + { isTestMode ? testingInstructions : '' }

Date: Wed, 2 Nov 2022 14:32:33 +0100 Subject: [PATCH 15/20] Leverage the session storage with created payment intent --- client/checkout/blocks/upe-fields.js | 25 +++++++++++++++++--- client/checkout/classic/upe.js | 35 +++++++--------------------- client/checkout/utils/upe.js | 28 ++++++++++++++++++++++ 3 files changed, 59 insertions(+), 29 deletions(-) diff --git a/client/checkout/blocks/upe-fields.js b/client/checkout/blocks/upe-fields.js index 61aefae10e7..3148a7b9264 100644 --- a/client/checkout/blocks/upe-fields.js +++ b/client/checkout/blocks/upe-fields.js @@ -20,8 +20,8 @@ import { useEffect, useState } from '@wordpress/element'; */ import './style.scss'; import confirmUPEPayment from './confirm-upe-payment.js'; -import { getConfig } from 'utils/checkout'; -import { getTerms } from '../utils/upe'; +import { getConfig, getUPEConfig } from 'utils/checkout'; +import { getTerms, getPaymentIntentFromSession } from '../utils/upe'; import { WC_STORE_CART } from '../constants.js'; import enableStripeLinkPaymentMethod from 'wcpay/checkout/stripe-link'; import { useDispatch, useSelect } from '@wordpress/data'; @@ -366,6 +366,7 @@ const ConsumableWCPayFields = ( { api, ...props } ) => { getConfig( 'wcBlocksUPEAppearance' ) ); const [ fontRules ] = useState( getFontRulesFromPage() ); + const paymentMethodsConfig = getUPEConfig( 'paymentMethodsConfig' ); useEffect( () => { async function generateUPEAppearance() { @@ -396,11 +397,29 @@ const ConsumableWCPayFields = ( { api, ...props } ) => { ); } } + + function getOrCreateIntent( paymentMethodId ) { + const { + intentId, + clientSecret: paymentClientSecret, + } = getPaymentIntentFromSession( + paymentMethodsConfig, + paymentMethodId + ); + if ( ! intentId ) { + createIntent( paymentMethodId ); + } else { + setPaymentIntentId( intentId ); + setClientSecret( paymentClientSecret ); + } + } + setHasRequestedIntent( true ); - createIntent( props.paymentMethodId ); + getOrCreateIntent( props.paymentMethodId ); }, [ props.paymentMethodId, paymentIntentId, + paymentMethodsConfig, hasRequestedIntent, api, errorMessage, diff --git a/client/checkout/classic/upe.js b/client/checkout/classic/upe.js index 351bf2eac91..c34aaad3d10 100644 --- a/client/checkout/classic/upe.js +++ b/client/checkout/classic/upe.js @@ -18,7 +18,11 @@ import { getUPEConfig } from 'utils/checkout'; import WCPayAPI from '../api'; import enqueueFraudScripts from 'fraud-scripts'; import { getFontRulesFromPage, getAppearance } from '../upe-styles'; -import { getTerms, getCookieValue, isWCPayChosen } from '../utils/upe'; +import { + getTerms, + isWCPayChosen, + getPaymentIntentFromSession, +} from '../utils/upe'; import enableStripeLinkPaymentMethod from '../stripe-link'; import apiRequest from '../utils/request'; import showErrorCheckout from '../utils/show-error-checkout'; @@ -230,7 +234,10 @@ jQuery( function ( $ ) { let { intentId, clientSecret } = isSetupIntent ? getSetupIntentFromSession( paymentMethodType ) - : getPaymentIntentFromSession( paymentMethodType ); + : getPaymentIntentFromSession( + paymentMethodsConfig, + paymentMethodType + ); const $upeContainer = $( upeDOMElement ); blockUI( $upeContainer ); @@ -667,30 +674,6 @@ jQuery( function ( $ ) { ); } - /** - * Returns the cached payment intent for the current cart state. - * - * @param {string} paymentMethodType Stripe payment method type ID. - * @return {Object} The intent id and client secret required for mounting the UPE element. - */ - function getPaymentIntentFromSession( paymentMethodType ) { - const cartHash = getCookieValue( 'woocommerce_cart_hash' ); - const upePaymentIntentData = - paymentMethodsConfig[ paymentMethodType ].upePaymentIntentData; - - if ( - cartHash && - upePaymentIntentData && - upePaymentIntentData.startsWith( cartHash ) - ) { - const intentId = upePaymentIntentData.split( '-' )[ 1 ]; - const clientSecret = upePaymentIntentData.split( '-' )[ 2 ]; - return { intentId, clientSecret }; - } - - return {}; - } - /** * Returns the cached setup intent. * diff --git a/client/checkout/utils/upe.js b/client/checkout/utils/upe.js index 8dabb9500b4..e5cba6529ab 100644 --- a/client/checkout/utils/upe.js +++ b/client/checkout/utils/upe.js @@ -36,3 +36,31 @@ export const isWCPayChosen = function () { return document.getElementById( 'payment_method_woocommerce_payments' ) .checked; }; + +/** + * Returns the cached payment intent for the current cart state. + * + * @param {Object} paymentMethodsConfig Array of configs for payment methods. + * @param {string} paymentMethodType Type of the payment method. + * @return {Object} The intent id and client secret required for mounting the UPE element. + */ +export const getPaymentIntentFromSession = ( + paymentMethodsConfig, + paymentMethodType +) => { + const cartHash = getCookieValue( 'woocommerce_cart_hash' ); + const upePaymentIntentData = + paymentMethodsConfig[ paymentMethodType ].upePaymentIntentData; + + if ( + cartHash && + upePaymentIntentData && + upePaymentIntentData.startsWith( cartHash ) + ) { + const intentId = upePaymentIntentData.split( '-' )[ 1 ]; + const clientSecret = upePaymentIntentData.split( '-' )[ 2 ]; + return { intentId, clientSecret }; + } + + return {}; +}; From 7dd6bfe783f9b8556710533e1df893c0fd2dc8d0 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Wed, 2 Nov 2022 18:04:34 +0100 Subject: [PATCH 16/20] Align the definition of method responsible for supplying testing instructions text --- client/checkout/blocks/upe-fields.js | 5 +++-- includes/payment-methods/class-bancontact-payment-method.php | 4 ++-- includes/payment-methods/class-becs-payment-method.php | 2 +- includes/payment-methods/class-cc-payment-method.php | 2 +- includes/payment-methods/class-eps-payment-method.php | 4 ++-- includes/payment-methods/class-giropay-payment-method.php | 4 ++-- includes/payment-methods/class-ideal-payment-method.php | 4 ++-- includes/payment-methods/class-link-payment-method.php | 4 ++-- includes/payment-methods/class-p24-payment-method.php | 4 ++-- includes/payment-methods/class-sepa-payment-method.php | 2 +- includes/payment-methods/class-sofort-payment-method.php | 4 ++-- includes/payment-methods/class-upe-payment-method.php | 2 +- 12 files changed, 21 insertions(+), 20 deletions(-) diff --git a/client/checkout/blocks/upe-fields.js b/client/checkout/blocks/upe-fields.js index 3148a7b9264..fc25a40aea2 100644 --- a/client/checkout/blocks/upe-fields.js +++ b/client/checkout/blocks/upe-fields.js @@ -81,8 +81,9 @@ const WCPayUPEFields = ( { const paymentMethodsConfig = getConfig( 'paymentMethodsConfig' ); const isTestMode = getConfig( 'testMode' ); - const testingInstructionsIfAppropriate = - isTestMode && false !== testingInstructions ? testingInstructions : ''; + const testingInstructionsIfAppropriate = isTestMode + ? testingInstructions + : ''; const gatewayConfig = getPaymentMethods()[ paymentMethodId ]; const customerData = useCustomerData(); diff --git a/includes/payment-methods/class-bancontact-payment-method.php b/includes/payment-methods/class-bancontact-payment-method.php index 269dd3611fc..aa936112f2a 100644 --- a/includes/payment-methods/class-bancontact-payment-method.php +++ b/includes/payment-methods/class-bancontact-payment-method.php @@ -33,10 +33,10 @@ public function __construct( $token_service ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { - return false; + return ''; } } diff --git a/includes/payment-methods/class-becs-payment-method.php b/includes/payment-methods/class-becs-payment-method.php index 61eef6b91a6..305537643f1 100644 --- a/includes/payment-methods/class-becs-payment-method.php +++ b/includes/payment-methods/class-becs-payment-method.php @@ -33,7 +33,7 @@ public function __construct( $token_service ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { return __( 'Test mode: use the test account number 000123456. Other payment methods may redirect to a Stripe test page to authorize payment. More test card numbers are listed here.', 'woocommerce-payments' ); diff --git a/includes/payment-methods/class-cc-payment-method.php b/includes/payment-methods/class-cc-payment-method.php index c8ac9d682e0..8511d1453d1 100644 --- a/includes/payment-methods/class-cc-payment-method.php +++ b/includes/payment-methods/class-cc-payment-method.php @@ -63,7 +63,7 @@ public function get_title( $payment_details = false ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { return __( 'Test mode: use the test VISA card 4242424242424242 with any expiry date and CVC. Other payment methods may redirect to a Stripe test page to authorize payment. More test card numbers are listed here.', 'woocommerce-payments' ); diff --git a/includes/payment-methods/class-eps-payment-method.php b/includes/payment-methods/class-eps-payment-method.php index 64da91bfde7..f4edea97f1c 100644 --- a/includes/payment-methods/class-eps-payment-method.php +++ b/includes/payment-methods/class-eps-payment-method.php @@ -33,9 +33,9 @@ public function __construct( $token_service ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { - return false; + return ''; } } diff --git a/includes/payment-methods/class-giropay-payment-method.php b/includes/payment-methods/class-giropay-payment-method.php index 97f24399fc0..1dfce93aa4a 100644 --- a/includes/payment-methods/class-giropay-payment-method.php +++ b/includes/payment-methods/class-giropay-payment-method.php @@ -33,9 +33,9 @@ public function __construct( $token_service ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { - return false; + return ''; } } diff --git a/includes/payment-methods/class-ideal-payment-method.php b/includes/payment-methods/class-ideal-payment-method.php index b562202ea77..1a642e612aa 100644 --- a/includes/payment-methods/class-ideal-payment-method.php +++ b/includes/payment-methods/class-ideal-payment-method.php @@ -33,9 +33,9 @@ public function __construct( $token_service ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { - return false; + return ''; } } diff --git a/includes/payment-methods/class-link-payment-method.php b/includes/payment-methods/class-link-payment-method.php index 4c02af48e7e..23943f16309 100644 --- a/includes/payment-methods/class-link-payment-method.php +++ b/includes/payment-methods/class-link-payment-method.php @@ -33,9 +33,9 @@ public function __construct( $token_service ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { - return false; + return ''; } } diff --git a/includes/payment-methods/class-p24-payment-method.php b/includes/payment-methods/class-p24-payment-method.php index 8e95225307e..abb51b47e71 100644 --- a/includes/payment-methods/class-p24-payment-method.php +++ b/includes/payment-methods/class-p24-payment-method.php @@ -33,9 +33,9 @@ public function __construct( $token_service ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { - return false; + return ''; } } diff --git a/includes/payment-methods/class-sepa-payment-method.php b/includes/payment-methods/class-sepa-payment-method.php index 0b3fb6a9a25..eef834296ed 100644 --- a/includes/payment-methods/class-sepa-payment-method.php +++ b/includes/payment-methods/class-sepa-payment-method.php @@ -33,7 +33,7 @@ public function __construct( $token_service ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { return __( 'Test mode: use the test account number AT611904300234573201. Other payment methods may redirect to a Stripe test page to authorize payment. More test card numbers are listed here.', 'woocommerce-payments' ); diff --git a/includes/payment-methods/class-sofort-payment-method.php b/includes/payment-methods/class-sofort-payment-method.php index 2d9b9c2f617..a9d254d107f 100644 --- a/includes/payment-methods/class-sofort-payment-method.php +++ b/includes/payment-methods/class-sofort-payment-method.php @@ -34,9 +34,9 @@ public function __construct( $token_service ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ public function get_testing_instructions() { - return false; + return ''; } } diff --git a/includes/payment-methods/class-upe-payment-method.php b/includes/payment-methods/class-upe-payment-method.php index 556da212f01..583a405567a 100644 --- a/includes/payment-methods/class-upe-payment-method.php +++ b/includes/payment-methods/class-upe-payment-method.php @@ -151,7 +151,7 @@ public function get_payment_token_for_user( $user, $payment_method_id ) { /** * Returns testing credentials to be printed at checkout in test mode. * - * @return string|bool + * @return string */ abstract public function get_testing_instructions(); From f208c9edd9a9c081e1e682a2ae1d00d3251e8c55 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Mon, 7 Nov 2022 12:25:10 +0100 Subject: [PATCH 17/20] Update the state with paymentIntent to avoid a recurring intent creation --- client/checkout/blocks/upe-fields.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/client/checkout/blocks/upe-fields.js b/client/checkout/blocks/upe-fields.js index fc25a40aea2..6e36d6b98de 100644 --- a/client/checkout/blocks/upe-fields.js +++ b/client/checkout/blocks/upe-fields.js @@ -21,7 +21,11 @@ import { useEffect, useState } from '@wordpress/element'; import './style.scss'; import confirmUPEPayment from './confirm-upe-payment.js'; import { getConfig, getUPEConfig } from 'utils/checkout'; -import { getTerms, getPaymentIntentFromSession } from '../utils/upe'; +import { + getTerms, + getPaymentIntentFromSession, + getCookieValue, +} from '../utils/upe'; import { WC_STORE_CART } from '../constants.js'; import enableStripeLinkPaymentMethod from 'wcpay/checkout/stripe-link'; import { useDispatch, useSelect } from '@wordpress/data'; @@ -388,6 +392,17 @@ const ConsumableWCPayFields = ( { api, ...props } ) => { async function createIntent( paymentMethodId ) { try { const response = await api.createIntent( paymentMethodId ); + const cartHash = getCookieValue( 'woocommerce_cart_hash' ); + if ( cartHash ) { + paymentMethodsConfig[ + paymentMethodId + ].upePaymentIntentData = + cartHash + + '-' + + response.id + + '-' + + response.client_secret; + } setPaymentIntentId( response.id ); setClientSecret( response.client_secret ); } catch ( error ) { From c16cfec392a41b1328280bb1b6d8159c323c22c2 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Tue, 8 Nov 2022 03:49:24 +0100 Subject: [PATCH 18/20] Align method invocation with its definition --- client/checkout/classic/upe.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/checkout/classic/upe.js b/client/checkout/classic/upe.js index c34aaad3d10..90dbab2ed65 100644 --- a/client/checkout/classic/upe.js +++ b/client/checkout/classic/upe.js @@ -704,6 +704,7 @@ jQuery( function ( $ ) { return upeComponents.paymentIntentClientSecret; } const { clientSecret } = getPaymentIntentFromSession( + paymentMethodsConfig, paymentMethodType ); return clientSecret ? clientSecret : null; From e3ceb21160673b1145a513fc0b5ed071b352c2e0 Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Tue, 8 Nov 2022 03:49:54 +0100 Subject: [PATCH 19/20] Get rid of the changelog file due to the nature of changes --- changelog/fix-4603-block-split-upe | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 changelog/fix-4603-block-split-upe diff --git a/changelog/fix-4603-block-split-upe b/changelog/fix-4603-block-split-upe deleted file mode 100644 index 0e77a4db08e..00000000000 --- a/changelog/fix-4603-block-split-upe +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix - -Integrate split UPE payments with WooCommerce Blocks From f17d4a478ef180248d1ec0ec9f45b30c80b8223f Mon Sep 17 00:00:00 2001 From: Timur Karimov Date: Tue, 8 Nov 2022 16:12:10 +0100 Subject: [PATCH 20/20] Make sure callbacks are added to hooks for non-card payment methods in blocks --- .../class-upe-payment-gateway.php | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/includes/payment-methods/class-upe-payment-gateway.php b/includes/payment-methods/class-upe-payment-gateway.php index 86db2eaf2fc..7fc60180be3 100644 --- a/includes/payment-methods/class-upe-payment-gateway.php +++ b/includes/payment-methods/class-upe-payment-gateway.php @@ -105,18 +105,41 @@ public function __construct( if ( 'card' !== $this->stripe_id ) { $this->id = self::GATEWAY_ID . '_' . $this->stripe_id; $this->method_title = "WooCommerce Payments ($this->title)"; - } else { - // Only add these filters once. + } + + if ( ! has_action( 'wc_ajax_wcpay_log_payment_error', [ $this, 'log_payment_error_ajax' ] ) ) { add_action( 'wc_ajax_wcpay_log_payment_error', [ $this, 'log_payment_error_ajax' ] ); + } + + if ( ! has_action( 'wp_ajax_save_upe_appearance', [ $this, 'save_upe_appearance_ajax' ] ) ) { add_action( 'wp_ajax_save_upe_appearance', [ $this, 'save_upe_appearance_ajax' ] ); + } + + if ( ! has_action( 'wp_ajax_nopriv_save_upe_appearance', [ $this, 'save_upe_appearance_ajax' ] ) ) { add_action( 'wp_ajax_nopriv_save_upe_appearance', [ $this, 'save_upe_appearance_ajax' ] ); + } + + if ( ! has_action( 'switch_theme', [ $this, 'clear_upe_appearance_transient' ] ) ) { add_action( 'switch_theme', [ $this, 'clear_upe_appearance_transient' ] ); + } + + if ( ! has_action( 'woocommerce_woocommerce_payments_updated', [ $this, 'clear_upe_appearance_transient' ] ) ) { add_action( 'woocommerce_woocommerce_payments_updated', [ $this, 'clear_upe_appearance_transient' ] ); + } + if ( ! has_action( 'wp', [ $this, 'maybe_process_upe_redirect' ] ) ) { add_action( 'wp', [ $this, 'maybe_process_upe_redirect' ] ); + } + if ( ! has_action( 'woocommerce_order_payment_status_changed', [ __CLASS__, 'remove_upe_payment_intent_from_session' ] ) ) { add_action( 'woocommerce_order_payment_status_changed', [ __CLASS__, 'remove_upe_payment_intent_from_session' ], 10, 0 ); + } + + if ( ! has_action( 'woocommerce_after_account_payment_methods', [ $this, 'remove_upe_setup_intent_from_session' ] ) ) { add_action( 'woocommerce_after_account_payment_methods', [ $this, 'remove_upe_setup_intent_from_session' ], 10, 0 ); + } + + if ( ! has_action( 'woocommerce_subscription_payment_method_updated', [ $this, 'remove_upe_setup_intent_from_session' ] ) ) { add_action( 'woocommerce_subscription_payment_method_updated', [ $this, 'remove_upe_setup_intent_from_session' ], 10, 0 ); } }