Skip to content

Commit

Permalink
Drafting implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
wjrosa committed Feb 28, 2025
1 parent cae6275 commit 6b10104
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 19 deletions.
20 changes: 15 additions & 5 deletions client/blocks/upe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
} from 'wcstripe/blocks/utils';
import './styles.scss';
import { groupedCheckoutElement } from 'wcstripe/blocks/upe/grouped-checkout-element';
import { singleCheckoutElement } from 'wcstripe/blocks/upe/single-checkout-element';

const api = new WCStripeAPI(
getBlocksConfiguration(),
Expand All @@ -42,11 +43,20 @@ const methodsToFilter = [
];

// Register UPE Elements.
Object.entries( paymentMethodsConfig )
.filter( ( [ method ] ) => ! methodsToFilter.includes( method ) )
.forEach( ( [ method, config ] ) => {
registerPaymentMethod( groupedCheckoutElement( method, api, config ) );
} );
if ( true ) {
// @todo replace with feature flag
registerPaymentMethod(
singleCheckoutElement( api, paymentMethodsConfig.card )
);
} else {
Object.entries( paymentMethodsConfig )
.filter( ( [ method ] ) => ! methodsToFilter.includes( method ) )
.forEach( ( [ method, config ] ) => {
registerPaymentMethod(
groupedCheckoutElement( method, api, config )
);
} );
}

// Register Express Checkout Elements.
if (
Expand Down
97 changes: 97 additions & 0 deletions client/blocks/upe/single-checkout-element.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { PaymentElements } from 'wcstripe/blocks/upe/upe-deferred-intent-creation/payment-elements';
import { SavedTokenHandler } from 'wcstripe/blocks/upe/saved-token-handler';
import {
getPaymentMethodsConstants,
PAYMENT_METHOD_CARD,
} from 'wcstripe/stripe-utils/constants';
import { getBlocksConfiguration } from 'wcstripe/blocks/utils';
import Icons from 'wcstripe/payment-method-icons';
import { initializeCheckoutIcons } from 'wcstripe/blocks/upe/checkout-icons';
import WCStripeAPI from 'wcstripe/api';
import PaymentProcessor from 'wcstripe/blocks/upe/upe-deferred-intent-creation/payment-processor';

// Initialize checkout icons
const isAdmin = getBlocksConfiguration()?.isAdmin ?? false;
const checkoutIcons = initializeCheckoutIcons( isAdmin );

const upeMethods = getPaymentMethodsConstants();

/**
* Returns the UPE payment method element for registration.
*
* @param {WCStripeAPI} api The Stripe API object.
* @param {Object} upeConfig The UPE configuration.
* @return {Object} The UPE payment method configuration.
*/
export const singleCheckoutElement = ( api, upeConfig ) => {
const iconName = PAYMENT_METHOD_CARD;

// Use checkout icons if available, otherwise fallback to default Icons
const Icon =
( checkoutIcons && checkoutIcons[ iconName ] ) || Icons[ iconName ];
const supports = {
// Use `false` as fallback values in case server provided configuration is missing.
showSavedCards: getBlocksConfiguration()?.showSavedCards ?? false,
showSaveOption: upeConfig.showSaveOption ?? false,
features: getBlocksConfiguration()?.supports ?? [],
};
if ( getBlocksConfiguration().isAdmin ?? false ) {
supports.style = getBlocksConfiguration()?.style ?? [];
}

return {
name: upeMethods[ PAYMENT_METHOD_CARD ],
content: <GeneralElement api={ api } upeConfig={ upeConfig } />,
edit: <GeneralElement api={ api } upeConfig={ upeConfig } />,
savedTokenComponent: <SavedTokenHandler api={ api } />,
canMakePayment: ( cartData ) => {
const billingCountry = cartData.billingAddress.country;
const isRestrictedInAnyCountry = !! upeConfig.countries.length;
const isAvailableInTheCountry =
! isRestrictedInAnyCountry ||
upeConfig.countries.includes( billingCountry );

return isAvailableInTheCountry && !! api.getStripe();
},
// see .wc-block-checkout__payment-method styles in blocks/style.scss
label: (
<>
<span>
{ upeConfig.title }
<Icon alt={ upeConfig.title } />
</span>
</>
),
ariaLabel: 'Stripe',
supports,
};
};

/**
* Get the general element for the UPE.
*
* @param {*} props The props.
* @param {WCStripeAPI} props.api The Stripe API object.
* @param {Object} props.upeConfig The UPE configuration.
* @return {JSX.Element} The general element for the UPE.
*/
const GeneralElement = ( { api, upeConfig, ...props } ) => {
return (
<PaymentElements
api={ api }
paymentMethodId={ PAYMENT_METHOD_CARD }
showSaveOption={ upeConfig.showSaveOption ?? false }
supportsDeferredIntent={ upeConfig.supportsDeferredIntent }
{ ...props }
>
<PaymentProcessor
api={ api }
description={ upeConfig.description }
testingInstructions={ upeConfig.testingInstructions }
paymentMethodId={ PAYMENT_METHOD_CARD }
upeMethods={ upeMethods }
{ ...props }
/>
</PaymentElements>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,6 @@ export const PaymentElements = ( {

// Build options object.
const options = {
appearance,
paymentMethodCreation: 'manual',
fonts: getFontRulesFromPage(),
...( supportsDeferredIntent
? {
mode: amount < 1 ? 'setup' : 'payment',
Expand All @@ -105,12 +102,6 @@ export const PaymentElements = ( {
),
}
: { clientSecret } ),
// If the cart contains a subscription or the payment method supports saving, we need to use off_session setup so Stripe can display appropriate terms and conditions.
...( supportsDeferredIntent &&
( getBlocksConfiguration()?.cartContainsSubscription ||
showSaveOption ) && {
setupFutureUsage: 'off_session',
} ),
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,7 @@ const PaymentProcessor = ( {
__html: testingInstructionsIfAppropriate,
} }
/>
<PaymentElement
options={ getStripeElementOptions() }
onChange={ onSelectedPaymentMethodChange }
className="wcstripe-payment-element"
/>
<PaymentElement />
</>
);
};
Expand Down

0 comments on commit 6b10104

Please sign in to comment.