Skip to content

Commit

Permalink
Merge branch 'develop' into fix/8029-prb-invalid-recurring-shipping-m…
Browse files Browse the repository at this point in the history
…ethod
  • Loading branch information
mattallan authored Apr 12, 2024
2 parents 512f612 + 78409e7 commit 271e25f
Show file tree
Hide file tree
Showing 29 changed files with 493 additions and 59 deletions.
4 changes: 4 additions & 0 deletions changelog/8143-add-bnpl-pmme-to-checkout-radio-buttons
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Add BNPL terms to checkout payment methods.
5 changes: 5 additions & 0 deletions changelog/cart-pmme-total-updates
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: add
Comment: Adding skeleton component to BNPL messaging on cart page which has not yet been deployed.


5 changes: 5 additions & 0 deletions changelog/chore-remove-unused-use-statements-in-tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: dev
Comment: chore: remove unused use statement in tests


4 changes: 4 additions & 0 deletions changelog/dev-track-account-management-links
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: update

Adding a tracking event for external redirects to update account details, more consistent behaviour for redirects.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fix

Ensure that the currency configurations are set correctly when multi-currency is enabled.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fix

Ensure we avoid an infinite recursive call stack through 'wc_get_price_decimal_separator' filter.
21 changes: 21 additions & 0 deletions client/checkout/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,4 +533,25 @@ export default class WCPayAPI {
...paymentData,
} );
}

/**
* Fetches the cart data from the woocommerce store api.
*
* @return {Object} JSON data.
* @throws Error if the response is not ok.
*/
pmmeGetCartData() {
return fetch( `${ getUPEConfig( 'storeApiURL' ) }/cart`, {
method: 'GET',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
} ).then( ( response ) => {
if ( ! response.ok ) {
throw new Error( response.statusText );
}
return response.json();
} );
}
}
24 changes: 11 additions & 13 deletions client/checkout/blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { getUPEConfig } from 'utils/checkout';
import { isLinkEnabled } from '../utils/upe';
import WCPayAPI from '../api';
import { SavedTokenHandler } from './saved-token-handler';
import PaymentMethodLabel from './payment-method-label';
import request from '../utils/request';
import enqueueFraudScripts from 'fraud-scripts';
import paymentRequestPaymentMethod from '../../payment-request/blocks';
Expand Down Expand Up @@ -68,6 +69,9 @@ const api = new WCPayAPI(
},
request
);

const stripeAppearance = getUPEConfig( 'wcBlocksUPEAppearance' );

Object.entries( enabledPaymentMethodsConfig )
.filter( ( [ upeName ] ) => upeName !== 'link' )
.forEach( ( [ upeName, upeConfig ] ) => {
Expand Down Expand Up @@ -99,19 +103,13 @@ Object.entries( enabledPaymentMethodsConfig )
paymentMethodId: upeMethods[ upeName ],
// see .wc-block-checkout__payment-method styles in blocks/style.scss
label: (
<>
<span>
{ upeConfig.title }
<img
src={
upeAppearanceTheme === 'night'
? upeConfig.darkIcon
: upeConfig.icon
}
alt={ upeConfig.title }
/>
</span>
</>
<PaymentMethodLabel
api={ api }
upeConfig={ upeConfig }
upeName={ upeName }
stripeAppearance={ stripeAppearance }
upeAppearanceTheme={ upeAppearanceTheme }
/>
),
ariaLabel: 'WooPayments',
supports: {
Expand Down
71 changes: 71 additions & 0 deletions client/checkout/blocks/payment-method-label.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Internal dependencies
*/
import {
Elements,
PaymentMethodMessagingElement,
} from '@stripe/react-stripe-js';
import { normalizeCurrencyToMinorUnit } from '../utils';

export default ( {
api,
upeConfig,
upeName,
stripeAppearance,
upeAppearanceTheme,
} ) => {
const cartData = wp.data.select( 'wc/store/cart' ).getCartData();

// Stripe expects the amount to be sent as the minor unit of 2 digits.
const amount = normalizeCurrencyToMinorUnit(
cartData.totals.total_price,
cartData.totals.currency_minor_unit
);

// Customer's country or base country of the store.
const currentCountry =
cartData.billingAddress.country ||
window.wcBlocksCheckoutData.storeCountry;

// console.log( currentCountry );

return (
<>
<span>
{ upeConfig.title }
{ upeName !== 'card' &&
( upeConfig.countries.length === 0 ||
upeConfig.countries.includes( currentCountry ) ) && (
<>
<Elements
stripe={ api.getStripeForUPE( upeName ) }
options={ {
appearance: stripeAppearance ?? {},
} }
>
<PaymentMethodMessagingElement
options={ {
amount: parseInt( amount, 10 ) || 0,
currency:
cartData.totals.currency_code ||
'USD',
paymentMethodTypes: [ upeName ],
countryCode: currentCountry,
displayType: 'promotional_text',
} }
/>
</Elements>
</>
) }
<img
src={
upeAppearanceTheme === 'night'
? upeConfig.darkIcon
: upeConfig.icon
}
alt={ upeConfig.title }
/>
</span>
</>
);
};
36 changes: 29 additions & 7 deletions client/checkout/blocks/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,42 @@ button.wcpay-stripelink-modal-trigger:hover {
span {
width: 95%;

img {
float: right;
&:has( .StripeElement ) {
display: grid;
grid-template-columns: 1fr auto;
}
}

#payment-method {
label img {
img {
float: right;
border: 0;
padding: 0;
max-height: 1.618em;
min-height: 30px;
height: 24px;
max-height: 24px;
}

.StripeElement {
width: 100%;
grid-column: 1 / span 2;
grid-row-start: 2;
pointer-events: none;

+ img {
grid-row: 1 / span 2;
grid-column: 2;
}
}
}

#payment-method {
label.wc-block-components-radio-control__option-checked {
.StripeElement {
display: none;
}
img {
grid-column: 2;
grid-row: 1;
}
}
/* stylelint-disable-next-line selector-id-pattern */
#radio-control-wc-payment-method-options-woocommerce_payments_affirm__label
img {
Expand Down
57 changes: 57 additions & 0 deletions client/checkout/classic/event-handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import {
processPayment,
mountStripePaymentElement,
mountStripePaymentMethodMessagingElement,
renderTerms,
createAndConfirmSetupIntent,
maybeEnableStripeLink,
Expand Down Expand Up @@ -69,6 +70,7 @@ jQuery( function ( $ ) {

$( document.body ).on( 'updated_checkout', () => {
maybeMountStripePaymentElement();
injectStripePMMEContainers();
} );

$checkoutForm.on( generateCheckoutEventNames(), function () {
Expand Down Expand Up @@ -150,6 +152,61 @@ jQuery( function ( $ ) {
handleWooPayEmailInput( '#billing_email', api );
}

async function injectStripePMMEContainers() {
const bnplMethods = [ 'affirm', 'afterpay_clearpay', 'klarna' ];
const labelBase = 'payment_method_woocommerce_payments_';
const paymentMethods = getUPEConfig( 'paymentMethodsConfig' );
const paymentMethodsKeys = Object.keys( paymentMethods );
const cartData = await api.pmmeGetCartData();

for ( const method of paymentMethodsKeys ) {
if ( bnplMethods.includes( method ) ) {
const targetLabel = document.querySelector(
`label[for="${ labelBase }${ method }"]`
);
const containerID = `stripe-pmme-container-${ method }`;

if ( document.getElementById( containerID ) ) {
document.getElementById( containerID ).innerHTML = '';
}

if ( targetLabel ) {
let container = document.getElementById( containerID );
if ( ! container ) {
container = document.createElement( 'span' );
container.id = containerID;
container.dataset.paymentMethodType = method;
container.classList.add( 'stripe-pmme-container' );
targetLabel.appendChild( container );
}

const currentCountry =
cartData?.billing_address?.country ||
getUPEConfig( 'storeCountry' );

if (
paymentMethods[ method ]?.countries.length === 0 ||
paymentMethods[ method ]?.countries?.includes(
currentCountry
)
) {
await mountStripePaymentMethodMessagingElement(
api,
container,
{
amount: cartData?.totals?.total_price,
currency: cartData?.totals?.currency_code,
decimalPlaces:
cartData?.totals?.currency_minor_unit,
country: currentCountry,
}
);
}
}
}
}
}

function processPaymentIfNotUsingSavedMethod( $form ) {
const paymentMethodType = getSelectedUPEGatewayPaymentMethod();
if ( ! isUsingSavedPaymentMethod( paymentMethodType ) ) {
Expand Down
34 changes: 34 additions & 0 deletions client/checkout/classic/payment-processing.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import { getUPEConfig } from 'wcpay/utils/checkout';
import { getAppearance, getFontRulesFromPage } from '../upe-styles';
import { normalizeCurrencyToMinorUnit } from 'wcpay/checkout/utils';
import showErrorCheckout from 'wcpay/checkout/utils/show-error-checkout';
import {
appendFingerprintInputToForm,
Expand Down Expand Up @@ -401,6 +402,39 @@ export async function mountStripePaymentElement( api, domElement ) {
upeElement.mount( domElement );
}

export async function mountStripePaymentMethodMessagingElement(
api,
domElement,
cartData
) {
const paymentMethodType = domElement.dataset.paymentMethodType;
const appearance = await initializeAppearance( api );

try {
const paymentMethodMessagingElement = api
.getStripe()
.elements( {
appearance: appearance,
fonts: getFontRulesFromPage(),
} )
.create( 'paymentMethodMessaging', {
currency: cartData.currency,
amount: normalizeCurrencyToMinorUnit(
cartData.amount,
cartData.decimalPlaces
),
countryCode: cartData.country, // Customer's country or base country of the store.
paymentMethodTypes: [ paymentMethodType ],
displayType: 'promotional_text',
} );

return paymentMethodMessagingElement.mount( domElement );
} finally {
// Resolve the promise even if the element mounting fails.
return Promise.resolve();
}
}

/**
* Creates and confirms a setup intent using the provided ID, then appends the confirmed setup intent to the given jQuery form.
*
Expand Down
Loading

0 comments on commit 271e25f

Please sign in to comment.