Skip to content

Commit

Permalink
Fix missing order attribution metadata when using ECE (#3629)
Browse files Browse the repository at this point in the history
* Fix missing order attribution metadata when using ECE

* Adding order attribution fields to block checkout

* Adding order attribution fields to PRB

* Add order attribution data to ECE

* Adding inputs only when they don't exist

* Moving logic to a new method

* Fix order attribution for PRB

* Move method to shared file

* Moving order attribution inputs creation to a shared trait

* Fix include

* Fix data not being sent for shortcode PRB

* Removing unnecessary trait

* Changelog and readme entries

* Reverting unnecessary changes

* Reverting unnecessary changes

* Adding specific unit tests

* Adding specific unit tests

* Adding specific unit tests

* Fix block checkout attribution
  • Loading branch information
wjrosa authored Dec 2, 2024
1 parent c3e261c commit 7779798
Show file tree
Hide file tree
Showing 11 changed files with 192 additions and 5 deletions.
22 changes: 20 additions & 2 deletions assets/js/stripe-payment-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ jQuery( function( $ ) {

data = wc_stripe_payment_request.getRequiredFieldDataFromCheckoutForm( data );

return data;
return { ...data, ...wc_stripe_payment_request.extractOrderAttributionData() };
},

/**
Expand Down Expand Up @@ -173,7 +173,7 @@ jQuery( function( $ ) {
if ( ! data[ name ] ) {
data[ name ] = value;
}

// if shipping same as billing is selected, copy the billing field to shipping field.
const shipToDiffAddress = $( '#ship-to-different-address' ).find( 'input' ).is( ':checked' );
if ( ! shipToDiffAddress ) {
Expand Down Expand Up @@ -833,6 +833,24 @@ jQuery( function( $ ) {
} );
},

/**
* Get order attribution data from the hidden inputs.
*
* @return {Object} Order attribution data.
*/
extractOrderAttributionData: function() {
const $orderAttributionWrapper = $( 'wc-order-attribution-inputs' );
if ( ! $orderAttributionWrapper.length ) {
return {};
}

const orderAttributionData = {};
$orderAttributionWrapper.children( 'input' ).each( function () {
orderAttributionData[ $(this).attr( 'name' ) ] = $(this).val();
});
return orderAttributionData;
},

showPaymentRequestButton: function( prButton ) {
if ( wc_stripe_payment_request.isCustomPaymentRequestButton( prButton ) ) {
prButton.addClass( 'is-active' );
Expand Down
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*** Changelog ***

= 9.0.0 - xxxx-xx-xx =
* Fix - Fix order attribution metadata not included in PRBs or Express Checkout Element.
* Add - Pre-fill user email and phone number for Link in the Payment Element.
* Remove - Remove Link autofill modal feature.
* Update - Improve accuracy of webhook status information displayed in settings page.
Expand Down
46 changes: 46 additions & 0 deletions client/blocks/__tests__/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { render } from '@testing-library/react';
import {
extractOrderAttributionData,
populateOrderAttributionInputs,
} from 'wcstripe/blocks/utils';

describe( 'Blocks Utils', () => {
describe( 'extractOrderAttributionData', () => {
it( 'order attribution wrapper not found', () => {
const data = extractOrderAttributionData();
expect( data ).toStrictEqual( {} );
} );

it( 'order attribution wrapper exists', () => {
render(
<wc-order-attribution-inputs>
<input name="foo" defaultValue="bar" />
<input name="baz" defaultValue="qux" />
</wc-order-attribution-inputs>
);

const data = extractOrderAttributionData();
expect( data ).toStrictEqual( {
foo: 'bar',
baz: 'qux',
} );
} );
} );

describe( 'populateOrderAttributionInputs', () => {
test( 'order attribution global present', () => {
global.wc_order_attribution = {
params: {
allowTracking: true,
},
setOrderTracking: jest.fn(),
};

populateOrderAttributionInputs();

expect(
global.wc_order_attribution.setOrderTracking
).toHaveBeenCalledWith( true );
} );
} );
} );
7 changes: 5 additions & 2 deletions client/blocks/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
* @typedef {import('@woocommerce/type-defs/billing').BillingData} CartBillingAddress
*/

import { getBlocksConfiguration } from 'wcstripe/blocks/utils';
import {
extractOrderAttributionData,
getBlocksConfiguration,
} from 'wcstripe/blocks/utils';

/**
* Normalizes order data received upon creating an order using the store's AJAX API.
Expand Down Expand Up @@ -79,7 +82,7 @@ const normalizeOrderData = ( paymentMethodEvent, paymentRequestType ) => {
data.shipping_postcode = shipping?.postalCode;
}

return data;
return { ...data, ...extractOrderAttributionData() };
};

/**
Expand Down
13 changes: 13 additions & 0 deletions client/blocks/payment-request/payment-request-express.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { __ } from '@wordpress/i18n';
import { useEffect } from '@wordpress/element';
import {
Elements,
PaymentRequestButtonElement,
Expand Down Expand Up @@ -70,6 +71,17 @@ const PaymentRequestExpressComponent = ( {
);
useCancelHandler( paymentRequest, onClose );

useEffect( () => {
if ( paymentRequest ) {
const orderAttribution = window?.wc_order_attribution;
if ( orderAttribution ) {
orderAttribution.setOrderTracking(
orderAttribution.params.allowTracking
);
}
}
}, [ paymentRequest ] );

// locale is not a valid value for the paymentRequestButton style.
// Make sure `theme` defaults to 'dark' if it's not found in the server provided configuration.
let {
Expand Down Expand Up @@ -173,6 +185,7 @@ export const PaymentRequestExpress = ( props ) => {
return (
<Elements stripe={ stripe }>
<PaymentRequestExpressComponent { ...props } />
<wc-order-attribution-inputs id="wc-stripe-express-checkout__order-attribution-inputs" />
</Elements>
);
};
12 changes: 11 additions & 1 deletion client/blocks/upe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ import {
expressCheckoutElementsStripeLink,
} from 'wcstripe/blocks/express-checkout';
import WCStripeAPI from 'wcstripe/api';
import { getBlocksConfiguration } from 'wcstripe/blocks/utils';
import {
addOrderAttributionInputsIfNotExists,
getBlocksConfiguration,
populateOrderAttributionInputs,
} from 'wcstripe/blocks/utils';
import './styles.scss';

const api = new WCStripeAPI(
Expand Down Expand Up @@ -106,3 +110,9 @@ if ( getBlocksConfiguration()?.isECEEnabled ) {

// Update token labels when the checkout form is loaded.
updateTokenLabelsWhenLoaded();

// Add order attribution inputs to the page.
addOrderAttributionInputsIfNotExists();

// Populate order attribution inputs with order tracking data.
populateOrderAttributionInputs();
54 changes: 54 additions & 0 deletions client/blocks/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,57 @@ export const getApiKey = () => {
}
return apiKey;
};

/**
* Get order attribution data from the hidden inputs.
*
* @return {Object} Order attribution data.
*/
export const extractOrderAttributionData = () => {
const orderAttributionWrapper = document.getElementsByTagName(
'wc-order-attribution-inputs'
);
if ( ! orderAttributionWrapper.length ) {
return {};
}

const orderAttributionData = {};
const orderAttributionInputs = orderAttributionWrapper[ 0 ].children;
for ( let i = 0; i < orderAttributionInputs.length; i++ ) {
orderAttributionData[ orderAttributionInputs[ i ].name ] =
orderAttributionInputs[ i ].value;
}
return orderAttributionData;
};

/**
* Populate order attribution inputs with order tracking data.
*
* @return {void}
*/
export const populateOrderAttributionInputs = () => {
const orderAttribution = window?.wc_order_attribution;
if ( orderAttribution ) {
orderAttribution.setOrderTracking(
orderAttribution.params.allowTracking
);
}
};

/**
* Add order attribution inputs to the page.
*
* @return {void}
*/
export const addOrderAttributionInputsIfNotExists = () => {
const elementId = 'wc-stripe-express-checkout__order-attribution-inputs';
if ( document.getElementById( elementId ) ) {
return;
}

const orderAttributionInputs = document.createElement(
'wc-order-attribution-inputs'
);
orderAttributionInputs.id = elementId;
document.body.appendChild( orderAttributionInputs );
};
3 changes: 3 additions & 0 deletions client/express-checkout/utils/normalize.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { extractOrderAttributionData } from 'wcstripe/blocks/utils';

/**
* Normalizes incoming cart total items for use as a displayItems with the Stripe api.
*
Expand Down Expand Up @@ -72,6 +74,7 @@ export const normalizeOrderData = ( event, paymentMethodId ) => {
express_checkout_type: event?.expressPaymentType,
express_payment_type: event?.expressPaymentType,
'wc-stripe-is-deferred-intent': true,
...extractOrderAttributionData(),
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,9 +420,25 @@ public function display_express_checkout_button_html() {
<!-- A Stripe Element will be inserted here. -->
</div>
<?php

if ( is_cart() ) {
add_action( 'woocommerce_after_cart', [ $this, 'add_order_attribution_inputs' ], 1 );
} else {
$this->add_order_attribution_inputs();
}

$this->display_express_checkout_button_separator_html();
}

/**
* Add order attribution inputs to the page.
*
* @return void
*/
public function add_order_attribution_inputs() {
echo '<wc-order-attribution-inputs id="wc-stripe-express-checkout__order-attribution-inputs"></wc-order-attribution-inputs>';
}

/**
* Display express checkout button separator.
*/
Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o
== Changelog ==

= 9.0.0 - xxxx-xx-xx =
* Fix - Fix order attribution metadata not included in PRBs or Express Checkout Element.
* Add - Pre-fill user email and phone number for Link in the Payment Element.
* Remove - Remove Link autofill modal feature.
* Update - Improve accuracy of webhook status information displayed in settings page.
Expand Down
22 changes: 22 additions & 0 deletions tests/phpunit/test-wc-stripe-express-checkout-element.php
Original file line number Diff line number Diff line change
Expand Up @@ -362,4 +362,26 @@ public function provide_test_display_express_checkout_button_separator_html() {
],
];
}

/**
* Test for `add_order_attribution_data`.
*
* @return void
*/
public function test_add_order_attribution_data() {
$ajax_handler = $this->getMockBuilder( WC_Stripe_Express_Checkout_Ajax_Handler::class )
->disableOriginalConstructor()
->getMock();

$helper = $this->getMockBuilder( WC_Stripe_Express_Checkout_Helper::class )
->disableOriginalConstructor()
->getMock();

$element = new WC_Stripe_Express_Checkout_Element( $ajax_handler, $helper );

ob_start();
$element->add_order_attribution_inputs();
$output = ob_get_clean();
$this->assertStringMatchesFormat( '%aid="wc-stripe-express-checkout__order-attribution-inputs"%a', $output );
}
}

0 comments on commit 7779798

Please sign in to comment.