mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-30 05:00:51 +08:00
Fix merge conflict
This commit is contained in:
commit
57581a5ac4
60 changed files with 3143 additions and 369 deletions
|
@ -16,10 +16,13 @@ use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
|||
|
||||
return function (
|
||||
string $root_dir,
|
||||
ContainerInterface ...$additional_containers
|
||||
array $additional_containers = array(),
|
||||
array $additional_modules = array()
|
||||
): ContainerInterface {
|
||||
$modules = ( require "$root_dir/modules.php" )( $root_dir );
|
||||
|
||||
$modules = array_merge( $modules, $additional_modules );
|
||||
|
||||
/**
|
||||
* Use this filter to add custom module or remove some of existing ones.
|
||||
* Modules able to access container, add services and modify existing ones.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
*** Changelog ***
|
||||
|
||||
= 2.0.3 - TBD =
|
||||
= 2.0.3 - 2023-03-14 =
|
||||
* Fix - `DEVICE_DATA_NOT_AVAILABLE` error message when FraudNet is enabled #1177
|
||||
* Fix - Redirect to connection tab after manual credentials input #1201
|
||||
* Fix - Asking for address fields in checkout when not using them #1089
|
||||
|
@ -9,6 +9,9 @@
|
|||
* Fix - After Updating to 2.0.2, Site Health reports REST API error #1195
|
||||
* Fix - Do not send buyer-country for previews in live mode to avoid error #1186
|
||||
* Fix - PPEC compatibility layer does not take over subscriptions #1193
|
||||
* Fix - Checkout conflict with "All products for subscriptions" plugin #629
|
||||
* Fix - Pay Later on order pay page #1214
|
||||
* Fix - High volume of traffic from merchant-integrations endpoint #1241
|
||||
* Enhancement - Save checkout form before free trial redirect #1135
|
||||
* Enhancement - Add filter for controlling the ditching of items/breakdown #1146
|
||||
* Enhancement - Add patch order data filter #1147
|
||||
|
|
|
@ -175,12 +175,12 @@ class WebhookEndpoint {
|
|||
*
|
||||
* @param Webhook $hook The webhook to delete.
|
||||
*
|
||||
* @return bool
|
||||
* @throws RuntimeException If the request fails.
|
||||
* @throws PayPalApiException If the request fails.
|
||||
*/
|
||||
public function delete( Webhook $hook ): bool {
|
||||
public function delete( Webhook $hook ): void {
|
||||
if ( ! $hook->id() ) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
|
@ -198,7 +198,18 @@ class WebhookEndpoint {
|
|||
__( 'Not able to delete the webhook.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
return wp_remote_retrieve_response_code( $response ) === 204;
|
||||
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 204 !== $status_code ) {
|
||||
$json = null;
|
||||
if ( is_array( $response ) ) {
|
||||
$json = json_decode( $response['body'] );
|
||||
}
|
||||
throw new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -58,7 +58,7 @@ class ItemFactory {
|
|||
mb_substr( $product->get_name(), 0, 127 ),
|
||||
new Money( $price, $this->currency ),
|
||||
$quantity,
|
||||
substr( wp_strip_all_tags( $product->get_description() ), 0, 127 ) ?: '',
|
||||
$this->prepare_description( $product->get_description() ),
|
||||
null,
|
||||
$product->get_sku(),
|
||||
( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
|
||||
|
@ -130,7 +130,7 @@ class ItemFactory {
|
|||
mb_substr( $item->get_name(), 0, 127 ),
|
||||
new Money( $price_without_tax_rounded, $currency ),
|
||||
$quantity,
|
||||
substr( wp_strip_all_tags( $product instanceof WC_Product ? $product->get_description() : '' ), 0, 127 ) ?: '',
|
||||
$product instanceof WC_Product ? $this->prepare_description( $product->get_description() ) : '',
|
||||
null,
|
||||
$product instanceof WC_Product ? $product->get_sku() : '',
|
||||
( $product instanceof WC_Product && $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
|
||||
|
@ -198,4 +198,15 @@ class ItemFactory {
|
|||
$category
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanups the description and prepares it for sending to PayPal.
|
||||
*
|
||||
* @param string $description Item description.
|
||||
* @return string
|
||||
*/
|
||||
protected function prepare_description( string $description ): string {
|
||||
$description = strip_shortcodes( wp_strip_all_tags( $description ) );
|
||||
return substr( $description, 0, 127 ) ?: '';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import PayNowBootstrap from "./modules/ContextBootstrap/PayNowBootstrap";
|
|||
import Renderer from './modules/Renderer/Renderer';
|
||||
import ErrorHandler from './modules/ErrorHandler';
|
||||
import CreditCardRenderer from "./modules/Renderer/CreditCardRenderer";
|
||||
import dataClientIdAttributeHandler from "./modules/DataClientIdAttributeHandler";
|
||||
import MessageRenderer from "./modules/Renderer/MessageRenderer";
|
||||
import Spinner from "./modules/Helper/Spinner";
|
||||
import {
|
||||
|
@ -19,6 +18,7 @@ import {isChangePaymentPage} from "./modules/Helper/Subscriptions";
|
|||
import FreeTrialHandler from "./modules/ActionHandler/FreeTrialHandler";
|
||||
import FormSaver from './modules/Helper/FormSaver';
|
||||
import FormValidator from "./modules/Helper/FormValidator";
|
||||
import {loadPaypalScript} from "./modules/Helper/ScriptLoading";
|
||||
|
||||
// TODO: could be a good idea to have a separate spinner for each gateway,
|
||||
// but I think we care mainly about the script loading, so one spinner should be enough.
|
||||
|
@ -258,24 +258,10 @@ document.addEventListener(
|
|||
hideOrderButtonIfPpcpGateway();
|
||||
});
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.addEventListener('load', (event) => {
|
||||
loadPaypalScript(PayPalCommerceGateway, () => {
|
||||
bootstrapped = true;
|
||||
|
||||
bootstrap();
|
||||
});
|
||||
script.setAttribute('src', PayPalCommerceGateway.button.url);
|
||||
Object.entries(PayPalCommerceGateway.script_attributes).forEach(
|
||||
(keyValue) => {
|
||||
script.setAttribute(keyValue[0], keyValue[1]);
|
||||
}
|
||||
);
|
||||
|
||||
if (PayPalCommerceGateway.data_client_id.set_attribute) {
|
||||
dataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.appendChild(script);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -9,31 +9,17 @@ class SingleProductActionHandler {
|
|||
constructor(
|
||||
config,
|
||||
updateCart,
|
||||
showButtonCallback,
|
||||
hideButtonCallback,
|
||||
formElement,
|
||||
errorHandler
|
||||
) {
|
||||
this.config = config;
|
||||
this.updateCart = updateCart;
|
||||
this.showButtonCallback = showButtonCallback;
|
||||
this.hideButtonCallback = hideButtonCallback;
|
||||
this.formElement = formElement;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
configuration()
|
||||
{
|
||||
|
||||
if ( this.hasVariations() ) {
|
||||
const observer = new ButtonsToggleListener(
|
||||
this.formElement.querySelector('.single_add_to_cart_button'),
|
||||
this.showButtonCallback,
|
||||
this.hideButtonCallback
|
||||
);
|
||||
observer.init();
|
||||
}
|
||||
|
||||
return {
|
||||
createOrder: this.createOrder(),
|
||||
onApprove: onApprove(this, this.errorHandler),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import CartActionHandler from '../ActionHandler/CartActionHandler';
|
||||
import {setVisible} from "../Helper/Hiding";
|
||||
|
||||
class CartBootstrap {
|
||||
constructor(gateway, renderer, errorHandler) {
|
||||
|
@ -16,13 +17,31 @@ class CartBootstrap {
|
|||
|
||||
jQuery(document.body).on('updated_cart_totals updated_checkout', () => {
|
||||
this.render();
|
||||
|
||||
fetch(
|
||||
this.gateway.ajax.cart_script_params.endpoint,
|
||||
{
|
||||
method: 'GET',
|
||||
credentials: 'same-origin',
|
||||
}
|
||||
)
|
||||
.then(result => result.json())
|
||||
.then(result => {
|
||||
if (! result.success) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newParams = result.data;
|
||||
const reloadRequired = this.gateway.url_params.intent !== newParams.intent;
|
||||
|
||||
// TODO: should reload the script instead
|
||||
setVisible(this.gateway.button.wrapper, !reloadRequired)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
shouldRender() {
|
||||
return document.querySelector(this.gateway.button.wrapper) !==
|
||||
null || document.querySelector(this.gateway.hosted_fields.wrapper) !==
|
||||
null;
|
||||
return document.querySelector(this.gateway.button.wrapper) !== null;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import UpdateCart from "../Helper/UpdateCart";
|
||||
import SingleProductActionHandler from "../ActionHandler/SingleProductActionHandler";
|
||||
import {hide, show, setVisible} from "../Helper/Hiding";
|
||||
import ButtonsToggleListener from "../Helper/ButtonsToggleListener";
|
||||
|
||||
class SingleProductBootstap {
|
||||
constructor(gateway, renderer, messages, errorHandler) {
|
||||
|
@ -12,10 +14,10 @@ class SingleProductBootstap {
|
|||
|
||||
|
||||
handleChange() {
|
||||
if (!this.shouldRender()) {
|
||||
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
||||
this.renderer.hideButtons(this.gateway.button.wrapper);
|
||||
this.messages.hideMessages();
|
||||
const shouldRender = this.shouldRender();
|
||||
setVisible(this.gateway.button.wrapper, shouldRender);
|
||||
setVisible(this.gateway.messages.wrapper, shouldRender);
|
||||
if (!shouldRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -23,7 +25,6 @@ class SingleProductBootstap {
|
|||
}
|
||||
|
||||
init() {
|
||||
|
||||
const form = document.querySelector('form.cart');
|
||||
if (!form) {
|
||||
return;
|
||||
|
@ -32,20 +33,33 @@ class SingleProductBootstap {
|
|||
form.addEventListener('change', this.handleChange.bind(this));
|
||||
this.mutationObserver.observe(form, {childList: true, subtree: true});
|
||||
|
||||
const buttonObserver = new ButtonsToggleListener(
|
||||
form.querySelector('.single_add_to_cart_button'),
|
||||
() => {
|
||||
show(this.gateway.button.wrapper);
|
||||
show(this.gateway.messages.wrapper);
|
||||
this.messages.renderWithAmount(this.priceAmount())
|
||||
},
|
||||
() => {
|
||||
hide(this.gateway.button.wrapper);
|
||||
hide(this.gateway.messages.wrapper);
|
||||
},
|
||||
);
|
||||
buttonObserver.init();
|
||||
|
||||
if (!this.shouldRender()) {
|
||||
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
||||
this.messages.hideMessages();
|
||||
hide(this.gateway.button.wrapper);
|
||||
hide(this.gateway.messages.wrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
this.render();
|
||||
|
||||
}
|
||||
|
||||
shouldRender() {
|
||||
|
||||
return document.querySelector('form.cart') !== null && !this.priceAmountIsZero();
|
||||
|
||||
return document.querySelector('form.cart') !== null
|
||||
&& !this.priceAmountIsZero()
|
||||
&& !this.isSubscriptionMode();
|
||||
}
|
||||
|
||||
priceAmount() {
|
||||
|
@ -55,8 +69,13 @@ class SingleProductBootstap {
|
|||
() => {
|
||||
const priceEl = document.querySelector('.product .woocommerce-Price-amount');
|
||||
// variable products show price like 10.00 - 20.00 here
|
||||
if (priceEl && priceEl.parentElement.querySelectorAll('.woocommerce-Price-amount').length === 1) {
|
||||
return priceEl.innerText;
|
||||
// but the second price also can be the suffix with the price incl/excl tax
|
||||
if (priceEl) {
|
||||
const allPriceElements = Array.from(priceEl.parentElement.querySelectorAll('.woocommerce-Price-amount'))
|
||||
.filter(el => !el.parentElement.classList.contains('woocommerce-price-suffix'));
|
||||
if (allPriceElements.length === 1) {
|
||||
return priceEl.innerText;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
@ -74,6 +93,12 @@ class SingleProductBootstap {
|
|||
return !price || price === 0;
|
||||
}
|
||||
|
||||
isSubscriptionMode() {
|
||||
// Check "All products for subscriptions" plugin.
|
||||
return document.querySelector('.wcsatt-options-product:not(.wcsatt-options-product--hidden) .subscription-option input[type="radio"]:checked') !== null
|
||||
|| document.querySelector('.wcsatt-options-prompt-label-subscription input[type="radio"]:checked') !== null; // grouped
|
||||
}
|
||||
|
||||
render() {
|
||||
const actionHandler = new SingleProductActionHandler(
|
||||
this.gateway,
|
||||
|
@ -81,16 +106,6 @@ class SingleProductBootstap {
|
|||
this.gateway.ajax.change_cart.endpoint,
|
||||
this.gateway.ajax.change_cart.nonce,
|
||||
),
|
||||
() => {
|
||||
this.renderer.showButtons(this.gateway.button.wrapper);
|
||||
this.renderer.showButtons(this.gateway.hosted_fields.wrapper);
|
||||
this.messages.renderWithAmount(this.priceAmount())
|
||||
},
|
||||
() => {
|
||||
this.renderer.hideButtons(this.gateway.button.wrapper);
|
||||
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
||||
this.messages.hideMessages();
|
||||
},
|
||||
document.querySelector('form.cart'),
|
||||
this.errorHandler,
|
||||
);
|
||||
|
|
|
@ -14,6 +14,9 @@ class ButtonsToggleListener {
|
|||
|
||||
init()
|
||||
{
|
||||
if (!this.element) {
|
||||
return;
|
||||
}
|
||||
const config = { attributes : true };
|
||||
const callback = () => {
|
||||
if (this.element.classList.contains('disabled')) {
|
||||
|
@ -33,4 +36,4 @@ class ButtonsToggleListener {
|
|||
}
|
||||
}
|
||||
|
||||
export default ButtonsToggleListener;
|
||||
export default ButtonsToggleListener;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import dataClientIdAttributeHandler from "../DataClientIdAttributeHandler";
|
||||
|
||||
export const loadPaypalScript = (config, onLoaded) => {
|
||||
if (typeof paypal !== 'undefined') {
|
||||
onLoaded();
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.addEventListener('load', onLoaded);
|
||||
script.setAttribute('src', config.url);
|
||||
Object.entries(config.script_attributes).forEach(
|
||||
(keyValue) => {
|
||||
script.setAttribute(keyValue[0], keyValue[1]);
|
||||
}
|
||||
);
|
||||
|
||||
if (config.data_client_id.set_attribute) {
|
||||
dataClientIdAttributeHandler(script, config.data_client_id);
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.appendChild(script);
|
||||
}
|
|
@ -53,14 +53,5 @@ class MessageRenderer {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
hideMessages() {
|
||||
const domElement = document.querySelector(this.config.wrapper);
|
||||
if (! domElement ) {
|
||||
return false;
|
||||
}
|
||||
domElement.style.display = 'none';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export default MessageRenderer;
|
||||
|
|
|
@ -99,24 +99,6 @@ class Renderer {
|
|||
return this.renderedSources.has(wrapper + fundingSource ?? '');
|
||||
}
|
||||
|
||||
hideButtons(element) {
|
||||
const domElement = document.querySelector(element);
|
||||
if (! domElement ) {
|
||||
return false;
|
||||
}
|
||||
domElement.style.display = 'none';
|
||||
return true;
|
||||
}
|
||||
|
||||
showButtons(element) {
|
||||
const domElement = document.querySelector(element);
|
||||
if (! domElement ) {
|
||||
return false;
|
||||
}
|
||||
domElement.style.display = 'block';
|
||||
return true;
|
||||
}
|
||||
|
||||
disableCreditCardFields() {
|
||||
this.creditCardRenderer.disableFields();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Button;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\CartScriptParamsEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\CheckoutFormSaver;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\SaveCheckoutFormEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Validation\CheckoutFormValidator;
|
||||
|
@ -220,6 +221,12 @@ return array(
|
|||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'button.endpoint.cart-script-params' => static function ( ContainerInterface $container ): CartScriptParamsEndpoint {
|
||||
return new CartScriptParamsEndpoint(
|
||||
$container->get( 'button.smart-button' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'button.helper.three-d-secure' => static function ( ContainerInterface $container ): ThreeDSecure {
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new ThreeDSecure( $logger );
|
||||
|
|
|
@ -24,12 +24,16 @@ class DisabledSmartButton implements SmartButtonInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Enqueues necessary scripts.
|
||||
*
|
||||
* @return bool
|
||||
* Whether the scripts should be loaded.
|
||||
*/
|
||||
public function enqueue(): bool {
|
||||
return true;
|
||||
public function should_load(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues necessary scripts.
|
||||
*/
|
||||
public function enqueue(): void {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,4 +45,13 @@ class DisabledSmartButton implements SmartButtonInterface {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The configuration for the smart buttons.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function script_data(): array {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\ApproveOrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\CartScriptParamsEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\CreateOrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\DataClientIdEndpoint;
|
||||
|
@ -405,7 +406,7 @@ class SmartButton implements SmartButtonInterface {
|
|||
add_action(
|
||||
$this->pay_order_renderer_hook(),
|
||||
array( $this, 'message_renderer' ),
|
||||
11
|
||||
15
|
||||
);
|
||||
}
|
||||
return true;
|
||||
|
@ -478,7 +479,8 @@ class SmartButton implements SmartButtonInterface {
|
|||
function (): void {
|
||||
$this->button_renderer( PayPalGateway::ID );
|
||||
$this->button_renderer( CardButtonGateway::ID );
|
||||
}
|
||||
},
|
||||
20
|
||||
);
|
||||
add_action(
|
||||
$this->checkout_button_renderer_hook(),
|
||||
|
@ -506,17 +508,25 @@ class SmartButton implements SmartButtonInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Enqueues the script.
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
* Whether the scripts should be loaded.
|
||||
*/
|
||||
public function enqueue(): bool {
|
||||
public function should_load(): bool {
|
||||
$buttons_enabled = $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' );
|
||||
if ( ! is_checkout() && ! $buttons_enabled ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the scripts.
|
||||
*/
|
||||
public function enqueue(): void {
|
||||
if ( ! $this->should_load() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$load_script = false;
|
||||
if ( is_checkout() && $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
|
||||
$load_script = true;
|
||||
|
@ -554,10 +564,9 @@ class SmartButton implements SmartButtonInterface {
|
|||
wp_localize_script(
|
||||
'ppcp-smart-button',
|
||||
'PayPalCommerceGateway',
|
||||
$this->localize_script()
|
||||
$this->script_data()
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -751,18 +760,22 @@ class SmartButton implements SmartButtonInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* The localized data for the smart button.
|
||||
* The configuration for the smart buttons.
|
||||
*
|
||||
* @return array
|
||||
* @throws NotFoundException If a setting hasn't been found.
|
||||
*/
|
||||
private function localize_script(): array {
|
||||
public function script_data(): array {
|
||||
global $wp;
|
||||
|
||||
$is_free_trial_cart = $this->is_free_trial_cart();
|
||||
|
||||
$url_params = $this->url_params();
|
||||
|
||||
$this->request_data->enqueue_nonce_fix();
|
||||
$localize = array(
|
||||
'url' => add_query_arg( $url_params, 'https://www.paypal.com/sdk/js' ),
|
||||
'url_params' => $url_params,
|
||||
'script_attributes' => $this->attributes(),
|
||||
'data_client_id' => array(
|
||||
'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() ) || $this->can_save_vault_token(),
|
||||
|
@ -798,6 +811,9 @@ class SmartButton implements SmartButtonInterface {
|
|||
'endpoint' => \WC_AJAX::get_endpoint( ValidateCheckoutEndpoint::ENDPOINT ),
|
||||
'nonce' => wp_create_nonce( ValidateCheckoutEndpoint::nonce() ),
|
||||
),
|
||||
'cart_script_params' => array(
|
||||
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
|
||||
),
|
||||
),
|
||||
'enforce_vault' => $this->has_subscriptions(),
|
||||
'can_save_vault_token' => $this->can_save_vault_token(),
|
||||
|
@ -809,7 +825,6 @@ class SmartButton implements SmartButtonInterface {
|
|||
'wrapper' => '#ppc-button-' . PayPalGateway::ID,
|
||||
'mini_cart_wrapper' => '#ppc-button-minicart',
|
||||
'cancel_wrapper' => '#ppcp-cancel',
|
||||
'url' => $this->url(),
|
||||
'mini_cart_style' => array(
|
||||
'layout' => $this->style_for_context( 'layout', 'mini-cart' ),
|
||||
'color' => $this->style_for_context( 'color', 'mini-cart' ),
|
||||
|
@ -916,12 +931,12 @@ class SmartButton implements SmartButtonInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* The JavaScript SDK url to load.
|
||||
* The JavaScript SDK url parameters.
|
||||
*
|
||||
* @return string
|
||||
* @return array
|
||||
* @throws NotFoundException If a setting was not found.
|
||||
*/
|
||||
private function url(): string {
|
||||
private function url_params(): array {
|
||||
$intent = ( $this->settings->has( 'intent' ) ) ? $this->settings->get( 'intent' ) : 'capture';
|
||||
$product_intent = $this->subscription_helper->current_product_is_subscription() ? 'authorize' : $intent;
|
||||
$other_context_intent = $this->subscription_helper->cart_contains_subscription() ? 'authorize' : $intent;
|
||||
|
@ -972,19 +987,20 @@ class SmartButton implements SmartButtonInterface {
|
|||
$disable_funding = $all_sources;
|
||||
}
|
||||
|
||||
if ( ! $this->settings_status->is_pay_later_button_enabled_for_context( $this->context() ) ) {
|
||||
$disable_funding[] = 'credit';
|
||||
$enable_funding = array( 'venmo' );
|
||||
|
||||
if ( $this->settings_status->is_pay_later_button_enabled_for_location( $this->context() ) ||
|
||||
$this->settings_status->is_pay_later_messaging_enabled_for_location( $this->context() )
|
||||
) {
|
||||
$enable_funding[] = 'paylater';
|
||||
} else {
|
||||
$disable_funding[] = 'paylater';
|
||||
}
|
||||
|
||||
if ( count( $disable_funding ) > 0 ) {
|
||||
$params['disable-funding'] = implode( ',', array_unique( $disable_funding ) );
|
||||
}
|
||||
|
||||
$enable_funding = array( 'venmo' );
|
||||
if ( $this->settings_status->is_pay_later_messaging_enabled_for_location( $this->context() ) || ! in_array( 'credit', $disable_funding, true ) ) {
|
||||
$enable_funding[] = 'paylater';
|
||||
}
|
||||
|
||||
if ( $this->is_free_trial_cart() ) {
|
||||
$enable_funding = array();
|
||||
}
|
||||
|
@ -993,8 +1009,7 @@ class SmartButton implements SmartButtonInterface {
|
|||
$params['enable-funding'] = implode( ',', array_unique( $enable_funding ) );
|
||||
}
|
||||
|
||||
$smart_button_url = add_query_arg( $params, 'https://www.paypal.com/sdk/js' );
|
||||
return $smart_button_url;
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1074,11 +1089,10 @@ class SmartButton implements SmartButtonInterface {
|
|||
switch ( $this->context() ) {
|
||||
case 'checkout':
|
||||
case 'cart':
|
||||
case 'pay-now':
|
||||
return $smart_button_enabled_for_current_location || $messaging_enabled_for_current_location;
|
||||
case 'product':
|
||||
return $smart_button_enabled_for_current_location || $messaging_enabled_for_current_location || $smart_button_enabled_for_mini_cart;
|
||||
case 'pay-now':
|
||||
return true;
|
||||
default:
|
||||
return $smart_button_enabled_for_mini_cart;
|
||||
}
|
||||
|
|
|
@ -22,11 +22,14 @@ interface SmartButtonInterface {
|
|||
public function render_wrapper(): bool;
|
||||
|
||||
/**
|
||||
* Enqueues the necessary scripts.
|
||||
*
|
||||
* @return bool
|
||||
* Whether the scripts should be loaded.
|
||||
*/
|
||||
public function enqueue(): bool;
|
||||
public function should_load(): bool;
|
||||
|
||||
/**
|
||||
* Enqueues the necessary scripts.
|
||||
*/
|
||||
public function enqueue(): void;
|
||||
|
||||
/**
|
||||
* Whether the running installation could save vault tokens or not.
|
||||
|
@ -34,4 +37,11 @@ interface SmartButtonInterface {
|
|||
* @return bool
|
||||
*/
|
||||
public function can_save_vault_token(): bool;
|
||||
|
||||
/**
|
||||
* The configuration for the smart buttons.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function script_data(): array;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Button;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\CartScriptParamsEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\SaveCheckoutFormEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\ValidateCheckoutEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||
|
@ -177,6 +178,15 @@ class ButtonModule implements ModuleInterface {
|
|||
$endpoint->handle_request();
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'wc_ajax_' . CartScriptParamsEndpoint::ENDPOINT,
|
||||
static function () use ( $container ) {
|
||||
$endpoint = $container->get( 'button.endpoint.cart-script-params' );
|
||||
assert( $endpoint instanceof CartScriptParamsEndpoint );
|
||||
$endpoint->handle_request();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
/**
|
||||
* The endpoint for returning the PayPal SDK Script parameters for the current cart.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Button\Endpoint
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Button\Endpoint;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
|
||||
|
||||
/**
|
||||
* Class CartScriptParamsEndpoint.
|
||||
*/
|
||||
class CartScriptParamsEndpoint implements EndpointInterface {
|
||||
|
||||
|
||||
const ENDPOINT = 'ppc-cart-script-params';
|
||||
|
||||
/**
|
||||
* The SmartButton.
|
||||
*
|
||||
* @var SmartButton
|
||||
*/
|
||||
private $smart_button;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* CartScriptParamsEndpoint constructor.
|
||||
*
|
||||
* @param SmartButton $smart_button he SmartButton.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
SmartButton $smart_button,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->smart_button = $smart_button;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nonce.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function nonce(): string {
|
||||
return self::ENDPOINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle_request(): bool {
|
||||
try {
|
||||
$script_data = $this->smart_button->script_data();
|
||||
|
||||
wp_send_json_success( $script_data['url_params'] );
|
||||
|
||||
return true;
|
||||
} catch ( Throwable $error ) {
|
||||
$this->logger->error( "CartScriptParamsEndpoint execution failed. {$error->getMessage()} {$error->getFile()}:{$error->getLine()}" );
|
||||
|
||||
wp_send_json_error();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1723,9 +1723,9 @@ loader-runner@^4.2.0:
|
|||
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
|
||||
|
||||
loader-utils@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
|
||||
integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
|
||||
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
|
||||
dependencies:
|
||||
big.js "^5.2.2"
|
||||
emojis-list "^3.0.0"
|
||||
|
|
|
@ -184,14 +184,14 @@ class SubscriptionsHandler {
|
|||
}
|
||||
|
||||
// Are we on the WC > Subscriptions screen?
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
// phpcs:ignore WordPress.Security.NonceVerification
|
||||
$post_type = wc_clean( wp_unslash( $_GET['post_type'] ?? $_POST['post_type'] ?? '' ) );
|
||||
if ( $post_type === 'shop_subscription' ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Are we editing an order or subscription tied to PPEC?
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
// phpcs:ignore WordPress.Security.NonceVerification
|
||||
$order_id = wc_clean( wp_unslash( $_GET['post'] ?? $_POST['post_ID'] ?? '' ) );
|
||||
if ( $order_id ) {
|
||||
$order = wc_get_order( $order_id );
|
||||
|
|
|
@ -1702,9 +1702,9 @@ loader-runner@^4.2.0:
|
|||
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
|
||||
|
||||
loader-utils@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
|
||||
integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
|
||||
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
|
||||
dependencies:
|
||||
big.js "^5.2.2"
|
||||
emojis-list "^3.0.0"
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\Onboarding;
|
|||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar;
|
||||
|
||||
/**
|
||||
* Exposes and handles REST routes related to onboarding.
|
||||
|
@ -249,7 +250,7 @@ class OnboardingRESTController {
|
|||
}
|
||||
|
||||
$webhook_registrar = $this->container->get( 'webhook.registrar' );
|
||||
$webhook_registrar->unregister();
|
||||
assert( $webhook_registrar instanceof WebhookRegistrar );
|
||||
$webhook_registrar->register();
|
||||
|
||||
return array();
|
||||
|
|
|
@ -1702,9 +1702,9 @@ loader-runner@^4.2.0:
|
|||
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
|
||||
|
||||
loader-utils@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
|
||||
integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
|
||||
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
|
||||
dependencies:
|
||||
big.js "^5.2.2"
|
||||
emojis-list "^3.0.0"
|
||||
|
|
|
@ -1805,9 +1805,9 @@ loader-runner@^4.2.0:
|
|||
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
|
||||
|
||||
loader-utils@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
|
||||
integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
|
||||
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
|
||||
dependencies:
|
||||
big.js "^5.2.2"
|
||||
emojis-list "^3.0.0"
|
||||
|
|
|
@ -20,7 +20,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
|||
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
||||
use WooCommerce\PayPalCommerce\Compat\PPEC\PPECHelper;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\WebhookInfoStorage;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\WebhookEventStorage;
|
||||
|
||||
/**
|
||||
* Class StatusReportModule
|
||||
|
@ -62,7 +62,7 @@ class StatusReportModule implements ModuleInterface {
|
|||
$messages_apply = $c->get( 'button.helper.messages-apply' );
|
||||
|
||||
$last_webhook_storage = $c->get( 'webhook.last-webhook-storage' );
|
||||
assert( $last_webhook_storage instanceof WebhookInfoStorage );
|
||||
assert( $last_webhook_storage instanceof WebhookEventStorage );
|
||||
|
||||
$billing_agreements_endpoint = $c->get( 'api.endpoint.billing-agreements' );
|
||||
assert( $billing_agreements_endpoint instanceof BillingAgreementsEndpoint );
|
||||
|
|
|
@ -50,7 +50,7 @@ class SubscriptionHelper {
|
|||
if ( ! isset( $item['data'] ) || ! is_a( $item['data'], WC_Product::class ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( $item['data']->is_type( 'subscription' ) || $item['data']->is_type( 'subscription_variation' ) ) {
|
||||
if ( WC_Subscriptions_Product::is_subscription( $item['data'] ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1805,9 +1805,9 @@ loader-runner@^4.2.0:
|
|||
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
|
||||
|
||||
loader-utils@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
|
||||
integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
|
||||
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
|
||||
dependencies:
|
||||
big.js "^5.2.2"
|
||||
emojis-list "^3.0.0"
|
||||
|
|
2318
modules/ppcp-vaulting/yarn.lock
Normal file
2318
modules/ppcp-vaulting/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
|
@ -336,7 +336,8 @@ return array(
|
|||
$signup_link_cache,
|
||||
$signup_link_ids,
|
||||
$pui_status_cache,
|
||||
$dcc_status_cache
|
||||
$dcc_status_cache,
|
||||
$container->get( 'http.redirector' )
|
||||
);
|
||||
},
|
||||
'wcgateway.order-processor' => static function ( ContainerInterface $container ): OrderProcessor {
|
||||
|
@ -644,7 +645,7 @@ return array(
|
|||
>',
|
||||
'</a>'
|
||||
),
|
||||
'options' => $container->get( 'wcgateway.all-funding-sources' ),
|
||||
'options' => $container->get( 'wcgateway.settings.funding-sources' ),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
|
@ -881,6 +882,17 @@ return array(
|
|||
'sofort' => _x( 'Sofort', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
'venmo' => _x( 'Venmo', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
'trustly' => _x( 'Trustly', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
'paylater' => _x( 'Pay Later', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
);
|
||||
},
|
||||
'wcgateway.settings.funding-sources' => static function( ContainerInterface $container ): array {
|
||||
return array_diff_key(
|
||||
$container->get( 'wcgateway.all-funding-sources' ),
|
||||
array_flip(
|
||||
array(
|
||||
'paylater',
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -939,7 +951,8 @@ return array(
|
|||
$settings,
|
||||
$partner_endpoint,
|
||||
$container->get( 'dcc.status-cache' ),
|
||||
$container->get( 'api.helpers.dccapplies' )
|
||||
$container->get( 'api.helpers.dccapplies' ),
|
||||
$container->get( 'onboarding.state' )
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -951,9 +964,11 @@ return array(
|
|||
|
||||
'wcgateway.funding-source.renderer' => function ( ContainerInterface $container ) : FundingSourceRenderer {
|
||||
return new FundingSourceRenderer(
|
||||
$container->get( 'wcgateway.settings' )
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'wcgateway.all-funding-sources' )
|
||||
);
|
||||
},
|
||||
|
||||
'wcgateway.checkout-helper' => static function ( ContainerInterface $container ): CheckoutHelper {
|
||||
return new CheckoutHelper();
|
||||
},
|
||||
|
@ -1007,7 +1022,8 @@ return array(
|
|||
return new PayUponInvoiceProductStatus(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'api.endpoint.partners' ),
|
||||
$container->get( 'pui.status-cache' )
|
||||
$container->get( 'pui.status-cache' ),
|
||||
$container->get( 'onboarding.state' )
|
||||
);
|
||||
},
|
||||
'wcgateway.pay-upon-invoice' => static function ( ContainerInterface $container ): PayUponInvoice {
|
||||
|
@ -1254,7 +1270,7 @@ return array(
|
|||
|
||||
$dcc_enabled = $dcc_product_status->dcc_is_active();
|
||||
|
||||
$enabled_status_text = esc_html__( 'Status: Enabled', 'woocommerce-paypal-payments' );
|
||||
$enabled_status_text = esc_html__( 'Status: Available', 'woocommerce-paypal-payments' );
|
||||
$disabled_status_text = esc_html__( 'Status: Not yet enabled', 'woocommerce-paypal-payments' );
|
||||
|
||||
$dcc_button_text = $dcc_enabled
|
||||
|
@ -1287,7 +1303,7 @@ return array(
|
|||
|
||||
$pui_enabled = $pui_product_status->pui_is_active();
|
||||
|
||||
$enabled_status_text = esc_html__( 'Status: Enabled', 'woocommerce-paypal-payments' );
|
||||
$enabled_status_text = esc_html__( 'Status: Available', 'woocommerce-paypal-payments' );
|
||||
$disabled_status_text = esc_html__( 'Status: Not yet enabled', 'woocommerce-paypal-payments' );
|
||||
|
||||
$enable_pui_url = $environment->current_environment_is( Environment::PRODUCTION )
|
||||
|
@ -1338,24 +1354,10 @@ return array(
|
|||
assert( $settings instanceof Settings );
|
||||
|
||||
$button_locations = $container->get( 'wcgateway.button.locations' );
|
||||
unset( $button_locations['mini-cart'] );
|
||||
|
||||
$smart_button_selected_locations = $settings->has( 'smart_button_locations' ) ? $settings->get( 'smart_button_locations' ) : array();
|
||||
$pay_later_button_locations = array();
|
||||
|
||||
if ( empty( $smart_button_selected_locations ) ) {
|
||||
return $pay_later_button_locations;
|
||||
}
|
||||
|
||||
foreach ( $button_locations as $location_key => $location ) {
|
||||
if ( ! in_array( $location_key, $smart_button_selected_locations, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pay_later_button_locations[ $location_key ] = $location;
|
||||
}
|
||||
|
||||
return $pay_later_button_locations;
|
||||
return array_intersect_key( $button_locations, array_flip( $smart_button_selected_locations ) );
|
||||
},
|
||||
'wcgateway.ppcp-gateways' => static function ( ContainerInterface $container ): array {
|
||||
return array(
|
||||
|
|
|
@ -22,13 +22,32 @@ class FundingSourceRenderer {
|
|||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Map funding source ID -> human-readable name.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $funding_sources;
|
||||
|
||||
/**
|
||||
* The IDs of the sources belonging to PayPal that do not need to mention "via PayPal".
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $own_funding_sources = array( 'venmo', 'paylater' );
|
||||
|
||||
/**
|
||||
* FundingSourceRenderer constructor.
|
||||
*
|
||||
* @param ContainerInterface $settings The settings.
|
||||
* @param ContainerInterface $settings The settings.
|
||||
* @param array<string, string> $funding_sources Map funding source ID -> human-readable name.
|
||||
*/
|
||||
public function __construct( ContainerInterface $settings ) {
|
||||
$this->settings = $settings;
|
||||
public function __construct(
|
||||
ContainerInterface $settings,
|
||||
array $funding_sources
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->funding_sources = $funding_sources;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,9 +56,17 @@ class FundingSourceRenderer {
|
|||
* @param string $id The ID of the funding source, such as 'venmo'.
|
||||
*/
|
||||
public function render_name( string $id ): string {
|
||||
if ( 'venmo' === $id ) {
|
||||
return __( 'Venmo', 'woocommerce-paypal-payments' );
|
||||
if ( array_key_exists( $id, $this->funding_sources ) ) {
|
||||
if ( in_array( $id, $this->own_funding_sources, true ) ) {
|
||||
return $this->funding_sources[ $id ];
|
||||
}
|
||||
return sprintf(
|
||||
/* translators: %s - Sofort, BLIK, iDeal, Mercado Pago, etc. */
|
||||
__( '%s (via PayPal)', 'woocommerce-paypal-payments' ),
|
||||
$this->funding_sources[ $id ]
|
||||
);
|
||||
}
|
||||
|
||||
return $this->settings->has( 'title' ) ?
|
||||
$this->settings->get( 'title' )
|
||||
: __( 'PayPal', 'woocommerce-paypal-payments' );
|
||||
|
@ -51,9 +78,14 @@ class FundingSourceRenderer {
|
|||
* @param string $id The ID of the funding source, such as 'venmo'.
|
||||
*/
|
||||
public function render_description( string $id ): string {
|
||||
if ( 'venmo' === $id ) {
|
||||
return __( 'Pay via Venmo.', 'woocommerce-paypal-payments' );
|
||||
if ( array_key_exists( $id, $this->funding_sources ) ) {
|
||||
return sprintf(
|
||||
/* translators: %s - Sofort, BLIK, iDeal, Mercado Pago, etc. */
|
||||
__( 'Pay via %s.', 'woocommerce-paypal-payments' ),
|
||||
$this->funding_sources[ $id ]
|
||||
);
|
||||
}
|
||||
|
||||
return $this->settings->has( 'description' ) ?
|
||||
$this->settings->get( 'description' )
|
||||
: __( 'Pay via PayPal.', 'woocommerce-paypal-payments' );
|
||||
|
|
|
@ -14,6 +14,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
|
@ -57,6 +58,13 @@ class DCCProductStatus {
|
|||
*/
|
||||
protected $dcc_applies;
|
||||
|
||||
/**
|
||||
* The onboarding state.
|
||||
*
|
||||
* @var State
|
||||
*/
|
||||
private $onboarding_state;
|
||||
|
||||
/**
|
||||
* DccProductStatus constructor.
|
||||
*
|
||||
|
@ -64,17 +72,20 @@ class DCCProductStatus {
|
|||
* @param PartnersEndpoint $partners_endpoint The Partner Endpoint.
|
||||
* @param Cache $cache The cache.
|
||||
* @param DccApplies $dcc_applies The dcc applies helper.
|
||||
* @param State $onboarding_state The onboarding state.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
PartnersEndpoint $partners_endpoint,
|
||||
Cache $cache,
|
||||
DccApplies $dcc_applies
|
||||
DccApplies $dcc_applies,
|
||||
State $onboarding_state
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->partners_endpoint = $partners_endpoint;
|
||||
$this->cache = $cache;
|
||||
$this->dcc_applies = $dcc_applies;
|
||||
$this->onboarding_state = $onboarding_state;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,6 +94,10 @@ class DCCProductStatus {
|
|||
* @return bool
|
||||
*/
|
||||
public function dcc_is_active() : bool {
|
||||
if ( $this->onboarding_state->current_state() < State::STATE_ONBOARDED ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->cache->has( self::DCC_STATUS_CACHE_KEY ) ) {
|
||||
return (bool) $this->cache->get( self::DCC_STATUS_CACHE_KEY );
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ use Throwable;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
|
@ -49,21 +50,31 @@ class PayUponInvoiceProductStatus {
|
|||
*/
|
||||
private $partners_endpoint;
|
||||
|
||||
/**
|
||||
* The onboarding status
|
||||
*
|
||||
* @var State
|
||||
*/
|
||||
private $onboarding_state;
|
||||
|
||||
/**
|
||||
* PayUponInvoiceProductStatus constructor.
|
||||
*
|
||||
* @param Settings $settings The Settings.
|
||||
* @param PartnersEndpoint $partners_endpoint The Partner Endpoint.
|
||||
* @param Cache $cache The cache.
|
||||
* @param State $onboarding_state The onboarding state.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
PartnersEndpoint $partners_endpoint,
|
||||
Cache $cache
|
||||
Cache $cache,
|
||||
State $onboarding_state
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->partners_endpoint = $partners_endpoint;
|
||||
$this->cache = $cache;
|
||||
$this->onboarding_state = $onboarding_state;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,6 +83,10 @@ class PayUponInvoiceProductStatus {
|
|||
* @return bool
|
||||
*/
|
||||
public function pui_is_active() : bool {
|
||||
if ( $this->onboarding_state->current_state() < State::STATE_ONBOARDED ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->cache->has( self::PUI_STATUS_CACHE_KEY ) ) {
|
||||
return (bool) $this->cache->get( self::PUI_STATUS_CACHE_KEY );
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Helper;
|
||||
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
|
@ -37,7 +36,6 @@ class SettingsStatus {
|
|||
* Check whether Pay Later message is enabled either for checkout, cart or product page.
|
||||
*
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_messaging_enabled(): bool {
|
||||
$messaging_enabled = $this->settings->has( 'pay_later_messaging_enabled' ) && $this->settings->get( 'pay_later_messaging_enabled' );
|
||||
|
@ -51,27 +49,15 @@ class SettingsStatus {
|
|||
*
|
||||
* @param string $location The location setting name.
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_messaging_enabled_for_location( string $location ): bool {
|
||||
if ( ! $this->is_pay_later_messaging_enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$selected_locations = $this->settings->has( 'pay_later_messaging_locations' ) ? $this->settings->get( 'pay_later_messaging_locations' ) : array();
|
||||
|
||||
if ( empty( $selected_locations ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array( $location, $selected_locations, true );
|
||||
return $this->is_pay_later_messaging_enabled() && $this->is_enabled_for_location( 'pay_later_messaging_locations', $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether Pay Later button is enabled either for checkout, cart or product page.
|
||||
*
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_button_enabled(): bool {
|
||||
$pay_later_button_enabled = $this->settings->has( 'pay_later_button_enabled' ) && $this->settings->get( 'pay_later_button_enabled' );
|
||||
|
@ -85,45 +71,11 @@ class SettingsStatus {
|
|||
*
|
||||
* @param string $location The location.
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_button_enabled_for_location( string $location ): bool {
|
||||
if ( ! $this->is_pay_later_button_enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$selected_locations = $this->settings->has( 'pay_later_button_locations' ) ? $this->settings->get( 'pay_later_button_locations' ) : array();
|
||||
|
||||
if ( empty( $selected_locations ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array( $location, $selected_locations, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether Pay Later button is enabled for a given context.
|
||||
*
|
||||
* @param string $context The context.
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_button_enabled_for_context( string $context ): bool {
|
||||
if ( ! $this->is_pay_later_button_enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$selected_locations = $this->settings->has( 'pay_later_button_locations' ) ? $this->settings->get( 'pay_later_button_locations' ) : array();
|
||||
|
||||
if ( empty( $selected_locations ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$enabled_for_current_location = $this->is_pay_later_button_enabled_for_location( $context );
|
||||
$enabled_for_product = $this->is_pay_later_button_enabled_for_location( 'product' );
|
||||
$enabled_for_mini_cart = $this->is_pay_later_button_enabled_for_location( 'mini-cart' );
|
||||
|
||||
return $context === 'product' ? $enabled_for_product || $enabled_for_mini_cart : $enabled_for_current_location;
|
||||
return $this->is_pay_later_button_enabled() &&
|
||||
( $this->is_enabled_for_location( 'pay_later_button_locations', $location ) ||
|
||||
( 'product' === $location && $this->is_enabled_for_location( 'pay_later_button_locations', 'mini-cart' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,7 +85,33 @@ class SettingsStatus {
|
|||
* @return bool true if is enabled, otherwise false.
|
||||
*/
|
||||
public function is_smart_button_enabled_for_location( string $location ): bool {
|
||||
$selected_locations = $this->settings->has( 'smart_button_locations' ) ? $this->settings->get( 'smart_button_locations' ) : array();
|
||||
return $this->is_enabled_for_location( 'smart_button_locations', $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts the context value to match the location settings.
|
||||
*
|
||||
* @param string $location The location/context.
|
||||
* @return string
|
||||
*/
|
||||
protected function normalize_location( string $location ): string {
|
||||
if ( 'pay-now' === $location ) {
|
||||
$location = 'checkout';
|
||||
}
|
||||
return $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the locations field in the settings includes the given location.
|
||||
*
|
||||
* @param string $setting_name The name of the enabled locations field in the settings.
|
||||
* @param string $location The location.
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_enabled_for_location( string $setting_name, string $location ): bool {
|
||||
$location = $this->normalize_location( $location );
|
||||
|
||||
$selected_locations = $this->settings->has( $setting_name ) ? $this->settings->get( $setting_name ) : array();
|
||||
|
||||
if ( empty( $selected_locations ) ) {
|
||||
return false;
|
||||
|
|
|
@ -13,6 +13,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\Http\RedirectorInterface;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus;
|
||||
|
@ -111,20 +112,28 @@ class SettingsListener {
|
|||
*/
|
||||
protected $dcc_status_cache;
|
||||
|
||||
/**
|
||||
* The HTTP redirector.
|
||||
*
|
||||
* @var RedirectorInterface
|
||||
*/
|
||||
protected $redirector;
|
||||
|
||||
/**
|
||||
* SettingsListener constructor.
|
||||
*
|
||||
* @param Settings $settings The settings.
|
||||
* @param array $setting_fields The setting fields.
|
||||
* @param WebhookRegistrar $webhook_registrar The Webhook Registrar.
|
||||
* @param Cache $cache The Cache.
|
||||
* @param State $state The state.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
||||
* @param Cache $signup_link_cache The signup link cache.
|
||||
* @param array $signup_link_ids Signup link ids.
|
||||
* @param Cache $pui_status_cache The PUI status cache.
|
||||
* @param Cache $dcc_status_cache The DCC status cache.
|
||||
* @param Settings $settings The settings.
|
||||
* @param array $setting_fields The setting fields.
|
||||
* @param WebhookRegistrar $webhook_registrar The Webhook Registrar.
|
||||
* @param Cache $cache The Cache.
|
||||
* @param State $state The state.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
||||
* @param Cache $signup_link_cache The signup link cache.
|
||||
* @param array $signup_link_ids Signup link ids.
|
||||
* @param Cache $pui_status_cache The PUI status cache.
|
||||
* @param Cache $dcc_status_cache The DCC status cache.
|
||||
* @param RedirectorInterface $redirector The HTTP redirector.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
|
@ -137,7 +146,8 @@ class SettingsListener {
|
|||
Cache $signup_link_cache,
|
||||
array $signup_link_ids,
|
||||
Cache $pui_status_cache,
|
||||
Cache $dcc_status_cache
|
||||
Cache $dcc_status_cache,
|
||||
RedirectorInterface $redirector
|
||||
) {
|
||||
|
||||
$this->settings = $settings;
|
||||
|
@ -151,6 +161,7 @@ class SettingsListener {
|
|||
$this->signup_link_ids = $signup_link_ids;
|
||||
$this->pui_status_cache = $pui_status_cache;
|
||||
$this->dcc_status_cache = $dcc_status_cache;
|
||||
$this->redirector = $redirector;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,12 +209,13 @@ class SettingsListener {
|
|||
$redirect_url = add_query_arg( 'ppcp-onboarding-error', '1', $redirect_url );
|
||||
}
|
||||
|
||||
wp_safe_redirect( $redirect_url, 302 );
|
||||
exit;
|
||||
$this->redirector->redirect( $redirect_url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent enabling both Pay Later messaging and PayPal vaulting
|
||||
*
|
||||
* @throws RuntimeException When API request fails.
|
||||
*/
|
||||
public function listen_for_vaulting_enabled() {
|
||||
if ( ! $this->is_valid_site_request() || State::STATE_ONBOARDED !== $this->state->current_state() ) {
|
||||
|
@ -221,16 +233,7 @@ class SettingsListener {
|
|||
$this->settings->set( 'vault_enabled', false );
|
||||
$this->settings->persist();
|
||||
|
||||
add_action(
|
||||
'admin_notices',
|
||||
function () use ( $exception ) {
|
||||
printf(
|
||||
'<div class="notice notice-error"><p>%1$s</p><p>%2$s</p></div>',
|
||||
esc_html__( 'Authentication with PayPal failed: ', 'woocommerce-paypal-payments' ) . esc_attr( $exception->getMessage() ),
|
||||
wp_kses_post( __( 'Please verify your API Credentials and try again to connect your PayPal business account. Visit the <a href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/" target="_blank">plugin documentation</a> for more information about the setup.', 'woocommerce-paypal-payments' ) )
|
||||
);
|
||||
}
|
||||
);
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -322,16 +325,6 @@ class SettingsListener {
|
|||
}
|
||||
$this->settings->persist();
|
||||
|
||||
if ( $credentials_change_status ) {
|
||||
if ( in_array(
|
||||
$credentials_change_status,
|
||||
array( self::CREDENTIALS_ADDED, self::CREDENTIALS_CHANGED ),
|
||||
true
|
||||
) ) {
|
||||
$this->webhook_registrar->register();
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
||||
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
||||
}
|
||||
|
@ -345,7 +338,7 @@ class SettingsListener {
|
|||
}
|
||||
|
||||
$redirect_url = false;
|
||||
if ( self::CREDENTIALS_ADDED === $credentials_change_status ) {
|
||||
if ( self::CREDENTIALS_UNCHANGED !== $credentials_change_status ) {
|
||||
$redirect_url = $this->get_onboarding_redirect_url();
|
||||
}
|
||||
|
||||
|
@ -354,8 +347,7 @@ class SettingsListener {
|
|||
}
|
||||
|
||||
if ( $redirect_url ) {
|
||||
wp_safe_redirect( $redirect_url, 302 );
|
||||
exit;
|
||||
$this->redirector->redirect( $redirect_url );
|
||||
}
|
||||
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||
|
@ -532,6 +524,8 @@ class SettingsListener {
|
|||
|
||||
/**
|
||||
* Prevent enabling tracking if it is not enabled for merchant account.
|
||||
*
|
||||
* @throws RuntimeException When API request fails.
|
||||
*/
|
||||
public function listen_for_tracking_enabled(): void {
|
||||
if ( State::STATE_ONBOARDED !== $this->state->current_state() ) {
|
||||
|
@ -549,16 +543,7 @@ class SettingsListener {
|
|||
$this->settings->set( 'tracking_enabled', false );
|
||||
$this->settings->persist();
|
||||
|
||||
add_action(
|
||||
'admin_notices',
|
||||
function () use ( $exception ) {
|
||||
printf(
|
||||
'<div class="notice notice-error"><p>%1$s</p><p>%2$s</p></div>',
|
||||
esc_html__( 'Authentication with PayPal failed: ', 'woocommerce-paypal-payments' ) . esc_attr( $exception->getMessage() ),
|
||||
wp_kses_post( __( 'Please verify your API Credentials and try again to connect your PayPal business account. Visit the <a href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/" target="_blank">plugin documentation</a> for more information about the setup.', 'woocommerce-paypal-payments' ) )
|
||||
);
|
||||
}
|
||||
);
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway;
|
|||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||
use WC_Order;
|
||||
|
@ -179,7 +180,7 @@ class WCGatewayModule implements ModuleInterface {
|
|||
$c->get( 'onboarding.environment' ),
|
||||
$settings_status->is_pay_later_button_enabled(),
|
||||
$settings->has( 'disable_funding' ) ? $settings->get( 'disable_funding' ) : array(),
|
||||
$c->get( 'wcgateway.all-funding-sources' )
|
||||
$c->get( 'wcgateway.settings.funding-sources' )
|
||||
);
|
||||
$assets->register_assets();
|
||||
}
|
||||
|
@ -453,14 +454,30 @@ class WCGatewayModule implements ModuleInterface {
|
|||
'admin_init',
|
||||
static function () use ( $container ) {
|
||||
$listener = $container->get( 'wcgateway.settings.listener' );
|
||||
/**
|
||||
* The settings listener.
|
||||
*
|
||||
* @var SettingsListener $listener
|
||||
*/
|
||||
assert( $listener instanceof SettingsListener );
|
||||
|
||||
$listener->listen_for_merchant_id();
|
||||
$listener->listen_for_vaulting_enabled();
|
||||
$listener->listen_for_tracking_enabled();
|
||||
|
||||
try {
|
||||
$listener->listen_for_vaulting_enabled();
|
||||
$listener->listen_for_tracking_enabled();
|
||||
} catch ( RuntimeException $exception ) {
|
||||
add_action(
|
||||
'admin_notices',
|
||||
function () use ( $exception ) {
|
||||
printf(
|
||||
'<div class="notice notice-error"><p>%1$s</p><p>%2$s</p></div>',
|
||||
esc_html__( 'Authentication with PayPal failed: ', 'woocommerce-paypal-payments' ) . esc_attr( $exception->getMessage() ),
|
||||
wp_kses_post(
|
||||
__(
|
||||
'Please verify your API Credentials and try again to connect your PayPal business account. Visit the <a href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/" target="_blank">plugin documentation</a> for more information about the setup.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import {setVisibleByClass} from "../../../ppcp-button/resources/js/modules/Helper/Hiding"
|
||||
|
||||
document.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
() => {
|
||||
|
@ -147,5 +149,25 @@ document.addEventListener(
|
|||
simulateBtn.prop('disabled', false);
|
||||
}
|
||||
});
|
||||
|
||||
const sandboxCheckbox = document.querySelector('#ppcp-sandbox_on');
|
||||
if (sandboxCheckbox) {
|
||||
const setWebhooksVisibility = (show) => {
|
||||
[
|
||||
'#field-webhook_status_heading',
|
||||
'#field-webhooks_list',
|
||||
'#field-webhooks_resubscribe',
|
||||
'#field-webhooks_simulate',
|
||||
].forEach(selector => {
|
||||
setVisibleByClass(selector, show, 'hide');
|
||||
});
|
||||
};
|
||||
|
||||
const serverSandboxState = PayPalCommerceGatewayWebhooksStatus.environment === 'sandbox';
|
||||
setWebhooksVisibility(serverSandboxState === sandboxCheckbox.checked);
|
||||
sandboxCheckbox.addEventListener('click', () => {
|
||||
setWebhooksVisibility(serverSandboxState === sandboxCheckbox.checked);
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -170,7 +170,8 @@ return array(
|
|||
'webhook.status.assets' => function( ContainerInterface $container ) : WebhooksStatusPageAssets {
|
||||
return new WebhooksStatusPageAssets(
|
||||
$container->get( 'webhook.module-url' ),
|
||||
$container->get( 'ppcp.asset-version' )
|
||||
$container->get( 'ppcp.asset-version' ),
|
||||
$container->get( 'onboarding.environment' )
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -201,8 +202,8 @@ return array(
|
|||
);
|
||||
},
|
||||
|
||||
'webhook.last-webhook-storage' => static function ( ContainerInterface $container ): WebhookInfoStorage {
|
||||
return new WebhookInfoStorage( $container->get( 'webhook.last-webhook-storage.key' ) );
|
||||
'webhook.last-webhook-storage' => static function ( ContainerInterface $container ): WebhookEventStorage {
|
||||
return new WebhookEventStorage( $container->get( 'webhook.last-webhook-storage.key' ) );
|
||||
},
|
||||
'webhook.last-webhook-storage.key' => static function ( ContainerInterface $container ): string {
|
||||
return 'ppcp-last-webhook';
|
||||
|
|
|
@ -62,8 +62,6 @@ class ResubscribeEndpoint {
|
|||
// Validate nonce.
|
||||
$this->request_data->read_request( $this->nonce() );
|
||||
|
||||
$this->registrar->unregister();
|
||||
|
||||
if ( ! $this->registrar->register() ) {
|
||||
wp_send_json_error( 'Webhook subscription failed.', 500 );
|
||||
return false;
|
||||
|
|
|
@ -77,11 +77,11 @@ class IncomingWebhookEndpoint {
|
|||
private $simulation;
|
||||
|
||||
/**
|
||||
* The last webhook info storage.
|
||||
* The last webhook event storage.
|
||||
*
|
||||
* @var WebhookInfoStorage
|
||||
* @var WebhookEventStorage
|
||||
*/
|
||||
private $last_webhook_storage;
|
||||
private $last_webhook_event_storage;
|
||||
|
||||
/**
|
||||
* IncomingWebhookEndpoint constructor.
|
||||
|
@ -92,7 +92,7 @@ class IncomingWebhookEndpoint {
|
|||
* @param bool $verify_request Whether requests need to be verified or not.
|
||||
* @param WebhookEventFactory $webhook_event_factory The webhook event factory.
|
||||
* @param WebhookSimulation $simulation The simulation handler.
|
||||
* @param WebhookInfoStorage $last_webhook_storage The last webhook info storage.
|
||||
* @param WebhookEventStorage $last_webhook_event_storage The last webhook event storage.
|
||||
* @param RequestHandler ...$handlers The handlers, which process a request in the end.
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -102,18 +102,18 @@ class IncomingWebhookEndpoint {
|
|||
bool $verify_request,
|
||||
WebhookEventFactory $webhook_event_factory,
|
||||
WebhookSimulation $simulation,
|
||||
WebhookInfoStorage $last_webhook_storage,
|
||||
WebhookEventStorage $last_webhook_event_storage,
|
||||
RequestHandler ...$handlers
|
||||
) {
|
||||
|
||||
$this->webhook_endpoint = $webhook_endpoint;
|
||||
$this->webhook = $webhook;
|
||||
$this->handlers = $handlers;
|
||||
$this->logger = $logger;
|
||||
$this->verify_request = $verify_request;
|
||||
$this->webhook_event_factory = $webhook_event_factory;
|
||||
$this->last_webhook_storage = $last_webhook_storage;
|
||||
$this->simulation = $simulation;
|
||||
$this->webhook_endpoint = $webhook_endpoint;
|
||||
$this->webhook = $webhook;
|
||||
$this->handlers = $handlers;
|
||||
$this->logger = $logger;
|
||||
$this->verify_request = $verify_request;
|
||||
$this->webhook_event_factory = $webhook_event_factory;
|
||||
$this->last_webhook_event_storage = $last_webhook_event_storage;
|
||||
$this->simulation = $simulation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,7 +186,7 @@ class IncomingWebhookEndpoint {
|
|||
public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
|
||||
$event = $this->event_from_request( $request );
|
||||
|
||||
$this->last_webhook_storage->save( $event );
|
||||
$this->last_webhook_event_storage->save( $event );
|
||||
|
||||
if ( $this->simulation->is_simulation_event( $event ) ) {
|
||||
$this->logger->info( 'Received simulated webhook.' );
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Webhooks\Status\Assets;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
|
||||
|
@ -33,18 +34,28 @@ class WebhooksStatusPageAssets {
|
|||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* The environment object.
|
||||
*
|
||||
* @var Environment
|
||||
*/
|
||||
private $environment;
|
||||
|
||||
/**
|
||||
* WebhooksStatusPageAssets constructor.
|
||||
*
|
||||
* @param string $module_url The URL to the module.
|
||||
* @param string $version The assets version.
|
||||
* @param string $module_url The URL to the module.
|
||||
* @param string $version The assets version.
|
||||
* @param Environment $environment The environment object.
|
||||
*/
|
||||
public function __construct(
|
||||
string $module_url,
|
||||
string $version
|
||||
string $version,
|
||||
Environment $environment
|
||||
) {
|
||||
$this->module_url = untrailingslashit( $module_url );
|
||||
$this->version = $version;
|
||||
$this->module_url = untrailingslashit( $module_url );
|
||||
$this->version = $version;
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,6 +114,7 @@ class WebhooksStatusPageAssets {
|
|||
'tooLongDelayMessage' => __( 'Looks like the webhook cannot be received. Check that your website is accessible from the internet.', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
),
|
||||
'environment' => $this->environment->current_environment(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@ namespace WooCommerce\PayPalCommerce\Webhooks;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\WebhookEvent;
|
||||
|
||||
/**
|
||||
* Class WebhookInfoStorage
|
||||
* Class WebhookEventStorage
|
||||
*/
|
||||
class WebhookInfoStorage {
|
||||
class WebhookEventStorage {
|
||||
|
||||
/**
|
||||
* The WP option key.
|
|
@ -152,7 +152,6 @@ class WebhookModule implements ModuleInterface {
|
|||
add_action(
|
||||
'init',
|
||||
function () use ( $registrar ) {
|
||||
$registrar->unregister();
|
||||
$registrar->register();
|
||||
}
|
||||
);
|
||||
|
|
|
@ -45,11 +45,11 @@ class WebhookRegistrar {
|
|||
private $rest_endpoint;
|
||||
|
||||
/**
|
||||
* The last webhook info storage.
|
||||
* The last webhook event storage.
|
||||
*
|
||||
* @var WebhookInfoStorage
|
||||
* @var WebhookEventStorage
|
||||
*/
|
||||
private $last_webhook_storage;
|
||||
private $last_webhook_event_storage;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
|
@ -64,22 +64,22 @@ class WebhookRegistrar {
|
|||
* @param WebhookFactory $webhook_factory The Webhook factory.
|
||||
* @param WebhookEndpoint $endpoint The Webhook endpoint.
|
||||
* @param IncomingWebhookEndpoint $rest_endpoint The WordPress Rest API endpoint.
|
||||
* @param WebhookInfoStorage $last_webhook_storage The last webhook info storage.
|
||||
* @param WebhookEventStorage $last_webhook_event_storage The last webhook event storage.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
WebhookFactory $webhook_factory,
|
||||
WebhookEndpoint $endpoint,
|
||||
IncomingWebhookEndpoint $rest_endpoint,
|
||||
WebhookInfoStorage $last_webhook_storage,
|
||||
WebhookEventStorage $last_webhook_event_storage,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
|
||||
$this->webhook_factory = $webhook_factory;
|
||||
$this->endpoint = $endpoint;
|
||||
$this->rest_endpoint = $rest_endpoint;
|
||||
$this->last_webhook_storage = $last_webhook_storage;
|
||||
$this->logger = $logger;
|
||||
$this->webhook_factory = $webhook_factory;
|
||||
$this->endpoint = $endpoint;
|
||||
$this->rest_endpoint = $rest_endpoint;
|
||||
$this->last_webhook_event_storage = $last_webhook_event_storage;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,6 +88,8 @@ class WebhookRegistrar {
|
|||
* @return bool
|
||||
*/
|
||||
public function register(): bool {
|
||||
$this->unregister();
|
||||
|
||||
$webhook = $this->webhook_factory->for_url_and_events(
|
||||
$this->rest_endpoint->url(),
|
||||
$this->rest_endpoint->handled_event_types()
|
||||
|
@ -102,7 +104,7 @@ class WebhookRegistrar {
|
|||
self::KEY,
|
||||
$created->to_array()
|
||||
);
|
||||
$this->last_webhook_storage->clear();
|
||||
$this->last_webhook_event_storage->clear();
|
||||
$this->logger->info( 'Webhooks subscribed.' );
|
||||
return true;
|
||||
} catch ( RuntimeException $error ) {
|
||||
|
@ -113,27 +115,23 @@ class WebhookRegistrar {
|
|||
|
||||
/**
|
||||
* Unregister webhooks with PayPal.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function unregister(): bool {
|
||||
$data = (array) get_option( self::KEY, array() );
|
||||
if ( ! $data ) {
|
||||
return false;
|
||||
}
|
||||
public function unregister(): void {
|
||||
try {
|
||||
$webhook = $this->webhook_factory->from_array( $data );
|
||||
$success = $this->endpoint->delete( $webhook );
|
||||
$webhooks = $this->endpoint->list();
|
||||
foreach ( $webhooks as $webhook ) {
|
||||
try {
|
||||
$this->endpoint->delete( $webhook );
|
||||
} catch ( RuntimeException $deletion_error ) {
|
||||
$this->logger->error( "Failed to delete webhook {$webhook->id()}: {$deletion_error->getMessage()}" );
|
||||
}
|
||||
}
|
||||
} catch ( RuntimeException $error ) {
|
||||
$this->logger->error( 'Failed to delete webhooks: ' . $error->getMessage() );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $success ) {
|
||||
delete_option( self::KEY );
|
||||
$this->last_webhook_storage->clear();
|
||||
$this->logger->info( 'Webhooks deleted.' );
|
||||
}
|
||||
return $success;
|
||||
delete_option( self::KEY );
|
||||
$this->last_webhook_event_storage->clear();
|
||||
$this->logger->info( 'Webhooks deleted.' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1776,9 +1776,9 @@ loader-runner@^4.2.0:
|
|||
integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
|
||||
|
||||
loader-utils@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
|
||||
integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
|
||||
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
|
||||
dependencies:
|
||||
big.js "^5.2.2"
|
||||
emojis-list "^3.0.0"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "woocommerce-paypal-payments",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.3",
|
||||
"description": "WooCommerce PayPal Payments",
|
||||
"repository": "https://github.com/woocommerce/woocommerce-paypal-payments",
|
||||
"license": "GPL-2.0",
|
||||
|
|
|
@ -81,7 +81,7 @@ Follow the steps below to connect the plugin to your PayPal account:
|
|||
|
||||
== Changelog ==
|
||||
|
||||
= 2.0.3 =
|
||||
= 2.0.3 - 2023-03-14 =
|
||||
* Fix - `DEVICE_DATA_NOT_AVAILABLE` error message when FraudNet is enabled #1177
|
||||
* Fix - Redirect to connection tab after manual credentials input #1201
|
||||
* Fix - Asking for address fields in checkout when not using them #1089
|
||||
|
@ -90,6 +90,9 @@ Follow the steps below to connect the plugin to your PayPal account:
|
|||
* Fix - After Updating to 2.0.2, Site Health reports REST API error #1195
|
||||
* Fix - Do not send buyer-country for previews in live mode to avoid error #1186
|
||||
* Fix - PPEC compatibility layer does not take over subscriptions #1193
|
||||
* Fix - Checkout conflict with "All products for subscriptions" plugin #629
|
||||
* Fix - Pay Later on order pay page #1214
|
||||
* Fix - High volume of traffic from merchant-integrations endpoint #1241
|
||||
* Enhancement - Save checkout form before free trial redirect #1135
|
||||
* Enhancement - Add filter for controlling the ditching of items/breakdown #1146
|
||||
* Enhancement - Add patch order data filter #1147
|
||||
|
|
22
src/Http/RedirectorInterface.php
Normal file
22
src/Http/RedirectorInterface.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/**
|
||||
* HTTP redirection.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Api
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Http;
|
||||
|
||||
/**
|
||||
* Interface for HTTP redirection.
|
||||
*/
|
||||
interface RedirectorInterface {
|
||||
/**
|
||||
* Starts HTTP redirection and shutdowns.
|
||||
*
|
||||
* @param string $location The URL to redirect to.
|
||||
*/
|
||||
public function redirect( string $location): void;
|
||||
}
|
25
src/Http/WpRedirector.php
Normal file
25
src/Http/WpRedirector.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
/**
|
||||
* HTTP redirection.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Api
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Http;
|
||||
|
||||
/**
|
||||
* Wrapper for HTTP redirection via wp_safe_redirect.
|
||||
*/
|
||||
class WpRedirector implements RedirectorInterface {
|
||||
/**
|
||||
* Starts HTTP redirection and shutdowns.
|
||||
*
|
||||
* @param string $location The URL to redirect to.
|
||||
*/
|
||||
public function redirect( string $location ): void {
|
||||
wp_safe_redirect( $location, 302 );
|
||||
exit;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,8 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce;
|
||||
|
||||
use Dhii\Versions\StringVersionFactory;
|
||||
use WooCommerce\PayPalCommerce\Http\RedirectorInterface;
|
||||
use WooCommerce\PayPalCommerce\Http\WpRedirector;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WpOop\WordPress\Plugin\PluginInterface;
|
||||
|
||||
|
@ -24,4 +26,8 @@ return array(
|
|||
|
||||
return (string) $plugin->getVersion();
|
||||
},
|
||||
|
||||
'http.redirector' => function( ContainerInterface $container ) : RedirectorInterface {
|
||||
return new WpRedirector();
|
||||
},
|
||||
);
|
||||
|
|
|
@ -43,9 +43,8 @@ class ItemFactoryTest extends TestCase
|
|||
->expects('get_cart_contents')
|
||||
->andReturn($items);
|
||||
|
||||
expect('wp_strip_all_tags')
|
||||
->with('description')
|
||||
->andReturn('description');
|
||||
expect('wp_strip_all_tags')->andReturnFirstArg();
|
||||
expect('strip_shortcodes')->andReturnFirstArg();
|
||||
|
||||
$woocommerce = Mockery::mock(\WooCommerce::class);
|
||||
$session = Mockery::mock(\WC_Session::class);
|
||||
|
@ -99,9 +98,8 @@ class ItemFactoryTest extends TestCase
|
|||
->expects('get_cart_contents')
|
||||
->andReturn($items);
|
||||
|
||||
expect('wp_strip_all_tags')
|
||||
->with('description')
|
||||
->andReturn('description');
|
||||
expect('wp_strip_all_tags')->andReturnFirstArg();
|
||||
expect('strip_shortcodes')->andReturnFirstArg();
|
||||
|
||||
$woocommerce = Mockery::mock(\WooCommerce::class);
|
||||
$session = Mockery::mock(\WC_Session::class);
|
||||
|
@ -130,9 +128,9 @@ class ItemFactoryTest extends TestCase
|
|||
$product
|
||||
->expects('is_virtual')
|
||||
->andReturn(false);
|
||||
expect('wp_strip_all_tags')
|
||||
->with('description')
|
||||
->andReturn('description');
|
||||
|
||||
expect('wp_strip_all_tags')->andReturnFirstArg();
|
||||
expect('strip_shortcodes')->andReturnFirstArg();
|
||||
|
||||
$item = Mockery::mock(\WC_Order_Item_Product::class);
|
||||
$item
|
||||
|
@ -190,9 +188,8 @@ class ItemFactoryTest extends TestCase
|
|||
->expects('is_virtual')
|
||||
->andReturn(true);
|
||||
|
||||
expect('wp_strip_all_tags')
|
||||
->with('description')
|
||||
->andReturn('description');
|
||||
expect('wp_strip_all_tags')->andReturnFirstArg();
|
||||
expect('strip_shortcodes')->andReturnFirstArg();
|
||||
|
||||
$item = Mockery::mock(\WC_Order_Item_Product::class);
|
||||
$item
|
||||
|
@ -245,9 +242,8 @@ class ItemFactoryTest extends TestCase
|
|||
->expects('is_virtual')
|
||||
->andReturn(true);
|
||||
|
||||
expect('wp_strip_all_tags')
|
||||
->with($description)
|
||||
->andReturn(mb_substr( $description, 0, 127 ));
|
||||
expect('wp_strip_all_tags')->andReturnFirstArg();
|
||||
expect('strip_shortcodes')->andReturnFirstArg();
|
||||
|
||||
$item = Mockery::mock(\WC_Order_Item_Product::class);
|
||||
$item
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
|
|||
|
||||
use Exception;
|
||||
use Mockery;
|
||||
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Exception\ValidationException;
|
||||
use WooCommerce\PayPalCommerce\Button\Validation\CheckoutFormValidator;
|
||||
|
@ -13,6 +14,8 @@ use function Brain\Monkey\Functions\expect;
|
|||
|
||||
class ValidateCheckoutEndpointTest extends TestCase
|
||||
{
|
||||
use MockeryPHPUnitIntegration;
|
||||
|
||||
private $requestData;
|
||||
private $formValidator;
|
||||
private $logger;
|
||||
|
|
14
tests/PHPUnit/Helper/RedirectorStub.php
Normal file
14
tests/PHPUnit/Helper/RedirectorStub.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Helper;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Http\RedirectorInterface;
|
||||
|
||||
class RedirectorStub implements RedirectorInterface
|
||||
{
|
||||
public function redirect(string $location): void
|
||||
{
|
||||
throw new StubRedirectionException($location);
|
||||
}
|
||||
}
|
41
tests/PHPUnit/Helper/SettingsStub.php
Normal file
41
tests/PHPUnit/Helper/SettingsStub.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Helper;
|
||||
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
class SettingsStub extends Settings
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function get($id) {
|
||||
if ( ! $this->has( $id ) ) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return $this->data[$id];
|
||||
}
|
||||
|
||||
public function has($id) {
|
||||
return array_key_exists( $id, $this->data );
|
||||
}
|
||||
|
||||
public function set($id, $value) {
|
||||
$this->data[$id] = $value;
|
||||
}
|
||||
|
||||
public function persist() {
|
||||
}
|
||||
}
|
10
tests/PHPUnit/Helper/StubRedirectionException.php
Normal file
10
tests/PHPUnit/Helper/StubRedirectionException.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Helper;
|
||||
|
||||
use Exception;
|
||||
|
||||
class StubRedirectionException extends Exception
|
||||
{
|
||||
}
|
|
@ -3,10 +3,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\CompositeCachingServiceProvider;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\DelegatingContainer;
|
||||
use WooCommerce\PayPalCommerce\Helper\RedirectorStub;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use function Brain\Monkey\Functions\when;
|
||||
|
||||
|
@ -58,13 +59,28 @@ class ModularTestCase extends TestCase
|
|||
*/
|
||||
protected function bootstrapModule(array $overriddenServices = []): ContainerInterface
|
||||
{
|
||||
$overridingContainer = new DelegatingContainer(new CompositeCachingServiceProvider([
|
||||
new ServiceProvider($overriddenServices, []),
|
||||
]));
|
||||
$overriddenServices = array_merge([
|
||||
'http.redirector' => function () {
|
||||
return new RedirectorStub();
|
||||
}
|
||||
], $overriddenServices);
|
||||
|
||||
$module = new class ($overriddenServices) implements ModuleInterface {
|
||||
public function __construct(array $services) {
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
public function setup(): ServiceProviderInterface{
|
||||
return new ServiceProvider($this->services, []);
|
||||
}
|
||||
|
||||
public function run(ContainerInterface $c): void {
|
||||
}
|
||||
};
|
||||
|
||||
$rootDir = ROOT_DIR;
|
||||
$bootstrap = require ("$rootDir/bootstrap.php");
|
||||
$appContainer = $bootstrap($rootDir, $overridingContainer);
|
||||
$appContainer = $bootstrap($rootDir, [], [$module]);
|
||||
|
||||
return $appContainer;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,10 @@ class WcGatewayTest extends TestCase
|
|||
$this->environment = Mockery::mock(Environment::class);
|
||||
$this->paymentTokenRepository = Mockery::mock(PaymentTokenRepository::class);
|
||||
$this->logger = Mockery::mock(LoggerInterface::class);
|
||||
$this->funding_source_renderer = new FundingSourceRenderer($this->settings);
|
||||
$this->funding_source_renderer = new FundingSourceRenderer(
|
||||
$this->settings,
|
||||
['venmo' => 'Venmo', 'paylater' => 'Pay Later', 'blik' => 'BLIK']
|
||||
);
|
||||
$this->apiShopCountry = 'DE';
|
||||
|
||||
$this->onboardingState->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
|
||||
|
@ -271,6 +274,8 @@ class WcGatewayTest extends TestCase
|
|||
return [
|
||||
[null, 'PayPal', 'Pay via PayPal.'],
|
||||
['venmo', 'Venmo', 'Pay via Venmo.'],
|
||||
['paylater', 'Pay Later', 'Pay via Pay Later.'],
|
||||
['blik', 'BLIK (via PayPal)', 'Pay via BLIK.'],
|
||||
['qwerty', 'PayPal', 'Pay via PayPal.'],
|
||||
];
|
||||
}
|
||||
|
|
60
tests/PHPUnit/WcGateway/Settings/LocationsTest.php
Normal file
60
tests/PHPUnit/WcGateway/Settings/LocationsTest.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Helper\SettingsStub;
|
||||
use WooCommerce\PayPalCommerce\ModularTestCase;
|
||||
|
||||
class LocationsTest extends ModularTestCase
|
||||
{
|
||||
private $appContainer;
|
||||
|
||||
private $settings;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->settings = new SettingsStub([]);
|
||||
|
||||
$this->appContainer = $this->bootstrapModule([
|
||||
'wcgateway.settings' => function () {
|
||||
return $this->settings;
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider payLaterButtonLocationsData
|
||||
*/
|
||||
public function testPayLaterButtonLocations(array $selectedLocations, array $expectedResult) {
|
||||
$this->settings->set('smart_button_locations', $selectedLocations);
|
||||
|
||||
$result = $this->appContainer->get('wcgateway.settings.pay-later.button-locations');
|
||||
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
public function payLaterButtonLocationsData()
|
||||
{
|
||||
yield [
|
||||
['product', 'cart', 'checkout', 'mini-cart'],
|
||||
[
|
||||
'product' => 'Single Product',
|
||||
'cart' => 'Cart',
|
||||
'checkout' => 'Checkout',
|
||||
'mini-cart' => 'Mini Cart',
|
||||
],
|
||||
];
|
||||
yield [
|
||||
['cart', 'checkout'],
|
||||
[
|
||||
'cart' => 'Cart',
|
||||
'checkout' => 'Checkout',
|
||||
],
|
||||
];
|
||||
yield [
|
||||
[],
|
||||
[],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
|||
use Requests_Utility_CaseInsensitiveDictionary;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\Helper\RedirectorStub;
|
||||
use WooCommerce\PayPalCommerce\Helper\StubRedirectionException;
|
||||
use WooCommerce\PayPalCommerce\ModularTestCase;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use Mockery;
|
||||
|
@ -50,7 +52,8 @@ class SettingsListenerTest extends ModularTestCase
|
|||
$signup_link_cache,
|
||||
$signup_link_ids,
|
||||
$pui_status_cache,
|
||||
$dcc_status_cache
|
||||
$dcc_status_cache,
|
||||
new RedirectorStub()
|
||||
);
|
||||
|
||||
$_GET['section'] = PayPalGateway::ID;
|
||||
|
@ -85,6 +88,8 @@ class SettingsListenerTest extends ModularTestCase
|
|||
$dcc_status_cache->shouldReceive('has')
|
||||
->andReturn(false);
|
||||
|
||||
$this->expectException(StubRedirectionException::class);
|
||||
|
||||
$testee->listen();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,10 @@ class PurchaseUnitTest extends TestCase
|
|||
|
||||
$this->puFactory = $this->container->get( 'api.factory.purchase-unit' );
|
||||
assert($this->puFactory instanceof PurchaseUnitFactory);
|
||||
|
||||
add_filter('woocommerce_get_base_location', function () {
|
||||
return 'AQ';
|
||||
});
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
|
@ -195,6 +199,7 @@ class PurchaseUnitTest extends TestCase
|
|||
$product->set_regular_price((string) $data['price']);
|
||||
$product->set_tax_status('taxable');
|
||||
$product->set_tax_class('');
|
||||
$product->set_virtual(true);
|
||||
|
||||
$product->save();
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ class ValidationTest extends TestCase
|
|||
'terms-field'=>'1',
|
||||
'terms'=>'on',
|
||||
]);
|
||||
|
||||
self::assertTrue(true); // no assertions warnings
|
||||
}
|
||||
|
||||
public function testInvalid()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue