Merge branch 'trunk' into PT-51-plugin-information---support

This commit is contained in:
dinamiko 2021-08-09 13:00:10 +02:00
commit b49970be41
12 changed files with 203 additions and 35 deletions

View file

@ -12,6 +12,7 @@ branches:
only: only:
- master - master
- trunk - trunk
- compat/ppxo
script: | script: |
CHANGED_FILES=`git diff --name-only --diff-filter=ACMR $TRAVIS_COMMIT_RANGE | grep \\\\.php | awk '{print}' ORS=' '` CHANGED_FILES=`git diff --name-only --diff-filter=ACMR $TRAVIS_COMMIT_RANGE | grep \\\\.php | awk '{print}' ORS=' '`

View file

@ -1,5 +1,21 @@
*** Changelog *** *** Changelog ***
= 1.4.0 - 2021-07-27 =
* Add - Venmo update #169
* Add - Pay Later Button Global Expansion #182
* Add - Add Canada to advanced credit and debit card #180
* Add - Add button height setting for mini cart #181
* Add - Add BN Code to Pay Later Messaging #183
* Add - Add 30 seconds timeout by default to all API requests #184
* Fix - ACDC checkout error: "Card Details not valid"; but payment completes #193
* Fix - Incorrect API credentials cause fatal error #187
* Fix - PayPal payment fails if a new user account is created during the checkout process #177
* Fix - Disabled PayPal button appears when another button is loaded on the same page #192
* Fix - [UNPROCESSABLE_ENTITY] error during checkout #172
* Fix - Do not send customer email when order status is on hold #173
* Fix - Remove merchant-id query parameter in JSSDK #179
* Fix - Error on Plugin activation with Zettle POS Integration for WooCommerce #195
= 1.3.2 - 2021-06-08 = = 1.3.2 - 2021-06-08 =
* Fix - Improve Subscription plugin support. #161 * Fix - Improve Subscription plugin support. #161
* Fix - Disable vault setting if vaulting feature is not available. #150 * Fix - Disable vault setting if vaulting feature is not available. #150

View file

@ -182,7 +182,7 @@ class SmartButton implements SmartButtonInterface {
&& ! $this->session_handler->order() && ! $this->session_handler->order()
) { ) {
add_action( add_action(
'woocommerce_review_order_after_submit', $this->checkout_dcc_button_renderer_hook(),
array( array(
$this, $this,
'dcc_renderer', 'dcc_renderer',
@ -191,7 +191,7 @@ class SmartButton implements SmartButtonInterface {
); );
add_action( add_action(
'woocommerce_pay_order_after_submit', $this->pay_order_renderer_hook(),
array( array(
$this, $this,
'dcc_renderer', 'dcc_renderer',
@ -202,7 +202,7 @@ class SmartButton implements SmartButtonInterface {
add_filter( add_filter(
'woocommerce_credit_card_form_fields', 'woocommerce_credit_card_form_fields',
function ( $default_fields, $id ) { function ( $default_fields, $id ) {
if ( $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) && CreditCardGateway::ID === $id ) { if ( is_user_logged_in() && $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) && CreditCardGateway::ID === $id ) {
$default_fields['card-vault'] = sprintf( $default_fields['card-vault'] = sprintf(
'<p class="form-row form-row-wide"><label for="vault"><input class="ppcp-credit-card-vault" type="checkbox" id="ppcp-credit-card-vault" name="vault">%s</label></p>', '<p class="form-row form-row-wide"><label for="vault"><input class="ppcp-credit-card-vault" type="checkbox" id="ppcp-credit-card-vault" name="vault">%s</label></p>',
esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' ) esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' )
@ -255,7 +255,7 @@ class SmartButton implements SmartButtonInterface {
&& ! $not_enabled_on_cart && ! $not_enabled_on_cart
) { ) {
add_action( add_action(
'woocommerce_proceed_to_checkout', $this->proceed_to_checkout_button_renderer_hook(),
array( array(
$this, $this,
'message_renderer', 'message_renderer',
@ -271,7 +271,7 @@ class SmartButton implements SmartButtonInterface {
&& ! $not_enabled_on_product_page && ! $not_enabled_on_product_page
) { ) {
add_action( add_action(
'woocommerce_single_product_summary', $this->single_product_renderer_hook(),
array( array(
$this, $this,
'message_renderer', 'message_renderer',
@ -284,7 +284,7 @@ class SmartButton implements SmartButtonInterface {
! $this->settings->get( 'message_enabled' ); ! $this->settings->get( 'message_enabled' );
if ( ! $not_enabled_on_checkout ) { if ( ! $not_enabled_on_checkout ) {
add_action( add_action(
'woocommerce_review_order_after_submit', $this->checkout_dcc_button_renderer_hook(),
array( array(
$this, $this,
'message_renderer', 'message_renderer',
@ -292,7 +292,7 @@ class SmartButton implements SmartButtonInterface {
11 11
); );
add_action( add_action(
'woocommerce_pay_order_after_submit', $this->pay_order_renderer_hook(),
array( array(
$this, $this,
'message_renderer', 'message_renderer',
@ -318,7 +318,7 @@ class SmartButton implements SmartButtonInterface {
&& ! $not_enabled_on_cart && ! $not_enabled_on_cart
) { ) {
add_action( add_action(
'woocommerce_proceed_to_checkout', $this->proceed_to_checkout_button_renderer_hook(),
array( array(
$this, $this,
'button_renderer', 'button_renderer',
@ -334,7 +334,7 @@ class SmartButton implements SmartButtonInterface {
&& ! $not_enabled_on_product_page && ! $not_enabled_on_product_page
) { ) {
add_action( add_action(
'woocommerce_single_product_summary', $this->single_product_renderer_hook(),
array( array(
$this, $this,
'button_renderer', 'button_renderer',
@ -349,7 +349,7 @@ class SmartButton implements SmartButtonInterface {
! $not_enabled_on_minicart ! $not_enabled_on_minicart
) { ) {
add_action( add_action(
'woocommerce_widget_shopping_cart_after_buttons', $this->mini_cart_button_renderer_hook(),
static function () { static function () {
echo '<p echo '<p
id="ppc-button-minicart" id="ppc-button-minicart"
@ -360,8 +360,8 @@ class SmartButton implements SmartButtonInterface {
); );
} }
add_action( 'woocommerce_review_order_after_payment', array( $this, 'button_renderer' ), 10 ); add_action( $this->checkout_button_renderer_hook(), array( $this, 'button_renderer' ), 10 );
add_action( 'woocommerce_pay_order_after_submit', array( $this, 'button_renderer' ), 10 ); add_action( $this->pay_order_renderer_hook(), array( $this, 'button_renderer' ), 10 );
return true; return true;
} }
@ -963,4 +963,64 @@ class SmartButton implements SmartButtonInterface {
return $height; return $height;
} }
/**
* Return action name PayPal buttons will be rendered at on checkout page.
*
* @return string Action name.
*/
private function checkout_button_renderer_hook(): string {
return (string) apply_filters( 'woocommerce_paypal_payments_checkout_button_renderer_hook', 'woocommerce_review_order_after_payment' );
}
/**
* Return action name PayPal DCC button will be rendered at on checkout page.
*
* @return string
*/
private function checkout_dcc_button_renderer_hook(): string {
return (string) apply_filters( 'woocommerce_paypal_payments_checkout_dcc_renderer_hook', 'woocommerce_review_order_after_submit' );
}
/**
* Return action name PayPal button and Pay Later message will be rendered at on pay-order page.
*
* @return string
*/
private function pay_order_renderer_hook(): string {
return (string) apply_filters( 'woocommerce_paypal_payments_pay_order_dcc_renderer_hook', 'woocommerce_pay_order_after_submit' );
}
/**
* Return action name PayPal button will be rendered next to Proceed to checkout button (normally displayed in cart).
*
* @return string
*/
private function proceed_to_checkout_button_renderer_hook(): string {
return (string) apply_filters(
'woocommerce_paypal_payments_proceed_to_checkout_button_renderer_hook',
'woocommerce_proceed_to_checkout'
);
}
/**
* Return action name PayPal button will be rendered in the WC mini cart.
*
* @return string
*/
private function mini_cart_button_renderer_hook(): string {
return (string) apply_filters(
'woocommerce_paypal_payments_mini_cart_button_renderer_hook',
'woocommerce_widget_shopping_cart_after_buttons'
);
}
/**
* Return action name PayPal button and Pay Later message will be rendered at on the single product page.
*
* @return string
*/
private function single_product_renderer_hook(): string {
return (string) apply_filters( 'woocommerce_paypal_payments_single_product_renderer_hook', 'woocommerce_single_product_summary' );
}
} }

View file

@ -253,6 +253,7 @@ document.addEventListener(
'#field-button_mini-cart_label', '#field-button_mini-cart_label',
'#field-button_mini-cart_color', '#field-button_mini-cart_color',
'#field-button_mini-cart_shape', '#field-button_mini-cart_shape',
'#field-button_mini-cart_height',
] ]
); );

View file

@ -80,7 +80,7 @@ class SubscriptionModule implements ModuleInterface {
$settings = $container->get( 'wcgateway.settings' ); $settings = $container->get( 'wcgateway.settings' );
$subscription_helper = $container->get( 'subscription.helper' ); $subscription_helper = $container->get( 'subscription.helper' );
return $this->display_saved_paypal_payments( $settings, $id, $payment_token_repository, $description, $subscription_helper ); return $this->display_saved_paypal_payments( $settings, (string) $id, $payment_token_repository, (string) $description, $subscription_helper );
}, },
10, 10,
2 2

View file

@ -761,7 +761,7 @@ return array(
'type' => 'select', 'type' => 'select',
'class' => array(), 'class' => array(),
'input_class' => array( 'wc-enhanced-select' ), 'input_class' => array( 'wc-enhanced-select' ),
'default' => 'paypal', 'default' => apply_filters( 'woocommerce_paypal_payments_button_label_default', 'paypal' ),
'desc_tip' => true, 'desc_tip' => true,
'description' => __( 'description' => __(
'This controls the label on the primary button.', 'This controls the label on the primary button.',
@ -1063,7 +1063,7 @@ return array(
'type' => 'select', 'type' => 'select',
'class' => array(), 'class' => array(),
'input_class' => array( 'wc-enhanced-select' ), 'input_class' => array( 'wc-enhanced-select' ),
'default' => 'paypal', 'default' => apply_filters( 'woocommerce_paypal_payments_button_product_label_default', 'paypal' ),
'desc_tip' => true, 'desc_tip' => true,
'description' => __( 'description' => __(
'This controls the label on the primary button.', 'This controls the label on the primary button.',
@ -1366,7 +1366,7 @@ return array(
'type' => 'select', 'type' => 'select',
'class' => array(), 'class' => array(),
'input_class' => array( 'wc-enhanced-select' ), 'input_class' => array( 'wc-enhanced-select' ),
'default' => 'paypal', 'default' => apply_filters( 'woocommerce_paypal_payments_button_cart_label_default', 'paypal' ),
'desc_tip' => true, 'desc_tip' => true,
'description' => __( 'description' => __(
'This controls the label on the primary button.', 'This controls the label on the primary button.',
@ -1669,7 +1669,7 @@ return array(
'type' => 'select', 'type' => 'select',
'class' => array(), 'class' => array(),
'input_class' => array( 'wc-enhanced-select' ), 'input_class' => array( 'wc-enhanced-select' ),
'default' => 'paypal', 'default' => apply_filters( 'woocommerce_paypal_payments_button_mini_cart_label_default', 'paypal' ),
'desc_tip' => true, 'desc_tip' => true,
'description' => __( 'description' => __(
'This controls the label on the primary button.', 'This controls the label on the primary button.',

View file

@ -236,21 +236,16 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
} }
/** /**
* Returns the title of the gateway. * Returns the icons of the gateway.
* *
* @return string * @return string
*/ */
public function get_title() { public function get_icon() {
$icon = parent::get_icon();
//phpcs:disable WordPress.Security.NonceVerification.Recommended
if ( ! is_checkout() || ( is_ajax() && isset( $_GET['wc-ajax'] ) && 'update_order_review' !== $_GET['wc-ajax'] ) ) {
return parent::get_title();
}
//phpcs:enable WordPress.Security.NonceVerification.Recommended
$title = parent::get_title();
$icons = $this->config->has( 'card_icons' ) ? (array) $this->config->get( 'card_icons' ) : array(); $icons = $this->config->has( 'card_icons' ) ? (array) $this->config->get( 'card_icons' ) : array();
if ( empty( $icons ) ) { if ( empty( $icons ) ) {
return $title; return $icon;
} }
$title_options = $this->card_labels(); $title_options = $this->card_labels();
@ -258,13 +253,14 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
function ( string $type ) use ( $title_options ): string { function ( string $type ) use ( $title_options ): string {
return '<img return '<img
title="' . esc_attr( $title_options[ $type ] ) . '" title="' . esc_attr( $title_options[ $type ] ) . '"
src="' . esc_url( $this->module_url ) . '/assets/images/' . esc_attr( $type ) . '.svg" src="' . esc_url( $this->module_url ) . 'assets/images/' . esc_attr( $type ) . '.svg"
class="ppcp-card-icon" class="ppcp-card-icon"
> '; > ';
}, },
$icons $icons
); );
return $title . implode( '', $images );
return implode( '', $images );
} }
/** /**

View file

@ -96,6 +96,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
*/ */
private $refund_processor; private $refund_processor;
/**
* Whether the plugin is in onboarded state.
*
* @var bool
*/
private $onboarded;
/** /**
* PayPalGateway constructor. * PayPalGateway constructor.
* *
@ -132,8 +139,9 @@ class PayPalGateway extends \WC_Payment_Gateway {
$this->session_handler = $session_handler; $this->session_handler = $session_handler;
$this->refund_processor = $refund_processor; $this->refund_processor = $refund_processor;
$this->transaction_url_provider = $transaction_url_provider; $this->transaction_url_provider = $transaction_url_provider;
$this->onboarded = $state->current_state() === State::STATE_ONBOARDED;
if ( $state->current_state() === State::STATE_ONBOARDED ) { if ( $this->onboarded ) {
$this->supports = array( 'refunds' ); $this->supports = array( 'refunds' );
} }
if ( if (
@ -185,7 +193,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
*/ */
public function needs_setup(): bool { public function needs_setup(): bool {
return true; return ! $this->onboarded;
} }
/** /**
@ -373,4 +381,20 @@ class PayPalGateway extends \WC_Payment_Gateway {
return parent::get_transaction_url( $order ); return parent::get_transaction_url( $order );
} }
/**
* Updates WooCommerce gateway option.
*
* @param string $key The option key.
* @param string $value The option value.
* @return bool|void
*/
public function update_option( $key, $value = '' ) {
parent::update_option( $key, $value );
if ( 'enabled' === $key ) {
$this->config->set( 'enabled', 'yes' === $value );
$this->config->persist();
}
}
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "woocommerce-paypal-payments", "name": "woocommerce-paypal-payments",
"version": "1.3.2", "version": "1.4.0",
"description": "WooCommerce PayPal Payments", "description": "WooCommerce PayPal Payments",
"repository": "https://github.com/woocommerce/woocommerce-paypal-payments", "repository": "https://github.com/woocommerce/woocommerce-paypal-payments",
"license": "GPL-2.0", "license": "GPL-2.0",

View file

@ -2,9 +2,9 @@
Contributors: woocommerce, automattic Contributors: woocommerce, automattic
Tags: woocommerce, paypal, payments, ecommerce, e-commerce, store, sales, sell, shop, shopping, cart, checkout Tags: woocommerce, paypal, payments, ecommerce, e-commerce, store, sales, sell, shop, shopping, cart, checkout
Requires at least: 5.3 Requires at least: 5.3
Tested up to: 5.7 Tested up to: 5.8
Requires PHP: 7.1 Requires PHP: 7.1
Stable tag: 1.3.2 Stable tag: 1.4.0
License: GPLv2 License: GPLv2
License URI: http://www.gnu.org/licenses/gpl-2.0.html License URI: http://www.gnu.org/licenses/gpl-2.0.html
@ -58,6 +58,22 @@ Follow the steps below to connect the plugin to your PayPal account:
== Changelog == == Changelog ==
= 1.4.0 =
* Add - Venmo update #169
* Add - Pay Later Button Global Expansion #182
* Add - Add Canada to advanced credit and debit card #180
* Add - Add button height setting for mini cart #181
* Add - Add BN Code to Pay Later Messaging #183
* Add - Add 30 seconds timeout by default to all API requests #184
* Fix - ACDC checkout error: "Card Details not valid"; but payment completes #193
* Fix - Incorrect API credentials cause fatal error #187
* Fix - PayPal payment fails if a new user account is created during the checkout process #177
* Fix - Disabled PayPal button appears when another button is loaded on the same page #192
* Fix - [UNPROCESSABLE_ENTITY] error during checkout #172
* Fix - Do not send customer email when order status is on hold #173
* Fix - Remove merchant-id query parameter in JSSDK #179
* Fix - Error on Plugin activation with Zettle POS Integration for WooCommerce #195
= 1.3.2 = = 1.3.2 =
* Fix - Improve Subscription plugin support. #161 * Fix - Improve Subscription plugin support. #161
* Fix - Disable vault setting if vaulting feature is not available. #150 * Fix - Disable vault setting if vaulting feature is not available. #150

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway; namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
use Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\Onboarding\State; use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
@ -365,6 +366,45 @@ class WcGatewayTest extends TestCase
$this->assertFalse($testee->capture_authorized_payment($wcOrder)); $this->assertFalse($testee->capture_authorized_payment($wcOrder));
} }
/**
* @dataProvider dataForTestNeedsSetup
*/
public function testNeedsSetup($currentState, $needSetup)
{
expect('is_admin')->andReturn(true);
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$authorizedOrdersProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$authorizeOrderActionNotice = Mockery::mock(AuthorizeOrderActionNotice::class);
$config = Mockery::mock(ContainerInterface::class);
$config
->shouldReceive('has')
->andReturn(false);
$sessionHandler = Mockery::mock(SessionHandler::class);
$refundProcessor = Mockery::mock(RefundProcessor::class);
$onboardingState = Mockery::mock(State::class);
$onboardingState
->expects('current_state')
->andReturn($currentState);
$transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$subscriptionHelper = Mockery::mock(SubscriptionHelper::class);
$testee = new PayPalGateway(
$settingsRenderer,
$orderProcessor,
$authorizedOrdersProcessor,
$authorizeOrderActionNotice,
$config,
$sessionHandler,
$refundProcessor,
$onboardingState,
$transactionUrlProvider,
$subscriptionHelper
);
$this->assertSame($needSetup, $testee->needs_setup());
}
public function dataForTestCaptureAuthorizedPaymentNoActionableFailures() : array public function dataForTestCaptureAuthorizedPaymentNoActionableFailures() : array
{ {
@ -383,4 +423,13 @@ class WcGatewayTest extends TestCase
], ],
]; ];
} }
public function dataForTestNeedsSetup(): array
{
return [
[State::STATE_START, true],
[State::STATE_PROGRESSIVE, true],
[State::STATE_ONBOARDED, false]
];
}
} }

View file

@ -3,13 +3,13 @@
* Plugin Name: WooCommerce PayPal Payments * Plugin Name: WooCommerce PayPal Payments
* Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/ * Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
* Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage. * Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
* Version: 1.3.2 * Version: 1.4.0
* Author: WooCommerce * Author: WooCommerce
* Author URI: https://woocommerce.com/ * Author URI: https://woocommerce.com/
* License: GPL-2.0 * License: GPL-2.0
* Requires PHP: 7.1 * Requires PHP: 7.1
* WC requires at least: 3.9 * WC requires at least: 3.9
* WC tested up to: 4.9 * WC tested up to: 5.5
* Text Domain: woocommerce-paypal-payments * Text Domain: woocommerce-paypal-payments
* *
* @package WooCommerce\PayPalCommerce * @package WooCommerce\PayPalCommerce
@ -77,6 +77,11 @@ define( 'PPCP_FLAG_SUBSCRIPTION', true );
$modules[] = ( require $module_file )(); $modules[] = ( require $module_file )();
} }
$providers = array(); $providers = array();
// Use this filter to add custom module or remove some of existing ones.
// Modules able to access container, add services and modify existing ones.
$modules = apply_filters( 'woocommerce_paypal_payments_modules', $modules );
foreach ( $modules as $module ) { foreach ( $modules as $module ) {
/* @var $module ModuleInterface module */ /* @var $module ModuleInterface module */
$providers[] = $module->setup(); $providers[] = $module->setup();