Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing order attribution metadata when using ECE #3629

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { populateOrderAttributionInputs } from 'wcstripe/blocks/upe/populate-order-attribution-inputs';

describe( 'Unified Payment Element (Blocks)', () => {
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 );
} );
} );
} );
26 changes: 26 additions & 0 deletions client/blocks/upe/__tests__/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { render } from '@testing-library/react';
import { extractOrderAttributionData } 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',
} );
} );
} );
} );
4 changes: 4 additions & 0 deletions client/blocks/upe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import WCStripeAPI from 'wcstripe/api';
import { getBlocksConfiguration } from 'wcstripe/blocks/utils';
import './styles.scss';
import { populateOrderAttributionInputs } from 'wcstripe/blocks/upe/populate-order-attribution-inputs';

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

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

// Populate order attribution inputs with order tracking data.
populateOrderAttributionInputs();
13 changes: 13 additions & 0 deletions client/blocks/upe/populate-order-attribution-inputs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* 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
);
}
};
22 changes: 22 additions & 0 deletions client/blocks/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,25 @@ 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;
};
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 );
}
}
Loading