Skip to content

Commit

Permalink
fix: pricing decimal formatting for tokenized cart (#8992)
Browse files Browse the repository at this point in the history
  • Loading branch information
frosso authored Jun 24, 2024
1 parent aac2f27 commit bbebcd2
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 17 deletions.
4 changes: 4 additions & 0 deletions changelog/fix-tokenized-cart-decimals-price
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fix

fix: pricing decimal formatting for tokenized cart
14 changes: 11 additions & 3 deletions client/tokenized-payment-request/frontend-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { doingAction } from '@wordpress/hooks';
/**
* Internal dependencies
*/
import { transformCartDataForDisplayItems } from './transformers/wc-to-stripe';
import {
transformCartDataForDisplayItems,
transformPrice,
} from './transformers/wc-to-stripe';

/**
* Retrieves payment request data from global variable.
Expand Down Expand Up @@ -61,9 +64,14 @@ export const getPaymentRequest = ( { stripe, cartData, productData } ) => {
currency: cartData.totals.currency_code.toLowerCase(),
total: {
label: getPaymentRequestData( 'total_label' ),
amount:
amount: transformPrice(
parseInt( cartData.totals.total_price, 10 ) -
parseInt( cartData.totals.total_refund || 0, 10 ),
parseInt(
cartData.totals.total_refund || 0,
10
),
cartData.totals
),
},
requestShipping:
getPaymentRequestData( 'button_context' ) ===
Expand Down
31 changes: 22 additions & 9 deletions client/tokenized-payment-request/payment-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import {
transformCartDataForDisplayItems,
transformCartDataForShippingOptions,
transformPrice,
} from './transformers/wc-to-stripe';
import paymentRequestButtonUi from './button-ui';
import {
Expand Down Expand Up @@ -177,12 +178,14 @@ export default class WooPaymentsPaymentRequest {
paymentRequest.update( {
total: {
label: getPaymentRequestData( 'total_label' ),
amount:
amount: transformPrice(
parseInt( newCartData.totals.total_price, 10 ) -
parseInt(
newCartData.totals.total_refund || 0,
10
),
parseInt(
newCartData.totals.total_refund || 0,
10
),
newCartData.totals
),
},
displayItems: transformCartDataForDisplayItems(
newCartData
Expand Down Expand Up @@ -266,9 +269,14 @@ export default class WooPaymentsPaymentRequest {
),
total: {
label: getPaymentRequestData( 'total_label' ),
amount:
amount: transformPrice(
parseInt( cartData.totals.total_price, 10 ) -
parseInt( cartData.totals.total_refund || 0, 10 ),
parseInt(
cartData.totals.total_refund || 0,
10
),
cartData.totals
),
},
displayItems: transformCartDataForDisplayItems( cartData ),
} );
Expand All @@ -292,9 +300,14 @@ export default class WooPaymentsPaymentRequest {
status: 'success',
total: {
label: getPaymentRequestData( 'total_label' ),
amount:
amount: transformPrice(
parseInt( cartData.totals.total_price, 10 ) -
parseInt( cartData.totals.total_refund || 0, 10 ),
parseInt(
cartData.totals.total_refund || 0,
10
),
cartData.totals
),
},
displayItems: transformCartDataForDisplayItems( cartData ),
} );
Expand Down
28 changes: 23 additions & 5 deletions client/tokenized-payment-request/transformers/wc-to-stripe.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
*/
import { __ } from '@wordpress/i18n';

/**
* GooglePay/ApplePay expect the prices to be formatted in cents.
* But WooCommerce has a setting to define the number of decimals for amounts.
* Using this function to ensure the prices provided to GooglePay/ApplePay
* are always provided accurately, regardless of the number of decimals.
*
* @param {number} price the price to format.
* @param {{currency_minor_unit: {number}}} priceObject the price object returned by the Store API
*
* @return {number} the price amount for GooglePay/ApplePay, always expressed in cents.
*/
export const transformPrice = ( price, priceObject ) =>
// making sure the decimals are always correctly represented for GooglePay/ApplePay, since they don't allow us to specify the decimals.
price * 10 ** ( 2 - priceObject.currency_minor_unit );

/**
* Transforms the data from the Store API Cart response to `displayItems` for the Stripe PRB.
* See https://docs.stripe.com/js/appendix/payment_item_object for the data structure
Expand All @@ -12,7 +27,10 @@ import { __ } from '@wordpress/i18n';
*/
export const transformCartDataForDisplayItems = ( cartData ) => {
const displayItems = cartData.items.map( ( item ) => ( {
amount: parseInt( item.prices.price, 10 ),
amount: transformPrice(
parseInt( item.prices.price, 10 ),
item.prices
),
label: [
item.name,
item.quantity > 1 && `(x${ item.quantity })`,
Expand All @@ -31,7 +49,7 @@ export const transformCartDataForDisplayItems = ( cartData ) => {
const taxAmount = parseInt( cartData.totals.total_tax || '0', 10 );
if ( taxAmount ) {
displayItems.push( {
amount: taxAmount,
amount: transformPrice( taxAmount, cartData.totals ),
label: __( 'Tax', 'woocommerce-payments' ),
} );
}
Expand All @@ -42,15 +60,15 @@ export const transformCartDataForDisplayItems = ( cartData ) => {
);
if ( shippingAmount ) {
displayItems.push( {
amount: shippingAmount,
amount: transformPrice( shippingAmount, cartData.totals ),
label: __( 'Shipping', 'woocommerce-payments' ),
} );
}

const refundAmount = parseInt( cartData.totals.total_refund || '0', 10 );
if ( refundAmount ) {
displayItems.push( {
amount: -refundAmount,
amount: -transformPrice( refundAmount, cartData.totals ),
label: __( 'Refund', 'woocommerce-payments' ),
} );
}
Expand All @@ -68,6 +86,6 @@ export const transformCartDataForShippingOptions = ( cartData ) =>
cartData.shipping_rates[ 0 ].shipping_rates.map( ( rate ) => ( {
id: rate.rate_id,
label: rate.name,
amount: parseInt( rate.price, 10 ),
amount: transformPrice( parseInt( rate.price, 10 ), rate ),
detail: '',
} ) );

0 comments on commit bbebcd2

Please sign in to comment.