Allow to choose one of 3 card billing data handling modes

also handle it in one place, no need to mess with payer parsing and JS
This commit is contained in:
Alex P 2022-07-20 17:28:12 +03:00
parent 1b1091051d
commit 0c17c6b1de
7 changed files with 121 additions and 24 deletions

View file

@ -13,7 +13,7 @@ class CheckoutActionHandler {
configuration() { configuration() {
const spinner = this.spinner; const spinner = this.spinner;
const createOrder = (data, actions) => { const createOrder = (data, actions) => {
let payer = payerData(); const payer = payerData();
const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?
this.config.bn_codes[this.config.context] : ''; this.config.bn_codes[this.config.context] : '';
@ -29,10 +29,6 @@ class CheckoutActionHandler {
const paymentMethod = getCurrentPaymentMethod(); const paymentMethod = getCurrentPaymentMethod();
const fundingSource = window.ppcpFundingSource; const fundingSource = window.ppcpFundingSource;
if (fundingSource === 'card' && !PayPalCommerceGateway.use_form_billing_data_for_cards) {
payer = null;
}
return fetch(this.config.ajax.create_order.endpoint, { return fetch(this.config.ajax.create_order.endpoint, {
method: 'POST', method: 'POST',
body: JSON.stringify({ body: JSON.stringify({

View file

@ -133,6 +133,7 @@ return array(
$settings, $settings,
$early_order_handler, $early_order_handler,
$registration_needed, $registration_needed,
$container->get( 'wcgateway.settings.card_billing_data_mode' ),
$logger $logger
); );
}, },

View file

@ -891,7 +891,6 @@ class SmartButton implements SmartButtonInterface {
'single_product_buttons_enabled' => $this->settings->has( 'button_product_enabled' ) && $this->settings->get( 'button_product_enabled' ), 'single_product_buttons_enabled' => $this->settings->has( 'button_product_enabled' ) && $this->settings->get( 'button_product_enabled' ),
'mini_cart_buttons_enabled' => $this->settings->has( 'button_mini-cart_enabled' ) && $this->settings->get( 'button_mini-cart_enabled' ), 'mini_cart_buttons_enabled' => $this->settings->has( 'button_mini-cart_enabled' ) && $this->settings->get( 'button_mini-cart_enabled' ),
'basic_checkout_validation_enabled' => $this->basic_checkout_validation_enabled, 'basic_checkout_validation_enabled' => $this->basic_checkout_validation_enabled,
'use_form_billing_data_for_cards' => $this->settings->has( 'use_form_billing_data_for_cards' ) && $this->settings->get( 'use_form_billing_data_for_cards' ),
); );
if ( $this->style_for_context( 'layout', 'mini-cart' ) !== 'horizontal' ) { if ( $this->style_for_context( 'layout', 'mini-cart' ) !== 'horizontal' ) {

View file

@ -28,6 +28,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler; use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait; use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait;
use WooCommerce\PayPalCommerce\WcGateway\CardBillingMode;
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
@ -120,6 +121,13 @@ class CreateOrderEndpoint implements EndpointInterface {
*/ */
private $registration_needed; private $registration_needed;
/**
* The value of card_billing_data_mode from the settings.
*
* @var string
*/
protected $card_billing_data_mode;
/** /**
* The logger. * The logger.
* *
@ -139,6 +147,7 @@ class CreateOrderEndpoint implements EndpointInterface {
* @param Settings $settings The Settings object. * @param Settings $settings The Settings object.
* @param EarlyOrderHandler $early_order_handler The EarlyOrderHandler object. * @param EarlyOrderHandler $early_order_handler The EarlyOrderHandler object.
* @param bool $registration_needed Whether a new user must be registered during checkout. * @param bool $registration_needed Whether a new user must be registered during checkout.
* @param string $card_billing_data_mode The value of card_billing_data_mode from the settings.
* @param LoggerInterface $logger The logger. * @param LoggerInterface $logger The logger.
*/ */
public function __construct( public function __construct(
@ -151,6 +160,7 @@ class CreateOrderEndpoint implements EndpointInterface {
Settings $settings, Settings $settings,
EarlyOrderHandler $early_order_handler, EarlyOrderHandler $early_order_handler,
bool $registration_needed, bool $registration_needed,
string $card_billing_data_mode,
LoggerInterface $logger LoggerInterface $logger
) { ) {
@ -163,6 +173,7 @@ class CreateOrderEndpoint implements EndpointInterface {
$this->settings = $settings; $this->settings = $settings;
$this->early_order_handler = $early_order_handler; $this->early_order_handler = $early_order_handler;
$this->registration_needed = $registration_needed; $this->registration_needed = $registration_needed;
$this->card_billing_data_mode = $card_billing_data_mode;
$this->logger = $logger; $this->logger = $logger;
} }
@ -344,16 +355,21 @@ class CreateOrderEndpoint implements EndpointInterface {
); );
if ( 'card' === $funding_source ) { if ( 'card' === $funding_source ) {
if ( ApplicationContext::SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS === $shipping_preference ) { if ( CardBillingMode::MINIMAL_INPUT === $this->card_billing_data_mode ) {
if ( $payer ) { if ( ApplicationContext::SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS === $shipping_preference ) {
$payer->set_address( null ); if ( $payer ) {
$payer->set_address( null );
}
}
if ( ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING === $shipping_preference ) {
if ( $payer ) {
$payer->set_name( null );
}
} }
} }
if ( ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING === $shipping_preference ) {
if ( $payer ) { if ( CardBillingMode::NO_WC === $this->card_billing_data_mode ) {
$payer->set_name( null ); $payer = null;
}
} }
} }
@ -423,10 +439,7 @@ class CreateOrderEndpoint implements EndpointInterface {
$payer = $this->payer_factory->from_paypal_response( json_decode( wp_json_encode( $data['payer'] ) ) ); $payer = $this->payer_factory->from_paypal_response( json_decode( wp_json_encode( $data['payer'] ) ) );
} }
$use_form_billing_data_for_cards = $this->settings->has( 'use_form_billing_data_for_cards' ) && if ( ! $payer && isset( $data['form'] ) ) {
(bool) $this->settings->get( 'use_form_billing_data_for_cards' );
if ( ! $payer && isset( $data['form'] ) && $use_form_billing_data_for_cards ) {
$form_fields = $data['form']; $form_fields = $data['form'];
if ( is_array( $form_fields ) && isset( $form_fields['billing_email'] ) && '' !== $form_fields['billing_email'] ) { if ( is_array( $form_fields ) && isset( $form_fields['billing_email'] ) && '' !== $form_fields['billing_email'] ) {

View file

@ -869,13 +869,19 @@ return array(
'requirements' => array(), 'requirements' => array(),
'gateway' => 'paypal', 'gateway' => 'paypal',
), ),
'use_form_billing_data_for_cards' => array( 'card_billing_data_mode' => array(
'title' => __( 'Send billing data for cards', 'woocommerce-paypal-payments' ), 'title' => __( 'Card billing data handling', 'woocommerce-paypal-payments' ),
'type' => 'checkbox', 'type' => 'select',
'class' => array(),
'input_class' => array( 'wc-enhanced-select' ),
'desc_tip' => true, 'desc_tip' => true,
'label' => __( 'Send Checkout billing form data to PayPal smart card fields', 'woocommerce-paypal-payments' ), 'description' => __( 'Using the WC form data increases convenience for the customers, but can cause issues if card details do not match the billing data in the checkout form.', 'woocommerce-paypal-payments' ),
'description' => __( 'This increases convenience for the users, but can cause issues if card details do not match the billing data.', 'woocommerce-paypal-payments' ), 'default' => $container->get( 'wcgateway.settings.card_billing_data_mode.default' ),
'default' => false, 'options' => array(
CardBillingMode::USE_WC => __( 'Use WC checkout form data (do not show any address fields)', 'woocommerce-paypal-payments' ),
CardBillingMode::MINIMAL_INPUT => __( 'Request only name and postal code', 'woocommerce-paypal-payments' ),
CardBillingMode::NO_WC => __( 'Do not use WC checkout form data (request all address fields)', 'woocommerce-paypal-payments' ),
),
'screens' => array( 'screens' => array(
State::STATE_START, State::STATE_START,
State::STATE_ONBOARDED, State::STATE_ONBOARDED,
@ -2293,4 +2299,65 @@ return array(
return $pay_later_label; return $pay_later_label;
}, },
'wcgateway.settings.card_billing_data_mode.default' => static function ( ContainerInterface $container ): string {
return in_array(
$container->get( 'api.shop.country' ),
array(
'AI',
'AG',
'AR',
'AW',
'BS',
'BB',
'BZ',
'BM',
'BO',
'BR',
'VG',
'KY',
'CL',
'CO',
'CR',
'DM',
'DO',
'EC',
'SV',
'FK',
'GF',
'GD',
'GP',
'GT',
'GY',
'HN',
'JM',
'MQ',
'MX',
'MS',
'AN',
'NI',
'PA',
'PY',
'PE',
'KN',
'LC',
'PM',
'VC',
'SR',
'TT',
'TC',
'UY',
'VE',
),
true
) ? CardBillingMode::MINIMAL_INPUT : CardBillingMode::USE_WC;
},
'wcgateway.settings.card_billing_data_mode' => static function ( ContainerInterface $container ): string {
$settings = $container->get( 'wcgateway.settings' );
assert( $settings instanceof ContainerInterface );
return $settings->has( 'card_billing_data_mode' ) ?
(string) $settings->get( 'card_billing_data_mode' ) :
$container->get( 'wcgateway.settings.card_billing_data_mode.default' );
},
); );

View file

@ -0,0 +1,19 @@
<?php
/**
* Possible values of card_billing_data_mode.
*
* @package WooCommerce\PayPalCommerce\WcGateway
*/
declare( strict_types=1 );
namespace WooCommerce\PayPalCommerce\WcGateway;
/**
* Class CardBillingMode
*/
interface CardBillingMode {
public const USE_WC = 'use_wc';
public const MINIMAL_INPUT = 'minimal_input';
public const NO_WC = 'no_wc';
}

View file

@ -14,6 +14,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler; use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\TestCase;
use WooCommerce\PayPalCommerce\WcGateway\CardBillingMode;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use WooCommerce\WooCommerce\Logging\Logger\NullLogger; use WooCommerce\WooCommerce\Logging\Logger\NullLogger;
@ -164,6 +165,7 @@ class CreateOrderEndpointTest extends TestCase
$settings, $settings,
$early_order_handler, $early_order_handler,
false, false,
CardBillingMode::MINIMAL_INPUT,
new NullLogger() new NullLogger()
); );
return array($payer_factory, $testee); return array($payer_factory, $testee);