Merge trunk and fix conflicts

This commit is contained in:
dinamiko 2022-05-17 17:05:00 +02:00
commit 4ca2e637ed
58 changed files with 1174 additions and 785 deletions

View file

@ -209,12 +209,6 @@ class CreditCardRenderer {
const firstName = document.getElementById('billing_first_name') ? document.getElementById('billing_first_name').value : '';
const lastName = document.getElementById('billing_last_name') ? document.getElementById('billing_last_name').value : '';
if (!firstName || !lastName) {
this.spinner.unblock();
this.errorHandler.message(this.defaultConfig.hosted_fields.labels.cardholder_name_required);
return;
}
hostedFieldsData.cardholderName = firstName + ' ' + lastName;
}

View file

@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Button\Assets;
use Exception;
use Psr\Log\LoggerInterface;
use WC_Product;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
@ -220,16 +221,15 @@ class SmartButton implements SmartButtonInterface {
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
*/
public function render_wrapper(): bool {
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
return false;
}
if ( $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' ) ) {
$this->render_button_wrapper_registrar();
$this->render_message_wrapper_registrar();
}
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
return false;
}
if (
$this->settings->has( 'dcc_enabled' )
&& $this->settings->get( 'dcc_enabled' )
@ -430,6 +430,10 @@ class SmartButton implements SmartButtonInterface {
add_action(
$this->mini_cart_button_renderer_hook(),
function () {
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
return;
}
if ( $this->is_cart_price_total_zero() || $this->is_free_trial_cart() ) {
return;
}
@ -512,13 +516,16 @@ class SmartButton implements SmartButtonInterface {
* Renders the HTML for the buttons.
*/
public function button_renderer() {
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
return;
}
$product = wc_get_product();
if (
! is_checkout() && is_a( $product, \WC_Product::class )
&& (
$product->is_type( array( 'external', 'grouped' ) )
|| ! $product->is_in_stock()
)
! is_checkout() && is_a( $product, WC_Product::class )
&& ! $this->product_supports_payment( $product )
) {
return;
@ -538,7 +545,22 @@ class SmartButton implements SmartButtonInterface {
/**
* Renders the HTML for the credit messaging.
*/
public function message_renderer():void {
public function message_renderer() {
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
return false;
}
$product = wc_get_product();
if (
! is_checkout() && is_a( $product, WC_Product::class )
/**
* The filter returning true if PayPal buttons can be rendered, or false otherwise.
*/
&& ! $this->product_supports_payment( $product )
) {
return;
}
echo '<div id="ppcp-messages" data-partner-attribution-id="Woo_PPCP"></div>';
}
@ -559,7 +581,7 @@ class SmartButton implements SmartButtonInterface {
}
$placement = 'product';
$product = wc_get_product();
$amount = ( is_a( $product, \WC_Product::class ) ) ? wc_get_price_including_tax( $product ) : 0;
$amount = ( is_a( $product, WC_Product::class ) ) ? wc_get_price_including_tax( $product ) : 0;
$layout = $this->settings->has( 'message_product_layout' ) ?
$this->settings->get( 'message_product_layout' ) : 'text';
$logo_type = $this->settings->has( 'message_product_logo' ) ?
@ -1219,6 +1241,24 @@ class SmartButton implements SmartButtonInterface {
return WC()->cart && WC()->cart->get_total( 'numeric' ) == 0;
}
/**
* Checks if PayPal buttons/messages can be rendered for the given product.
*
* @param WC_Product $product The product.
*
* @return bool
*/
protected function product_supports_payment( WC_Product $product ): bool {
/**
* The filter returning true if PayPal buttons/messages can be rendered for this product, or false otherwise.
*/
return apply_filters(
'woocommerce_paypal_payments_product_supports_payment_request_button',
! $product->is_type( array( 'external', 'grouped' ) ) && $product->is_in_stock(),
$product
);
}
/**
* Retrieves all payment tokens for the user, via API or cached if already queried.
*

View file

@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
use Exception;
use Psr\Log\LoggerInterface;
use stdClass;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Amount;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
@ -242,6 +243,13 @@ class CreateOrderEndpoint implements EndpointInterface {
}
$order = $this->create_paypal_order( $wc_order );
if ( 'pay-now' === $data['context'] && is_a( $wc_order, \WC_Order::class ) ) {
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
$wc_order->save_meta_data();
}
wp_send_json_success( $order->to_array() );
return true;
@ -317,19 +325,51 @@ class CreateOrderEndpoint implements EndpointInterface {
* @return Order Created PayPal order.
*
* @throws RuntimeException If create order request fails.
* @throws PayPalApiException If create order request fails.
* phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
*/
private function create_paypal_order( \WC_Order $wc_order = null ): Order {
$needs_shipping = WC()->cart instanceof \WC_Cart && WC()->cart->needs_shipping();
$shipping_address_is_fix = $needs_shipping && 'checkout' === $this->parsed_request_data['context'];
return $this->api_endpoint->create(
$this->purchase_units,
$this->payer( $this->parsed_request_data, $wc_order ),
null,
$this->payment_method(),
'',
$shipping_address_is_fix
);
try {
return $this->api_endpoint->create(
$this->purchase_units,
$this->payer( $this->parsed_request_data, $wc_order ),
null,
$this->payment_method(),
'',
$shipping_address_is_fix
);
} catch ( PayPalApiException $exception ) {
// Looks like currently there is no proper way to validate the shipping address for PayPal,
// so we cannot make some invalid addresses null in PurchaseUnitFactory,
// which causes failure e.g. for guests using the button on products pages when the country does not have postal codes.
if ( 422 === $exception->status_code()
&& array_filter(
$exception->details(),
function ( stdClass $detail ): bool {
return isset( $detail->field ) && str_contains( (string) $detail->field, 'shipping/address' );
}
) ) {
$this->logger->info( 'Invalid shipping address for order creation, retrying without it.' );
foreach ( $this->purchase_units as $purchase_unit ) {
$purchase_unit->set_shipping( null );
}
return $this->api_endpoint->create(
$this->purchase_units,
$this->payer( $this->parsed_request_data, $wc_order ),
null,
$this->payment_method(),
'',
$shipping_address_is_fix
);
}
throw $exception;
}
}
/**