Skip to content

Commit

Permalink
Merge branch 'develop' into improve-pmme-placement-shortcode
Browse files Browse the repository at this point in the history
  • Loading branch information
gpressutto5 authored Dec 18, 2024
2 parents 7f44766 + 5eaa046 commit 76db323
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 16 deletions.
5 changes: 5 additions & 0 deletions changelog/fix-tokenized-cart-subscription-signup-fee
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: fix
Comment: fix: tokenized cart subscription signup fee price


4 changes: 4 additions & 0 deletions changelog/load-checkout-scripts-on-checkout-if-not-loaded
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fix

Load checkout scripts when they are not previously loaded on checkout page.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: update

Add failure reason to failed payments in the timeline.
19 changes: 13 additions & 6 deletions client/payment-details/timeline/map-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
import { formatFee } from 'utils/fees';
import { getAdminUrl } from 'wcpay/utils';
import { ShieldIcon } from 'wcpay/icons';
import { fraudOutcomeRulesetMapping } from './mappings';
import { fraudOutcomeRulesetMapping, paymentFailureMapping } from './mappings';

/**
* Creates a timeline item about a payment status change
Expand Down Expand Up @@ -772,18 +772,25 @@ const mapEventToTimelineItems = ( event ) => {
),
];
case 'failed':
const paymentFailureMessage =
paymentFailureMapping[ event.reason ] ||
paymentFailureMapping.default;

return [
getStatusChangeTimelineItem(
event,
__( 'Failed', 'woocommerce-payments' )
),
getMainTimelineItem(
event,
stringWithAmount(
/* translators: %s is a monetary amount */
__( 'A payment of %s failed.', 'woocommerce-payments' ),
event.amount,
true
sprintf(
/* translators: %1$s is the payment amount, %2$s is the failure reason message */
__(
'A payment of %1$s failed: %2$s.',
'woocommerce-payments'
),
formatExplicitCurrency( event.amount, event.currency ),
paymentFailureMessage
),
<CrossIcon className="is-error" />
),
Expand Down
43 changes: 43 additions & 0 deletions client/payment-details/timeline/mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,46 @@ export const fraudOutcomeRulesetMapping = {
),
},
};

// eslint-disable-next-line @typescript-eslint/naming-convention
export const paymentFailureMapping = {
card_declined: __(
'The card was declined by the bank',
'woocommerce-payments'
),
expired_card: __( 'The card has expired', 'woocommerce-payments' ),
incorrect_cvc: __(
'The security code is incorrect',
'woocommerce-payments'
),
incorrect_number: __(
'The card number is incorrect',
'woocommerce-payments'
),
incorrect_zip: __( 'The postal code is incorrect', 'woocommerce-payments' ),
invalid_cvc: __( 'The security code is invalid', 'woocommerce-payments' ),
invalid_expiry_month: __(
'The expiration month is invalid',
'woocommerce-payments'
),
invalid_expiry_year: __(
'The expiration year is invalid',
'woocommerce-payments'
),
invalid_number: __( 'The card number is invalid', 'woocommerce-payments' ),
processing_error: __(
'An error occurred while processing the card',
'woocommerce-payments'
),
authentication_required: __(
'The payment requires authentication',
'woocommerce-payments'
),
insufficient_funds: __(
'The card has insufficient funds to complete the purchase',
'woocommerce-payments'
),

// Default fallback
default: __( 'The payment was declined', 'woocommerce-payments' ),
};
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ exports[`PaymentDetailsTimeline renders correctly (with a mocked Timeline compon
</g>
</svg>
<span>
A payment of $77.00 failed.
A payment of $77.00 failed: The card was declined by the bank.
</span>
</div>
<span
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ exports[`mapTimelineEvents formats card_declined events 1`] = `
{
"body": [],
"date": 2020-04-01T03:35:13.000Z,
"headline": "A payment of $77.00 USD failed.",
"headline": "A payment of $77.00 USD failed: The card was declined by the bank.",
"icon": <CrossIcon
className="is-error"
/>,
Expand Down
55 changes: 55 additions & 0 deletions client/payment-details/timeline/test/map-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -662,4 +662,59 @@ describe( 'mapTimelineEvents', () => {
).toMatchSnapshot();
} );
} );

test( 'formats payment failure events with different error codes', () => {
const testCases = [
{
reason: 'insufficient_funds',
expectedMessage:
'A payment of $77.00 USD failed: The card has insufficient funds to complete the purchase.',
},
{
reason: 'expired_card',
expectedMessage:
'A payment of $77.00 USD failed: The card has expired.',
},
{
reason: 'invalid_cvc',
expectedMessage:
'A payment of $77.00 USD failed: The security code is invalid.',
},
{
reason: 'unknown_reason',
expectedMessage:
'A payment of $77.00 USD failed: The payment was declined.',
},
];

testCases.forEach( ( { reason, expectedMessage } ) => {
const events = mapTimelineEvents( [
{
amount: 7700,
currency: 'USD',
datetime: 1585712113,
reason,
type: 'failed',
},
] );

expect( events[ 1 ].headline ).toBe( expectedMessage );
} );
} );

test( 'formats payment failure events with different currencies', () => {
const events = mapTimelineEvents( [
{
amount: 7700,
currency: 'EUR',
datetime: 1585712113,
reason: 'card_declined',
type: 'failed',
},
] );

expect( events[ 1 ].headline ).toBe(
'A payment of €77.00 EUR failed: The card was declined by the bank.'
);
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export const transformPrice = ( price, priceObject ) => {
export const transformCartDataForDisplayItems = ( cartData ) => {
const displayItems = cartData.items.map( ( item ) => ( {
amount: transformPrice(
parseInt( item.prices.price, 10 ),
item.prices
parseInt( item.totals?.line_subtotal || item.prices.price, 10 ),
item.totals || item.prices
),
name: [
item.name,
Expand Down
31 changes: 25 additions & 6 deletions includes/class-wc-payments-checkout.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public function init_hooks() {

add_action( 'wp_enqueue_scripts', [ $this, 'register_scripts' ] );
add_action( 'wp_enqueue_scripts', [ $this, 'register_scripts_for_zero_order_total' ], 11 );
add_action( 'woocommerce_after_checkout_form', [ $this, 'maybe_load_checkout_scripts' ] );
}

/**
Expand Down Expand Up @@ -151,11 +152,18 @@ public function register_scripts_for_zero_order_total() {
! has_block( 'woocommerce/checkout' ) &&
! wp_script_is( 'wcpay-upe-checkout', 'enqueued' )
) {
WC_Payments::get_gateway()->tokenization_script();
$script_handle = 'wcpay-upe-checkout';
$js_object = 'wcpay_upe_config';
wp_localize_script( $script_handle, $js_object, WC_Payments::get_wc_payments_checkout()->get_payment_fields_js_config() );
wp_enqueue_script( $script_handle );
$this->load_checkout_scripts();
}
}

/**
* Sometimes the filters can remove the payment gateway from the checkout page which results in the payment fields not being displayed.
* This could prevent loading of the payment fields (checkout) scripts.
* This function ensures that these scripts are loaded.
*/
public function maybe_load_checkout_scripts() {
if ( is_checkout() && ! wp_script_is( 'wcpay-upe-checkout', 'enqueued' ) ) {
$this->load_checkout_scripts();
}
}

Expand Down Expand Up @@ -416,7 +424,7 @@ function () use ( $prepared_customer_data ) {
}

?>
<div class="wcpay-upe-form"
<div class="wcpay-upe-form"
data-payment-method-type="<?php echo esc_attr( $this->gateway->get_stripe_id() ); ?>"
>
<?php
Expand Down Expand Up @@ -497,4 +505,15 @@ public function set_gateway( $payment_method_id ) {
$this->gateway = $this->gateway->wc_payments_get_payment_gateway_by_id( $payment_method_id );
}
}

/**
* Load the checkout scripts.
*/
private function load_checkout_scripts() {
WC_Payments::get_gateway()->tokenization_script();
$script_handle = 'wcpay-upe-checkout';
$js_object = 'wcpay_upe_config';
wp_localize_script( $script_handle, $js_object, WC_Payments::get_wc_payments_checkout()->get_payment_fields_js_config() );
wp_enqueue_script( $script_handle );
}
}

0 comments on commit 76db323

Please sign in to comment.