Skip to content

Commit

Permalink
Implement PE with deferred intent for the card payment method in the …
Browse files Browse the repository at this point in the history
…classic checkout (#2753)

* Separate adding hooks from the constructor for WC_Stripe_Intent_Controller

* Make wc-stripe-upe-element a class instead of an id

* Render the Payment element in the classic checkout page without creating an intention

* Process payments with deferred intent in the classic checkout

* Fix expected dom element in unit tests

* Update process_payment_with_deferred_intent

* Add base uni test for PE with deferred intent processing

* Move some logic out of create_and_confirm_payment_intent

* Add validation for the payment information array

* Update unit tests for processing payments with a deferred intent

* Improve the error messaging on processing failures

* Remove unneeded test

* Fix typo in doc block

Co-authored-by: Matt Allan <matttallan@gmail.com>

* Remove resolved TODO comment

* Use the order currency instead of the store currency when creating an intent

Co-authored-by: Matt Allan <matttallan@gmail.com>

* Remove inline TODO comments that already have issues to address them

* Remove unnecesary order status assignment

* Remove TODO that will be addressed in a separate issue

* Set the selected payment method type as the order's payment method title

* Include shipping information for the payment intent when shipping is needed

* Pass the appearance and fonts parameters to the Elements initialization object

* Validate whether the provided payment method type is valid and allowed in the selected country

* Check whether the dom elements exist before changing their attributes

* Fix console error when checking out as a guest

* Adjust unit tests

---------

Co-authored-by: Matt Allan <matttallan@gmail.com>
  • Loading branch information
a-danae and mattallan authored Nov 27, 2023
1 parent 0b490e8 commit b672036
Show file tree
Hide file tree
Showing 9 changed files with 1,167 additions and 30 deletions.
59 changes: 59 additions & 0 deletions client/classic/upe/deferred-intent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import jQuery from 'jquery';
import WCStripeAPI from '../../api';
import {
generateCheckoutEventNames,
getSelectedUPEGatewayPaymentMethod,
getStripeServerData,
isUsingSavedPaymentMethod,
} from '../../stripe-utils';
import './style.scss';
import {
processPayment,
mountStripePaymentElement,
} from './payment-processing';

jQuery( function ( $ ) {
// Create an API object, which will be used throughout the checkout.
const api = new WCStripeAPI(
getStripeServerData(),
// A promise-based interface to jQuery.post.
( url, args ) => {
return new Promise( ( resolve, reject ) => {
jQuery.post( url, args ).then( resolve ).fail( reject );
} );
}
);

// Only attempt to mount the card element once that section of the page has loaded.
// We can use the updated_checkout event for this.
$( document.body ).on( 'updated_checkout', () => {
maybeMountStripePaymentElement();
} );

$( 'form.checkout' ).on( generateCheckoutEventNames(), function () {
return processPaymentIfNotUsingSavedMethod( $( this ) );
} );

function processPaymentIfNotUsingSavedMethod( $form ) {
const paymentMethodType = getSelectedUPEGatewayPaymentMethod();
if ( ! isUsingSavedPaymentMethod( paymentMethodType ) ) {
return processPayment( api, $form, paymentMethodType );
}
}

// If the card element selector doesn't exist, then do nothing.
// For example, when a 100% discount coupon is applied).
// We also don't re-mount if already mounted in DOM.
async function maybeMountStripePaymentElement() {
if (
$( '.wc-stripe-upe-element' ).length &&
! $( '.wc-stripe-upe-element' ).children().length
) {
for ( const upeElement of $(
'.wc-stripe-upe-element'
).toArray() ) {
await mountStripePaymentElement( api, upeElement );
}
}
}
} );
29 changes: 6 additions & 23 deletions client/classic/upe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { getFontRulesFromPage, getAppearance } from '../../styles/upe';
import enableStripeLinkPaymentMethod from '../../stripe-link';
import { legacyHashchangeHandler } from './legacy-support';
import './style.scss';
import './deferred-intent.js';

jQuery( function ( $ ) {
const key = getStripeServerData()?.key;
Expand Down Expand Up @@ -200,7 +201,7 @@ jQuery( function ( $ ) {
// Do not recreate UPE element unnecessarily.
if ( upeElement ) {
upeElement.unmount();
upeElement.mount( '#wc-stripe-upe-element' );
upeElement.mount( '.wc-stripe-upe-element' );
return;
}

Expand All @@ -221,7 +222,7 @@ jQuery( function ( $ ) {
// I repeat, do NOT recreate UPE element unnecessarily.
if ( upeElement || paymentIntentId ) {
upeElement.unmount();
upeElement.mount( '#wc-stripe-upe-element' );
upeElement.mount( '.wc-stripe-upe-element' );
return;
}

Expand Down Expand Up @@ -302,7 +303,7 @@ jQuery( function ( $ ) {
}

upeElement = elements.create( 'payment', upeSettings );
upeElement.mount( '#wc-stripe-upe-element' );
upeElement.mount( '.wc-stripe-upe-element' );

upeElement.on( 'ready', () => {
unblockUI( $( upeLoadingSelector ) );
Expand Down Expand Up @@ -339,31 +340,13 @@ jQuery( function ( $ ) {
} );
};

// Only attempt to mount the card element once that section of the page has loaded. We can use the updated_checkout
// event for this. This part of the page can also reload based on changes to checkout details, so we call unmount
// first to ensure the card element is re-mounted correctly.
$( document.body ).on( 'updated_checkout', () => {
// If the card element selector doesn't exist, then do nothing (for example, when a 100% discount coupon is applied).
// We also don't re-mount if already mounted in DOM.
if (
$( '#wc-stripe-upe-element' ).length &&
! $( '#wc-stripe-upe-element' ).children().length &&
isUPEEnabled
) {
const isSetupIntent = ! (
getStripeServerData()?.isPaymentNeeded ?? true
);
mountUPEElement( isSetupIntent );
}
} );

if (
$( 'form#add_payment_method' ).length ||
$( 'form#order_review' ).length
) {
if (
$( '#wc-stripe-upe-element' ).length &&
! $( '#wc-stripe-upe-element' ).children().length &&
$( '.wc-stripe-upe-element' ).length &&
! $( '.wc-stripe-upe-element' ).children().length &&
isUPEEnabled &&
! upeElement
) {
Expand Down
Loading

0 comments on commit b672036

Please sign in to comment.