mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-31 06:52:50 +08:00
Merge branch 'trunk' into PCP-1393-update-to-vault-v-3
This commit is contained in:
commit
d35f7598ed
37 changed files with 1815 additions and 658 deletions
|
@ -1,6 +1,6 @@
|
|||
*** Changelog ***
|
||||
|
||||
= 2.4.0 - xxxx-xx-xx =
|
||||
= 2.4.0 - 2023-10-31 =
|
||||
* Fix - Mini-Cart Bug cause of wrong DOM-Structure in v2.3.1 #1735
|
||||
* Fix - ACDC disappearing after plugin updates #1751
|
||||
* Fix - Subscription module hooks #1748
|
||||
|
|
|
@ -606,6 +606,37 @@ return array(
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'BE' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'CAD',
|
||||
'GBP',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'CHF',
|
||||
),
|
||||
'BG' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
),
|
||||
'CY' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'CAD',
|
||||
'GBP',
|
||||
'AUD',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'NOK',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'CHF',
|
||||
),
|
||||
'CZ' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'CZK',
|
||||
),
|
||||
'DE' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
|
@ -624,6 +655,16 @@ return array(
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'DK' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'DKK',
|
||||
'NOK',
|
||||
),
|
||||
'EE' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
),
|
||||
'ES' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
|
@ -642,6 +683,10 @@ return array(
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'FI' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
),
|
||||
'FR' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
|
@ -678,6 +723,16 @@ return array(
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'GR' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'GBP',
|
||||
),
|
||||
'HU' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'HUF',
|
||||
),
|
||||
'IT' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
|
@ -696,6 +751,32 @@ return array(
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'LT' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'CAD',
|
||||
'GBP',
|
||||
'JPY',
|
||||
'AUD',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'HUF',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'CHF',
|
||||
'NZD',
|
||||
'NOK',
|
||||
),
|
||||
'LU' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
),
|
||||
'LV' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'CAD',
|
||||
'GBP',
|
||||
),
|
||||
'US' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
|
@ -722,9 +803,81 @@ return array(
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'MT' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'CAD',
|
||||
'GBP',
|
||||
'JPY',
|
||||
'AUD',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'HUF',
|
||||
'NOK',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'CHF',
|
||||
),
|
||||
'MX' => array(
|
||||
'MXN',
|
||||
),
|
||||
'NL' => array(
|
||||
'EUR',
|
||||
'GBP',
|
||||
'AUD',
|
||||
'CZK',
|
||||
'HUF',
|
||||
'CHF',
|
||||
'CAD',
|
||||
'USD',
|
||||
),
|
||||
'NO' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'CAD',
|
||||
'GBP',
|
||||
'NOK',
|
||||
),
|
||||
'PL' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'CAD',
|
||||
'GBP',
|
||||
'AUD',
|
||||
'DKK',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'CZK',
|
||||
),
|
||||
'PT' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'CAD',
|
||||
'GBP',
|
||||
'CZK',
|
||||
),
|
||||
'RO' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'GBP',
|
||||
),
|
||||
'SE' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'NOK',
|
||||
'SEK',
|
||||
),
|
||||
'SI' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
),
|
||||
'SK' => array(
|
||||
'EUR',
|
||||
'USD',
|
||||
'GBP',
|
||||
'CZK',
|
||||
'HUF',
|
||||
),
|
||||
'JP' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
|
@ -762,16 +915,51 @@ return array(
|
|||
'visa' => array(),
|
||||
'amex' => array( 'AUD' ),
|
||||
),
|
||||
'BE' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD', 'CAD' ),
|
||||
),
|
||||
'BG' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'CY' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'CZ' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'CZK' ),
|
||||
),
|
||||
'DE' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'DK' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'DKK' ),
|
||||
),
|
||||
'EE' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array(),
|
||||
),
|
||||
'ES' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'FI' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'FR' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
|
@ -782,6 +970,16 @@ return array(
|
|||
'visa' => array(),
|
||||
'amex' => array( 'GBP', 'USD' ),
|
||||
),
|
||||
'GR' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'HU' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'HUF' ),
|
||||
),
|
||||
'IT' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
|
@ -799,11 +997,71 @@ return array(
|
|||
'amex' => array( 'CAD' ),
|
||||
'jcb' => array( 'CAD' ),
|
||||
),
|
||||
'LT' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'LU' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'LV' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD' ),
|
||||
),
|
||||
'MT' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'MX' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array(),
|
||||
),
|
||||
'NL' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD' ),
|
||||
),
|
||||
'NO' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'NOK' ),
|
||||
),
|
||||
'PL' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD', 'GBP', 'PLN' ),
|
||||
),
|
||||
'PT' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD', 'CAD', 'GBP' ),
|
||||
),
|
||||
'RO' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD' ),
|
||||
),
|
||||
'SE' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'SEK' ),
|
||||
),
|
||||
'SI' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'SK' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'GBP' ),
|
||||
),
|
||||
'JP' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
|
|
|
@ -23,18 +23,17 @@ class ApplepayButton {
|
|||
this.ppcpConfig
|
||||
);
|
||||
|
||||
//PRODUCT DETAIL PAGE
|
||||
this.refreshContextData();
|
||||
|
||||
this.updated_contact_info = []
|
||||
this.selectedShippingMethod = []
|
||||
this.nonce = document.getElementById('woocommerce-process-checkout-nonce').value
|
||||
this.nonce = document.getElementById('woocommerce-process-checkout-nonce')?.value
|
||||
|
||||
this.log = function() {
|
||||
if ( this.buttonConfig.is_debug ) {
|
||||
console.log('[ApplePayButton]', ...arguments);
|
||||
}
|
||||
}
|
||||
|
||||
this.refreshContextData();
|
||||
}
|
||||
|
||||
init(config) {
|
||||
|
@ -260,6 +259,8 @@ class ApplepayButton {
|
|||
case 'product':
|
||||
// Refresh product data that makes the price change.
|
||||
this.productQuantity = document.querySelector('input.qty').value;
|
||||
this.products = this.contextHandler.products();
|
||||
this.log('Products updated', this.products);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -389,6 +390,7 @@ class ApplepayButton {
|
|||
return {
|
||||
action: 'ppcp_update_shipping_contact',
|
||||
product_id: product_id,
|
||||
products: JSON.stringify(this.products),
|
||||
caller_page: 'productDetail',
|
||||
product_quantity: this.productQuantity,
|
||||
simplified_contact: event.shippingContact,
|
||||
|
@ -419,6 +421,7 @@ class ApplepayButton {
|
|||
action: 'ppcp_update_shipping_method',
|
||||
shipping_method: event.shippingMethod,
|
||||
product_id: product_id,
|
||||
products: JSON.stringify(this.products),
|
||||
caller_page: 'productDetail',
|
||||
product_quantity: this.productQuantity,
|
||||
simplified_contact: this.updated_contact_info,
|
||||
|
@ -456,6 +459,7 @@ class ApplepayButton {
|
|||
action: 'ppcp_create_order',
|
||||
'caller_page': this.context,
|
||||
'product_id': this.buttonConfig.product.id ?? null,
|
||||
'products': JSON.stringify(this.products),
|
||||
'product_quantity': this.productQuantity ?? null,
|
||||
'shipping_contact': shippingContact,
|
||||
'billing_contact': billingContact,
|
||||
|
|
|
@ -49,12 +49,20 @@ class SingleProductHandler extends BaseHandler {
|
|||
}
|
||||
|
||||
createOrder() {
|
||||
return this.actionHandler().configuration().createOrder();
|
||||
}
|
||||
|
||||
products() {
|
||||
return this.actionHandler().getProducts();
|
||||
}
|
||||
|
||||
actionHandler() {
|
||||
const errorHandler = new ErrorHandler(
|
||||
this.ppcpConfig.labels.error.generic,
|
||||
document.querySelector('.woocommerce-notices-wrapper')
|
||||
);
|
||||
|
||||
const actionHandler = new SingleProductActionHandler(
|
||||
return new SingleProductActionHandler(
|
||||
this.ppcpConfig,
|
||||
new UpdateCart(
|
||||
this.ppcpConfig.ajax.change_cart.endpoint,
|
||||
|
@ -63,8 +71,6 @@ class SingleProductHandler extends BaseHandler {
|
|||
document.querySelector('form.cart'),
|
||||
errorHandler,
|
||||
);
|
||||
|
||||
return actionHandler.configuration().createOrder();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -100,7 +100,6 @@ return array(
|
|||
return new DataToAppleButtonScripts( $container->get( 'applepay.sdk_script_url' ), $container->get( 'wcgateway.settings' ) );
|
||||
},
|
||||
'applepay.button' => static function ( ContainerInterface $container ): ApplePayButton {
|
||||
|
||||
return new ApplePayButton(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' ),
|
||||
|
@ -108,7 +107,8 @@ return array(
|
|||
$container->get( 'applepay.url' ),
|
||||
$container->get( 'ppcp.asset-version' ),
|
||||
$container->get( 'applepay.data_to_scripts' ),
|
||||
$container->get( 'wcgateway.settings.status' )
|
||||
$container->get( 'wcgateway.settings.status' ),
|
||||
$container->get( 'button.helper.cart-products' )
|
||||
);
|
||||
},
|
||||
'applepay.blocks-payment-method' => static function ( ContainerInterface $container ): PaymentMethodTypeInterface {
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\Applepay;
|
|||
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
|
||||
use WooCommerce\PayPalCommerce\Applepay\Assets\ApplePayButton;
|
||||
use WooCommerce\PayPalCommerce\Applepay\Assets\AppleProductStatus;
|
||||
use WooCommerce\PayPalCommerce\Applepay\Assets\PropertiesDictionary;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\ButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Applepay\Helper\AvailabilityNotice;
|
||||
|
@ -40,6 +41,7 @@ class ApplepayModule implements ModuleInterface {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
public function run( ContainerInterface $c ): void {
|
||||
$module = $this;
|
||||
|
||||
// Clears product status when appropriate.
|
||||
add_action(
|
||||
|
@ -51,38 +53,65 @@ class ApplepayModule implements ModuleInterface {
|
|||
}
|
||||
);
|
||||
|
||||
// Check if the module is applicable, correct country, currency, ... etc.
|
||||
if ( ! $c->get( 'applepay.eligible' ) ) {
|
||||
return;
|
||||
}
|
||||
add_action(
|
||||
'init',
|
||||
static function () use ( $c, $module ) {
|
||||
|
||||
// Load the button handler.
|
||||
$apple_payment_method = $c->get( 'applepay.button' );
|
||||
// add onboarding and referrals hooks.
|
||||
assert( $apple_payment_method instanceof ApplepayButton );
|
||||
$apple_payment_method->initialize();
|
||||
// Check if the module is applicable, correct country, currency, ... etc.
|
||||
if ( ! $c->get( 'applepay.eligible' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show notice if there are product availability issues.
|
||||
$availability_notice = $c->get( 'applepay.availability_notice' );
|
||||
assert( $availability_notice instanceof AvailabilityNotice );
|
||||
$availability_notice->execute();
|
||||
// Load the button handler.
|
||||
$apple_payment_method = $c->get( 'applepay.button' );
|
||||
// add onboarding and referrals hooks.
|
||||
assert( $apple_payment_method instanceof ApplepayButton );
|
||||
$apple_payment_method->initialize();
|
||||
|
||||
// Return if server not supported.
|
||||
if ( ! $c->get( 'applepay.server_supported' ) ) {
|
||||
return;
|
||||
}
|
||||
// Show notice if there are product availability issues.
|
||||
$availability_notice = $c->get( 'applepay.availability_notice' );
|
||||
assert( $availability_notice instanceof AvailabilityNotice );
|
||||
$availability_notice->execute();
|
||||
|
||||
// Check if this merchant can activate / use the buttons.
|
||||
// We allow non referral merchants as they can potentially still use ApplePay, we just have no way of checking the capability.
|
||||
if ( ( ! $c->get( 'applepay.available' ) ) && $c->get( 'applepay.is_referral' ) ) {
|
||||
return;
|
||||
}
|
||||
// Return if server not supported.
|
||||
if ( ! $c->get( 'applepay.server_supported' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->load_assets( $c, $apple_payment_method );
|
||||
$this->handle_validation_file( $c );
|
||||
$this->render_buttons( $c, $apple_payment_method );
|
||||
// Check if this merchant can activate / use the buttons.
|
||||
// We allow non referral merchants as they can potentially still use ApplePay, we just have no way of checking the capability.
|
||||
if ( ( ! $c->get( 'applepay.available' ) ) && $c->get( 'applepay.is_referral' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$apple_payment_method->bootstrap_ajax_request();
|
||||
$module->load_assets( $c, $apple_payment_method );
|
||||
$module->handle_validation_file( $c );
|
||||
$module->render_buttons( $c, $apple_payment_method );
|
||||
|
||||
$apple_payment_method->bootstrap_ajax_request();
|
||||
}
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'nonce_user_logged_out',
|
||||
/**
|
||||
* Prevents nonce from being changed for non logged in users.
|
||||
*
|
||||
* @param int $uid The uid.
|
||||
* @param string|int $action The action.
|
||||
* @return int
|
||||
*
|
||||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
function ( $uid, $action ) {
|
||||
if ( $action === PropertiesDictionary::NONCE_ACTION ) {
|
||||
return 0;
|
||||
}
|
||||
return $uid;
|
||||
},
|
||||
100,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,6 +14,7 @@ use Psr\Log\LoggerInterface;
|
|||
use WC_Cart;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\ButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
|
@ -25,18 +26,21 @@ use WooCommerce\PayPalCommerce\Webhooks\Handler\RequestHandlerTrait;
|
|||
*/
|
||||
class ApplePayButton implements ButtonInterface {
|
||||
use RequestHandlerTrait;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* The response templates.
|
||||
*
|
||||
|
@ -58,12 +62,14 @@ class ApplePayButton implements ButtonInterface {
|
|||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* The method title.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $method_title;
|
||||
|
||||
/**
|
||||
* The processor for orders.
|
||||
*
|
||||
|
@ -84,18 +90,21 @@ class ApplePayButton implements ButtonInterface {
|
|||
* @var string
|
||||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* The module URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $module_url;
|
||||
|
||||
/**
|
||||
* The data to send to the ApplePay button script.
|
||||
*
|
||||
* @var DataToAppleButtonScripts
|
||||
*/
|
||||
private $script_data;
|
||||
|
||||
/**
|
||||
* The Settings status helper.
|
||||
*
|
||||
|
@ -103,6 +112,13 @@ class ApplePayButton implements ButtonInterface {
|
|||
*/
|
||||
private $settings_status;
|
||||
|
||||
/**
|
||||
* The cart products helper.
|
||||
*
|
||||
* @var CartProductsHelper
|
||||
*/
|
||||
protected $cart_products;
|
||||
|
||||
/**
|
||||
* PayPalPaymentMethod constructor.
|
||||
*
|
||||
|
@ -113,6 +129,7 @@ class ApplePayButton implements ButtonInterface {
|
|||
* @param string $version The module version.
|
||||
* @param DataToAppleButtonScripts $data The data to send to the ApplePay button script.
|
||||
* @param SettingsStatus $settings_status The settings status helper.
|
||||
* @param CartProductsHelper $cart_products The cart products helper.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
|
@ -121,7 +138,8 @@ class ApplePayButton implements ButtonInterface {
|
|||
string $module_url,
|
||||
string $version,
|
||||
DataToAppleButtonScripts $data,
|
||||
SettingsStatus $settings_status
|
||||
SettingsStatus $settings_status,
|
||||
CartProductsHelper $cart_products
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->response_templates = new ResponsesToApple();
|
||||
|
@ -133,6 +151,7 @@ class ApplePayButton implements ButtonInterface {
|
|||
$this->version = $version;
|
||||
$this->script_data = $data;
|
||||
$this->settings_status = $settings_status;
|
||||
$this->cart_products = $cart_products;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -822,15 +841,24 @@ class ApplePayButton implements ButtonInterface {
|
|||
*
|
||||
* @param ApplePayDataObjectHttp $applepay_request_data_object The request data object.
|
||||
* @return bool | string The cart item key after adding to the new cart.
|
||||
* @throws \Exception If cannot be added to cart.
|
||||
* @throws \Exception If it cannot be added to cart.
|
||||
*/
|
||||
public function prepare_cart( ApplePayDataObjectHttp $applepay_request_data_object ): string {
|
||||
$this->save_old_cart();
|
||||
$cart = WC()->cart;
|
||||
return $cart->add_to_cart(
|
||||
(int) $applepay_request_data_object->product_id(),
|
||||
(int) $applepay_request_data_object->product_quantity()
|
||||
$this->cart_products->set_cart( WC()->cart );
|
||||
|
||||
$product = $this->cart_products->product_from_data(
|
||||
array(
|
||||
'id' => (int) $applepay_request_data_object->product_id(),
|
||||
'quantity' => (int) $applepay_request_data_object->product_quantity(),
|
||||
'variations' => $applepay_request_data_object->product_variations(),
|
||||
'extra' => $applepay_request_data_object->product_extra(),
|
||||
'booking' => $applepay_request_data_object->product_booking(),
|
||||
)
|
||||
);
|
||||
|
||||
$this->cart_products->add_products( array( $product ) );
|
||||
return $this->cart_products->cart_item_keys()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,13 +38,6 @@ class ApplePayDataObjectHttp {
|
|||
*/
|
||||
protected $need_shipping;
|
||||
|
||||
/**
|
||||
* The product id.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $product_id = '';
|
||||
|
||||
/**
|
||||
* The caller page.
|
||||
*
|
||||
|
@ -52,6 +45,13 @@ class ApplePayDataObjectHttp {
|
|||
*/
|
||||
protected $caller_page;
|
||||
|
||||
/**
|
||||
* The product id.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $product_id = '';
|
||||
|
||||
/**
|
||||
* The product quantity.
|
||||
*
|
||||
|
@ -59,6 +59,27 @@ class ApplePayDataObjectHttp {
|
|||
*/
|
||||
protected $product_quantity = '';
|
||||
|
||||
/**
|
||||
* The product variations.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $product_variations = array();
|
||||
|
||||
/**
|
||||
* The product extra.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $product_extra = array();
|
||||
|
||||
/**
|
||||
* The product booking.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $product_booking = array();
|
||||
|
||||
/**
|
||||
* The shipping methods.
|
||||
*
|
||||
|
@ -166,6 +187,9 @@ class ApplePayDataObjectHttp {
|
|||
if ( ! $data ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $this->preprocess_request_data( $data );
|
||||
|
||||
$result = $this->update_required_data(
|
||||
$data,
|
||||
PropertiesDictionary::UPDATE_CONTACT_SINGLE_PROD_REQUIRED_FIELDS,
|
||||
|
@ -198,6 +222,9 @@ class ApplePayDataObjectHttp {
|
|||
if ( ! $data ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $this->preprocess_request_data( $data );
|
||||
|
||||
$result = $this->update_required_data(
|
||||
$data,
|
||||
PropertiesDictionary::UPDATE_METHOD_SINGLE_PROD_REQUIRED_FIELDS,
|
||||
|
@ -226,6 +253,10 @@ class ApplePayDataObjectHttp {
|
|||
if ( ! $data ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $this->append_products_to_data( $data, $_POST );
|
||||
$data = $this->preprocess_request_data( $data );
|
||||
|
||||
$data[ PropertiesDictionary::CALLER_PAGE ] = $caller_page;
|
||||
$result = $this->update_required_data(
|
||||
$data,
|
||||
|
@ -261,6 +292,27 @@ class ApplePayDataObjectHttp {
|
|||
$this->update_shipping_method( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-processes request data to transform it to a standard format.
|
||||
*
|
||||
* @param array $data The data.
|
||||
* @return array
|
||||
*/
|
||||
protected function preprocess_request_data( array $data ): array {
|
||||
// Fill product variables if a products object is received.
|
||||
if ( is_array( $data[ PropertiesDictionary::PRODUCTS ] ?? null ) ) {
|
||||
$product = $data[ PropertiesDictionary::PRODUCTS ][0];
|
||||
|
||||
$data[ PropertiesDictionary::PRODUCT_ID ] = $product['id'] ?? 0;
|
||||
$data[ PropertiesDictionary::PRODUCT_QUANTITY ] = $product['quantity'] ?? array();
|
||||
$data[ PropertiesDictionary::PRODUCT_VARIATIONS ] = $product['variations'] ?? array();
|
||||
$data[ PropertiesDictionary::PRODUCT_EXTRA ] = $product['extra'] ?? array();
|
||||
$data[ PropertiesDictionary::PRODUCT_BOOKING ] = $product['booking'] ?? array();
|
||||
}
|
||||
unset( $data[ PropertiesDictionary::PRODUCTS ] );
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the array contains all required fields and if those
|
||||
* are not empty.
|
||||
|
@ -300,7 +352,7 @@ class ApplePayDataObjectHttp {
|
|||
*/
|
||||
protected function assign_data_object_values( array $data ): void {
|
||||
foreach ( $data as $key => $value ) {
|
||||
// Null values may give origin to type errors. If necessary replace condition this with a specialized field filter.
|
||||
// Null values may give origin to type errors. If necessary replace this condition with a specialized field filter.
|
||||
if ( null === $value ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -547,6 +599,33 @@ class ApplePayDataObjectHttp {
|
|||
return $this->product_quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product variations.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function product_variations(): array {
|
||||
return $this->product_variations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product extra.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function product_extra(): array {
|
||||
return $this->product_extra;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product booking.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function product_booking(): array {
|
||||
return $this->product_booking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nonce.
|
||||
*
|
||||
|
@ -580,7 +659,7 @@ class ApplePayDataObjectHttp {
|
|||
* @return array|false|null
|
||||
*/
|
||||
public function get_filtered_request_data() {
|
||||
return filter_input_array(
|
||||
$data = filter_input_array(
|
||||
INPUT_POST,
|
||||
array(
|
||||
PropertiesDictionary::CALLER_PAGE => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
|
@ -604,8 +683,43 @@ class ApplePayDataObjectHttp {
|
|||
),
|
||||
PropertiesDictionary::PRODUCT_ID => FILTER_SANITIZE_NUMBER_INT,
|
||||
PropertiesDictionary::PRODUCT_QUANTITY => FILTER_SANITIZE_NUMBER_INT,
|
||||
PropertiesDictionary::PRODUCT_VARIATIONS => array(
|
||||
'filter' => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
'flags' => FILTER_REQUIRE_ARRAY,
|
||||
),
|
||||
PropertiesDictionary::PRODUCT_EXTRA => array(
|
||||
'filter' => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
'flags' => FILTER_REQUIRE_ARRAY,
|
||||
),
|
||||
PropertiesDictionary::PRODUCT_BOOKING => array(
|
||||
'filter' => FILTER_SANITIZE_SPECIAL_CHARS,
|
||||
'flags' => FILTER_REQUIRE_ARRAY,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! $data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->append_products_to_data( $data, $_POST );
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends product to a data array.
|
||||
*
|
||||
* @param array $data The data.
|
||||
* @param array $request_data The request data.
|
||||
* @return array
|
||||
*/
|
||||
public function append_products_to_data( array $data, array $request_data ): array {
|
||||
$products = json_decode( wp_unslash( $request_data[ PropertiesDictionary::PRODUCTS ] ?? '' ), true );
|
||||
|
||||
if ( $products ) {
|
||||
$data[ PropertiesDictionary::PRODUCTS ] = $products;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -169,37 +169,32 @@ class DataToAppleButtonScripts {
|
|||
if ( ! $cart ) {
|
||||
return array();
|
||||
}
|
||||
$nonce = wp_nonce_field( 'woocommerce-process_checkout', 'woocommerce-process-checkout-nonce' );
|
||||
$button_markup =
|
||||
'<div id="applepay-container">'
|
||||
. $nonce
|
||||
. '</div>';
|
||||
$type = $this->settings->has( 'applepay_button_type' ) ? $this->settings->get( 'applepay_button_type' ) : '';
|
||||
$color = $this->settings->has( 'applepay_button_color' ) ? $this->settings->get( 'applepay_button_color' ) : '';
|
||||
$lang = $this->settings->has( 'applepay_button_language' ) ? $this->settings->get( 'applepay_button_language' ) : '';
|
||||
$lang = apply_filters( 'woocommerce_paypal_payments_applepay_button_language', $lang );
|
||||
|
||||
$type = $this->settings->has( 'applepay_button_type' ) ? $this->settings->get( 'applepay_button_type' ) : '';
|
||||
$color = $this->settings->has( 'applepay_button_color' ) ? $this->settings->get( 'applepay_button_color' ) : '';
|
||||
$lang = $this->settings->has( 'applepay_button_language' ) ? $this->settings->get( 'applepay_button_language' ) : '';
|
||||
$lang = apply_filters( 'woocommerce_paypal_payments_applepay_button_language', $lang );
|
||||
|
||||
return array(
|
||||
'sdk_url' => $this->sdk_url,
|
||||
'is_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG ? true : false,
|
||||
'button' => array(
|
||||
'sdk_url' => $this->sdk_url,
|
||||
'is_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG ? true : false,
|
||||
'button' => array(
|
||||
'wrapper' => 'applepay-container',
|
||||
'mini_cart_wrapper' => 'applepay-container-minicart',
|
||||
'type' => $type,
|
||||
'color' => $color,
|
||||
'lang' => $lang,
|
||||
),
|
||||
'product' => array(
|
||||
'product' => array(
|
||||
'needShipping' => $cart->needs_shipping(),
|
||||
'subtotal' => $cart->get_subtotal(),
|
||||
),
|
||||
'shop' => array(
|
||||
'shop' => array(
|
||||
'countryCode' => $shop_country_code,
|
||||
'currencyCode' => $currency_code,
|
||||
'totalLabel' => $total_label,
|
||||
),
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
'buttonMarkup' => $button_markup,
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ namespace WooCommerce\PayPalCommerce\Applepay\Assets;
|
|||
*/
|
||||
class PropertiesDictionary {
|
||||
|
||||
|
||||
public const BILLING_CONTACT_INVALID = 'billing Contact Invalid';
|
||||
|
||||
public const CREATE_ORDER_SINGLE_PROD_REQUIRED_FIELDS =
|
||||
|
@ -62,19 +61,22 @@ class PropertiesDictionary {
|
|||
self::SIMPLIFIED_CONTACT,
|
||||
);
|
||||
|
||||
public const PRODUCT_ID = 'product_id';
|
||||
|
||||
public const SIMPLIFIED_CONTACT = 'simplified_contact';
|
||||
|
||||
public const SHIPPING_METHOD = 'shipping_method';
|
||||
|
||||
public const SHIPPING_CONTACT = 'shipping_contact';
|
||||
public const PRODUCTS = 'products';
|
||||
public const PRODUCT_ID = 'product_id';
|
||||
public const PRODUCT_QUANTITY = 'product_quantity';
|
||||
public const PRODUCT_VARIATIONS = 'product_variations';
|
||||
public const PRODUCT_EXTRA = 'product_extra';
|
||||
public const PRODUCT_BOOKING = 'product_booking';
|
||||
|
||||
public const SIMPLIFIED_CONTACT = 'simplified_contact';
|
||||
public const SHIPPING_METHOD = 'shipping_method';
|
||||
public const SHIPPING_CONTACT = 'shipping_contact';
|
||||
public const SHIPPING_CONTACT_INVALID = 'shipping Contact Invalid';
|
||||
public const BILLING_CONTACT = 'billing_contact';
|
||||
|
||||
public const NONCE = 'nonce';
|
||||
|
||||
public const WCNONCE = 'woocommerce-process-checkout-nonce';
|
||||
public const NONCE = 'nonce';
|
||||
public const NONCE_ACTION = 'woocommerce-process_checkout';
|
||||
public const WCNONCE = 'woocommerce-process-checkout-nonce';
|
||||
|
||||
public const CREATE_ORDER_CART_REQUIRED_FIELDS =
|
||||
array(
|
||||
|
@ -83,25 +85,16 @@ class PropertiesDictionary {
|
|||
self::SHIPPING_CONTACT,
|
||||
);
|
||||
|
||||
public const PRODUCT_QUANTITY = 'product_quantity';
|
||||
|
||||
public const CALLER_PAGE = 'caller_page';
|
||||
|
||||
public const BILLING_CONTACT = 'billing_contact';
|
||||
|
||||
public const NEED_SHIPPING = 'need_shipping';
|
||||
|
||||
public const UPDATE_SHIPPING_CONTACT = 'ppcp_update_shipping_contact';
|
||||
|
||||
public const UPDATE_SHIPPING_METHOD = 'ppcp_update_shipping_method';
|
||||
|
||||
public const CREATE_ORDER = 'ppcp_create_order';
|
||||
|
||||
public const CREATE_ORDER_CART = 'ppcp_create_order_cart';
|
||||
|
||||
public const REDIRECT = 'ppcp_redirect';
|
||||
|
||||
public const VALIDATE = 'ppcp_validate';
|
||||
public const UPDATE_SHIPPING_METHOD = 'ppcp_update_shipping_method';
|
||||
public const CREATE_ORDER = 'ppcp_create_order';
|
||||
public const CREATE_ORDER_CART = 'ppcp_create_order_cart';
|
||||
public const REDIRECT = 'ppcp_redirect';
|
||||
public const VALIDATE = 'ppcp_validate';
|
||||
|
||||
/**
|
||||
* Returns the possible list of button colors.
|
||||
|
|
|
@ -124,3 +124,29 @@ export const paypalOrderToWcAddresses = (order) => {
|
|||
|
||||
return {billingAddress, shippingAddress};
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges two WC addresses.
|
||||
* The objects can contain either the WC form fields or billingAddress, shippingAddress objects.
|
||||
*
|
||||
* @param {Object} address1
|
||||
* @param {Object} address2
|
||||
* @returns {any}
|
||||
*/
|
||||
export const mergeWcAddress = (address1, address2) => {
|
||||
if ('billingAddress' in address1) {
|
||||
return {
|
||||
billingAddress: mergeWcAddress(address1.billingAddress, address2.billingAddress),
|
||||
shippingAddress: mergeWcAddress(address1.shippingAddress, address2.shippingAddress),
|
||||
}
|
||||
}
|
||||
|
||||
let address2WithoutEmpty = {...address2};
|
||||
Object.keys(address2).forEach(key => {
|
||||
if (address2[key] === '') {
|
||||
delete address2WithoutEmpty[key];
|
||||
}
|
||||
});
|
||||
|
||||
return {...address1, ...address2WithoutEmpty};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {useEffect, useState} from '@wordpress/element';
|
||||
import {registerExpressPaymentMethod, registerPaymentMethod} from '@woocommerce/blocks-registry';
|
||||
import {paypalAddressToWc, paypalOrderToWcAddresses} from "./Helper/Address";
|
||||
import {mergeWcAddress, paypalAddressToWc, paypalOrderToWcAddresses} from "./Helper/Address";
|
||||
import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading'
|
||||
import buttonModuleWatcher from "../../../ppcp-button/resources/js/modules/ButtonModuleWatcher";
|
||||
|
||||
|
@ -24,6 +24,22 @@ const PayPalComponent = ({
|
|||
|
||||
const [paypalOrder, setPaypalOrder] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
// fill the form if in continuation (for product or mini-cart buttons)
|
||||
if (!config.scriptData.continuation || !config.scriptData.continuation.order || window.ppcpContinuationFilled) {
|
||||
return;
|
||||
}
|
||||
const paypalAddresses = paypalOrderToWcAddresses(config.scriptData.continuation.order);
|
||||
const wcAddresses = wp.data.select('wc/store/cart').getCustomerData();
|
||||
const addresses = mergeWcAddress(wcAddresses, paypalAddresses);
|
||||
wp.data.dispatch('wc/store/cart').setBillingAddress(addresses.billingAddress);
|
||||
if (shippingData.needsShipping) {
|
||||
wp.data.dispatch('wc/store/cart').setShippingAddress(addresses.shippingAddress);
|
||||
}
|
||||
// this useEffect should run only once, but adding this in case of some kind of full re-rendering
|
||||
window.ppcpContinuationFilled = true;
|
||||
}, [])
|
||||
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
useEffect(() => {
|
||||
if (!loaded) {
|
||||
|
|
|
@ -167,6 +167,11 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType {
|
|||
$script_data['continuation']['cancel'] = array(
|
||||
'html' => $this->cancellation_view->render_session_cancellation( $url, $this->session_handler->funding_source() ),
|
||||
);
|
||||
|
||||
$order = $this->session_handler->order();
|
||||
if ( $order ) {
|
||||
$script_data['continuation']['order'] = $order->to_array();
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\Button;
|
|||
use WooCommerce\PayPalCommerce\Button\Endpoint\ApproveSubscriptionEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\CartScriptParamsEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\SimulateCartEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\CheckoutFormSaver;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\SaveCheckoutFormEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Button\Validation\CheckoutFormValidator;
|
||||
|
@ -128,24 +129,24 @@ return array(
|
|||
if ( ! \WC()->cart ) {
|
||||
throw new RuntimeException( 'cant initialize endpoint at this moment' );
|
||||
}
|
||||
$smart_button = $container->get( 'button.smart-button' );
|
||||
$cart = WC()->cart;
|
||||
$request_data = $container->get( 'button.request-data' );
|
||||
$data_store = \WC_Data_Store::load( 'product' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new SimulateCartEndpoint( $smart_button, $cart, $request_data, $data_store, $logger );
|
||||
$smart_button = $container->get( 'button.smart-button' );
|
||||
$cart = WC()->cart;
|
||||
$request_data = $container->get( 'button.request-data' );
|
||||
$cart_products = $container->get( 'button.helper.cart-products' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new SimulateCartEndpoint( $smart_button, $cart, $request_data, $cart_products, $logger );
|
||||
},
|
||||
'button.endpoint.change-cart' => static function ( ContainerInterface $container ): ChangeCartEndpoint {
|
||||
if ( ! \WC()->cart ) {
|
||||
throw new RuntimeException( 'cant initialize endpoint at this moment' );
|
||||
}
|
||||
$cart = WC()->cart;
|
||||
$shipping = WC()->shipping();
|
||||
$request_data = $container->get( 'button.request-data' );
|
||||
$cart = WC()->cart;
|
||||
$shipping = WC()->shipping();
|
||||
$request_data = $container->get( 'button.request-data' );
|
||||
$purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
|
||||
$data_store = \WC_Data_Store::load( 'product' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new ChangeCartEndpoint( $cart, $shipping, $request_data, $purchase_unit_factory, $data_store, $logger );
|
||||
$cart_products = $container->get( 'button.helper.cart-products' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new ChangeCartEndpoint( $cart, $shipping, $request_data, $purchase_unit_factory, $cart_products, $logger );
|
||||
},
|
||||
'button.endpoint.create-order' => static function ( ContainerInterface $container ): CreateOrderEndpoint {
|
||||
$request_data = $container->get( 'button.request-data' );
|
||||
|
@ -251,6 +252,12 @@ return array(
|
|||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
|
||||
'button.helper.cart-products' => static function ( ContainerInterface $container ): CartProductsHelper {
|
||||
$data_store = \WC_Data_Store::load( 'product' );
|
||||
return new CartProductsHelper( $data_store );
|
||||
},
|
||||
|
||||
'button.helper.three-d-secure' => static function ( ContainerInterface $container ): ThreeDSecure {
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new ThreeDSecure( $logger );
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
|
|||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper;
|
||||
|
||||
/**
|
||||
* Abstract Class AbstractCartEndpoint
|
||||
|
@ -26,11 +27,11 @@ abstract class AbstractCartEndpoint implements EndpointInterface {
|
|||
protected $cart;
|
||||
|
||||
/**
|
||||
* The product data store.
|
||||
* The cart products helper.
|
||||
*
|
||||
* @var \WC_Data_Store
|
||||
* @var CartProductsHelper
|
||||
*/
|
||||
protected $product_data_store;
|
||||
protected $cart_products;
|
||||
|
||||
/**
|
||||
* The request data helper.
|
||||
|
@ -53,13 +54,6 @@ abstract class AbstractCartEndpoint implements EndpointInterface {
|
|||
*/
|
||||
protected $logger_tag = '';
|
||||
|
||||
/**
|
||||
* The added cart item IDs
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $cart_item_keys = array();
|
||||
|
||||
/**
|
||||
* The nonce.
|
||||
*
|
||||
|
@ -110,44 +104,13 @@ abstract class AbstractCartEndpoint implements EndpointInterface {
|
|||
protected function add_products( array $products ): bool {
|
||||
$this->cart->empty_cart( false );
|
||||
|
||||
$success = true;
|
||||
foreach ( $products as $product ) {
|
||||
|
||||
// Add extras to POST, they are usually added by custom plugins.
|
||||
if ( $product['extra'] && is_array( $product['extra'] ) ) {
|
||||
// Handle cases like field[].
|
||||
$query = http_build_query( $product['extra'] );
|
||||
parse_str( $query, $extra );
|
||||
|
||||
foreach ( $extra as $key => $value ) {
|
||||
$_POST[ $key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $product['product']->is_type( 'booking' ) ) {
|
||||
$success = $success && $this->add_booking_product(
|
||||
$product['product'],
|
||||
$product['booking']
|
||||
);
|
||||
} elseif ( $product['product']->is_type( 'variable' ) ) {
|
||||
$success = $success && $this->add_variable_product(
|
||||
$product['product'],
|
||||
$product['quantity'],
|
||||
$product['variations']
|
||||
);
|
||||
} else {
|
||||
$success = $success && $this->add_product(
|
||||
$product['product'],
|
||||
$product['quantity']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $success ) {
|
||||
try {
|
||||
$this->cart_products->add_products( $products );
|
||||
} catch ( Exception $e ) {
|
||||
$this->handle_error();
|
||||
}
|
||||
|
||||
return $success;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,7 +156,7 @@ abstract class AbstractCartEndpoint implements EndpointInterface {
|
|||
*/
|
||||
protected function products_from_request() {
|
||||
$data = $this->request_data->read_request( $this->nonce() );
|
||||
$products = $this->products_from_data( $data );
|
||||
$products = $this->cart_products->products_from_data( $data );
|
||||
if ( ! $products ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
|
@ -212,141 +175,12 @@ abstract class AbstractCartEndpoint implements EndpointInterface {
|
|||
return $products;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns product information from a data array.
|
||||
*
|
||||
* @param array $data The data array.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
protected function products_from_data( array $data ): ?array {
|
||||
|
||||
$products = array();
|
||||
|
||||
if (
|
||||
! isset( $data['products'] )
|
||||
|| ! is_array( $data['products'] )
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
foreach ( $data['products'] as $product ) {
|
||||
if ( ! isset( $product['quantity'] ) || ! isset( $product['id'] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$wc_product = wc_get_product( (int) $product['id'] );
|
||||
|
||||
if ( ! $wc_product ) {
|
||||
return null;
|
||||
}
|
||||
$products[] = array(
|
||||
'product' => $wc_product,
|
||||
'quantity' => (int) $product['quantity'],
|
||||
'variations' => $product['variations'] ?? null,
|
||||
'booking' => $product['booking'] ?? null,
|
||||
'extra' => $product['extra'] ?? null,
|
||||
);
|
||||
}
|
||||
return $products;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a product to the cart.
|
||||
*
|
||||
* @param \WC_Product $product The Product.
|
||||
* @param int $quantity The Quantity.
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception When product could not be added.
|
||||
*/
|
||||
private function add_product( \WC_Product $product, int $quantity ): bool {
|
||||
$cart_item_key = $this->cart->add_to_cart( $product->get_id(), $quantity );
|
||||
|
||||
if ( $cart_item_key ) {
|
||||
$this->cart_item_keys[] = $cart_item_key;
|
||||
}
|
||||
return false !== $cart_item_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds variations to the cart.
|
||||
*
|
||||
* @param \WC_Product $product The Product.
|
||||
* @param int $quantity The Quantity.
|
||||
* @param array $post_variations The variations.
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception When product could not be added.
|
||||
*/
|
||||
private function add_variable_product(
|
||||
\WC_Product $product,
|
||||
int $quantity,
|
||||
array $post_variations
|
||||
): bool {
|
||||
|
||||
$variations = array();
|
||||
foreach ( $post_variations as $key => $value ) {
|
||||
$variations[ $value['name'] ] = $value['value'];
|
||||
}
|
||||
|
||||
$variation_id = $this->product_data_store->find_matching_product_variation( $product, $variations );
|
||||
|
||||
// ToDo: Check stock status for variation.
|
||||
$cart_item_key = $this->cart->add_to_cart(
|
||||
$product->get_id(),
|
||||
$quantity,
|
||||
$variation_id,
|
||||
$variations
|
||||
);
|
||||
|
||||
if ( $cart_item_key ) {
|
||||
$this->cart_item_keys[] = $cart_item_key;
|
||||
}
|
||||
return false !== $cart_item_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds booking to the cart.
|
||||
*
|
||||
* @param \WC_Product $product The Product.
|
||||
* @param array $data Data used by the booking plugin.
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception When product could not be added.
|
||||
*/
|
||||
private function add_booking_product(
|
||||
\WC_Product $product,
|
||||
array $data
|
||||
): bool {
|
||||
|
||||
if ( ! is_callable( 'wc_bookings_get_posted_data' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cart_item_data = array(
|
||||
'booking' => wc_bookings_get_posted_data( $data, $product ),
|
||||
);
|
||||
|
||||
$cart_item_key = $this->cart->add_to_cart( $product->get_id(), 1, 0, array(), $cart_item_data );
|
||||
|
||||
if ( $cart_item_key ) {
|
||||
$this->cart_item_keys[] = $cart_item_key;
|
||||
}
|
||||
return false !== $cart_item_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes stored cart items from WooCommerce cart.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function remove_cart_items(): void {
|
||||
foreach ( $this->cart_item_keys as $cart_item_key ) {
|
||||
if ( ! $cart_item_key ) {
|
||||
continue;
|
||||
}
|
||||
$this->cart->remove_cart_item( $cart_item_key );
|
||||
}
|
||||
$this->cart_products->remove_cart_items();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
|
|||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper;
|
||||
|
||||
/**
|
||||
* Class ChangeCartEndpoint
|
||||
|
@ -41,7 +42,7 @@ class ChangeCartEndpoint extends AbstractCartEndpoint {
|
|||
* @param \WC_Shipping $shipping The current WC shipping object.
|
||||
* @param RequestData $request_data The request data helper.
|
||||
* @param PurchaseUnitFactory $purchase_unit_factory The PurchaseUnit factory.
|
||||
* @param \WC_Data_Store $product_data_store The data store for products.
|
||||
* @param CartProductsHelper $cart_products The cart products helper.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -49,7 +50,7 @@ class ChangeCartEndpoint extends AbstractCartEndpoint {
|
|||
\WC_Shipping $shipping,
|
||||
RequestData $request_data,
|
||||
PurchaseUnitFactory $purchase_unit_factory,
|
||||
\WC_Data_Store $product_data_store,
|
||||
CartProductsHelper $cart_products,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
|
||||
|
@ -57,7 +58,7 @@ class ChangeCartEndpoint extends AbstractCartEndpoint {
|
|||
$this->shipping = $shipping;
|
||||
$this->request_data = $request_data;
|
||||
$this->purchase_unit_factory = $purchase_unit_factory;
|
||||
$this->product_data_store = $product_data_store;
|
||||
$this->cart_products = $cart_products;
|
||||
$this->logger = $logger;
|
||||
|
||||
$this->logger_tag = 'updating';
|
||||
|
@ -70,6 +71,8 @@ class ChangeCartEndpoint extends AbstractCartEndpoint {
|
|||
* @throws Exception On error.
|
||||
*/
|
||||
protected function handle_data(): bool {
|
||||
$this->cart_products->set_cart( $this->cart );
|
||||
|
||||
$products = $this->products_from_request();
|
||||
|
||||
if ( ! $products ) {
|
||||
|
|
|
@ -13,6 +13,7 @@ use Exception;
|
|||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper;
|
||||
|
||||
/**
|
||||
* Class SimulateCartEndpoint
|
||||
|
@ -38,24 +39,24 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
|
|||
/**
|
||||
* ChangeCartEndpoint constructor.
|
||||
*
|
||||
* @param SmartButton $smart_button The SmartButton.
|
||||
* @param \WC_Cart $cart The current WC cart object.
|
||||
* @param RequestData $request_data The request data helper.
|
||||
* @param \WC_Data_Store $product_data_store The data store for products.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param SmartButton $smart_button The SmartButton.
|
||||
* @param \WC_Cart $cart The current WC cart object.
|
||||
* @param RequestData $request_data The request data helper.
|
||||
* @param CartProductsHelper $cart_products The cart products helper.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
SmartButton $smart_button,
|
||||
\WC_Cart $cart,
|
||||
RequestData $request_data,
|
||||
\WC_Data_Store $product_data_store,
|
||||
CartProductsHelper $cart_products,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->smart_button = $smart_button;
|
||||
$this->cart = clone $cart;
|
||||
$this->request_data = $request_data;
|
||||
$this->product_data_store = $product_data_store;
|
||||
$this->logger = $logger;
|
||||
$this->smart_button = $smart_button;
|
||||
$this->cart = clone $cart;
|
||||
$this->request_data = $request_data;
|
||||
$this->cart_products = $cart_products;
|
||||
$this->logger = $logger;
|
||||
|
||||
$this->logger_tag = 'simulation';
|
||||
}
|
||||
|
@ -147,6 +148,7 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
|
|||
// Store a reference to the real cart.
|
||||
$this->real_cart = WC()->cart;
|
||||
WC()->cart = $this->cart;
|
||||
$this->cart_products->set_cart( $this->cart );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
285
modules/ppcp-button/src/Helper/CartProductsHelper.php
Normal file
285
modules/ppcp-button/src/Helper/CartProductsHelper.php
Normal file
|
@ -0,0 +1,285 @@
|
|||
<?php
|
||||
/**
|
||||
* Handles the adding of products to WooCommerce cart.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Button\Helper
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Button\Helper;
|
||||
|
||||
use Exception;
|
||||
use WC_Cart;
|
||||
use WC_Data_Store;
|
||||
|
||||
/**
|
||||
* Class CartProductsHelper
|
||||
*/
|
||||
class CartProductsHelper {
|
||||
|
||||
/**
|
||||
* The cart
|
||||
*
|
||||
* @var ?WC_Cart
|
||||
*/
|
||||
private $cart;
|
||||
|
||||
/**
|
||||
* The product data store.
|
||||
*
|
||||
* @var WC_Data_Store
|
||||
*/
|
||||
protected $product_data_store;
|
||||
|
||||
/**
|
||||
* The added cart item IDs
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $cart_item_keys = array();
|
||||
|
||||
/**
|
||||
* CheckoutFormSaver constructor.
|
||||
*
|
||||
* @param WC_Data_Store $product_data_store The data store for products.
|
||||
*/
|
||||
public function __construct(
|
||||
WC_Data_Store $product_data_store
|
||||
) {
|
||||
$this->product_data_store = $product_data_store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new cart instance.
|
||||
*
|
||||
* @param WC_Cart $cart The cart.
|
||||
* @return void
|
||||
*/
|
||||
public function set_cart( WC_Cart $cart ): void {
|
||||
$this->cart = $cart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns products information from a data array.
|
||||
*
|
||||
* @param array $data The data array.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function products_from_data( array $data ): ?array {
|
||||
|
||||
$products = array();
|
||||
|
||||
if (
|
||||
! isset( $data['products'] )
|
||||
|| ! is_array( $data['products'] )
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
foreach ( $data['products'] as $product ) {
|
||||
$product = $this->product_from_data( $product );
|
||||
if ( $product ) {
|
||||
$products[] = $product;
|
||||
}
|
||||
}
|
||||
return $products;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns product information from a data array.
|
||||
*
|
||||
* @param array $product The product data array, usually provided by the product page form.
|
||||
* @return array|null
|
||||
*/
|
||||
public function product_from_data( array $product ): ?array {
|
||||
if ( ! isset( $product['quantity'] ) || ! isset( $product['id'] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$wc_product = wc_get_product( (int) $product['id'] );
|
||||
|
||||
if ( ! $wc_product ) {
|
||||
return null;
|
||||
}
|
||||
return array(
|
||||
'product' => $wc_product,
|
||||
'quantity' => (int) $product['quantity'],
|
||||
'variations' => $product['variations'] ?? null,
|
||||
'booking' => $product['booking'] ?? null,
|
||||
'extra' => $product['extra'] ?? null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds products to cart.
|
||||
*
|
||||
* @param array $products Array of products to be added to cart.
|
||||
* @return bool
|
||||
* @throws Exception Add to cart methods throw an exception on fail.
|
||||
*/
|
||||
public function add_products( array $products ): bool {
|
||||
$success = true;
|
||||
foreach ( $products as $product ) {
|
||||
|
||||
// Add extras to POST, they are usually added by custom plugins.
|
||||
if ( $product['extra'] && is_array( $product['extra'] ) ) {
|
||||
// Handle cases like field[].
|
||||
$query = http_build_query( $product['extra'] );
|
||||
parse_str( $query, $extra );
|
||||
|
||||
foreach ( $extra as $key => $value ) {
|
||||
$_POST[ $key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $product['product']->is_type( 'booking' ) ) {
|
||||
$success = $success && $this->add_booking_product(
|
||||
$product['product'],
|
||||
$product['booking']
|
||||
);
|
||||
} elseif ( $product['product']->is_type( 'variable' ) ) {
|
||||
$success = $success && $this->add_variable_product(
|
||||
$product['product'],
|
||||
$product['quantity'],
|
||||
$product['variations']
|
||||
);
|
||||
} else {
|
||||
$success = $success && $this->add_product(
|
||||
$product['product'],
|
||||
$product['quantity']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $success ) {
|
||||
throw new Exception( 'Error adding products to cart.' );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a product to the cart.
|
||||
*
|
||||
* @param \WC_Product $product The Product.
|
||||
* @param int $quantity The Quantity.
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception When product could not be added.
|
||||
*/
|
||||
public function add_product( \WC_Product $product, int $quantity ): bool {
|
||||
if ( ! $this->cart ) {
|
||||
throw new Exception( 'Cart not set.' );
|
||||
}
|
||||
|
||||
$cart_item_key = $this->cart->add_to_cart( $product->get_id(), $quantity );
|
||||
|
||||
if ( $cart_item_key ) {
|
||||
$this->cart_item_keys[] = $cart_item_key;
|
||||
}
|
||||
return false !== $cart_item_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds variations to the cart.
|
||||
*
|
||||
* @param \WC_Product $product The Product.
|
||||
* @param int $quantity The Quantity.
|
||||
* @param array $post_variations The variations.
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception When product could not be added.
|
||||
*/
|
||||
public function add_variable_product(
|
||||
\WC_Product $product,
|
||||
int $quantity,
|
||||
array $post_variations
|
||||
): bool {
|
||||
if ( ! $this->cart ) {
|
||||
throw new Exception( 'Cart not set.' );
|
||||
}
|
||||
|
||||
$variations = array();
|
||||
foreach ( $post_variations as $key => $value ) {
|
||||
$variations[ $value['name'] ] = $value['value'];
|
||||
}
|
||||
|
||||
$variation_id = $this->product_data_store->find_matching_product_variation( $product, $variations );
|
||||
|
||||
// ToDo: Check stock status for variation.
|
||||
$cart_item_key = $this->cart->add_to_cart(
|
||||
$product->get_id(),
|
||||
$quantity,
|
||||
$variation_id,
|
||||
$variations
|
||||
);
|
||||
|
||||
if ( $cart_item_key ) {
|
||||
$this->cart_item_keys[] = $cart_item_key;
|
||||
}
|
||||
return false !== $cart_item_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds booking to the cart.
|
||||
*
|
||||
* @param \WC_Product $product The Product.
|
||||
* @param array $data Data used by the booking plugin.
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception When product could not be added.
|
||||
*/
|
||||
public function add_booking_product(
|
||||
\WC_Product $product,
|
||||
array $data
|
||||
): bool {
|
||||
if ( ! $this->cart ) {
|
||||
throw new Exception( 'Cart not set.' );
|
||||
}
|
||||
|
||||
if ( ! is_callable( 'wc_bookings_get_posted_data' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cart_item_data = array(
|
||||
'booking' => wc_bookings_get_posted_data( $data, $product ),
|
||||
);
|
||||
|
||||
$cart_item_key = $this->cart->add_to_cart( $product->get_id(), 1, 0, array(), $cart_item_data );
|
||||
|
||||
if ( $cart_item_key ) {
|
||||
$this->cart_item_keys[] = $cart_item_key;
|
||||
}
|
||||
return false !== $cart_item_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes stored cart items from WooCommerce cart.
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception Throws if there's a failure removing the cart items.
|
||||
*/
|
||||
public function remove_cart_items(): void {
|
||||
if ( ! $this->cart ) {
|
||||
throw new Exception( 'Cart not set.' );
|
||||
}
|
||||
|
||||
foreach ( $this->cart_item_keys as $cart_item_key ) {
|
||||
if ( ! $cart_item_key ) {
|
||||
continue;
|
||||
}
|
||||
$this->cart->remove_cart_item( $cart_item_key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cart item keys of the items added to cart.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function cart_item_keys(): array {
|
||||
return $this->cart_item_keys;
|
||||
}
|
||||
|
||||
}
|
|
@ -86,7 +86,7 @@ trait ContextTrait {
|
|||
return $context;
|
||||
}
|
||||
|
||||
if ( is_shop() ) {
|
||||
if ( is_shop() || is_product_category() ) {
|
||||
return 'shop';
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@ document.addEventListener(
|
|||
const loadLocation = location.href + " " + orderTrackingContainerSelector + ">*";
|
||||
const gzdSyncEnabled = config.gzd_sync_enabled;
|
||||
const wcShipmentSyncEnabled = config.wc_shipment_sync_enabled;
|
||||
const wcShippingTaxSyncEnabled = config.wc_shipping_tax_sync_enabled;
|
||||
const wcShipmentSaveButton = document.querySelector('#woocommerce-shipment-tracking .button-save-form');
|
||||
const wcShipmentTaxBuyLabelButtonSelector = '.components-modal__screen-overlay .label-purchase-modal__sidebar .purchase-section button.components-button';
|
||||
|
||||
const toggleLoaderVisibility = function() {
|
||||
const loader = document.querySelector('.ppcp-tracking-loader');
|
||||
|
@ -45,5 +47,20 @@ document.addEventListener(
|
|||
waitForTrackingUpdate(jQuery('#shipment-tracking-form'));
|
||||
})
|
||||
}
|
||||
|
||||
if (wcShippingTaxSyncEnabled && typeof(wcShippingTaxSyncEnabled) != 'undefined' && wcShippingTaxSyncEnabled != null) {
|
||||
document.addEventListener('click', function(event) {
|
||||
const wcShipmentTaxBuyLabelButton = event.target.closest(wcShipmentTaxBuyLabelButtonSelector);
|
||||
|
||||
if (wcShipmentTaxBuyLabelButton) {
|
||||
toggleLoaderVisibility();
|
||||
setTimeout(function () {
|
||||
jQuery(orderTrackingContainerSelector).load(loadLocation, "", function(){
|
||||
toggleLoaderVisibility();
|
||||
});
|
||||
}, 10000);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
@ -65,6 +65,12 @@ return array(
|
|||
'compat.ywot.is_supported_plugin_version_active' => function (): bool {
|
||||
return function_exists( 'yith_ywot_init' );
|
||||
},
|
||||
'compat.shipstation.is_supported_plugin_version_active' => function (): bool {
|
||||
return function_exists( 'woocommerce_shipstation_init' );
|
||||
},
|
||||
'compat.wc_shipping_tax.is_supported_plugin_version_active' => function (): bool {
|
||||
return class_exists( 'WC_Connect_Loader' );
|
||||
},
|
||||
|
||||
'compat.module.url' => static function ( ContainerInterface $container ): string {
|
||||
/**
|
||||
|
@ -84,6 +90,7 @@ return array(
|
|||
$container->get( 'ppcp.asset-version' ),
|
||||
$container->get( 'compat.gzd.is_supported_plugin_version_active' ),
|
||||
$container->get( 'compat.wc_shipment_tracking.is_supported_plugin_version_active' ),
|
||||
$container->get( 'compat.wc_shipping_tax.is_supported_plugin_version_active' ),
|
||||
$container->get( 'api.bearer' )
|
||||
);
|
||||
},
|
||||
|
|
|
@ -47,6 +47,13 @@ class CompatAssets {
|
|||
*/
|
||||
protected $is_wc_shipment_active;
|
||||
|
||||
/**
|
||||
* Whether WC Shipping & Tax plugin is active
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_wc_shipping_tax_active;
|
||||
|
||||
/**
|
||||
* The bearer.
|
||||
*
|
||||
|
@ -61,6 +68,7 @@ class CompatAssets {
|
|||
* @param string $version The assets version.
|
||||
* @param bool $is_gzd_active Whether Germanized plugin is active.
|
||||
* @param bool $is_wc_shipment_active Whether WC Shipments plugin is active.
|
||||
* @param bool $is_wc_shipping_tax_active Whether WC Shipping & Tax plugin is active.
|
||||
* @param Bearer $bearer The bearer.
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -68,14 +76,16 @@ class CompatAssets {
|
|||
string $version,
|
||||
bool $is_gzd_active,
|
||||
bool $is_wc_shipment_active,
|
||||
bool $is_wc_shipping_tax_active,
|
||||
Bearer $bearer
|
||||
) {
|
||||
|
||||
$this->module_url = $module_url;
|
||||
$this->version = $version;
|
||||
$this->is_gzd_active = $is_gzd_active;
|
||||
$this->is_wc_shipment_active = $is_wc_shipment_active;
|
||||
$this->bearer = $bearer;
|
||||
$this->module_url = $module_url;
|
||||
$this->version = $version;
|
||||
$this->is_gzd_active = $is_gzd_active;
|
||||
$this->is_wc_shipment_active = $is_wc_shipment_active;
|
||||
$this->is_wc_shipping_tax_active = $is_wc_shipping_tax_active;
|
||||
$this->bearer = $bearer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,6 +109,7 @@ class CompatAssets {
|
|||
array(
|
||||
'gzd_sync_enabled' => apply_filters( 'woocommerce_paypal_payments_sync_gzd_tracking', true ) && $this->is_gzd_active,
|
||||
'wc_shipment_sync_enabled' => apply_filters( 'woocommerce_paypal_payments_sync_wc_shipment_tracking', true ) && $this->is_wc_shipment_active,
|
||||
'wc_shipping_tax_sync_enabled' => apply_filters( 'woocommerce_paypal_payments_sync_wc_shipping_tax', true ) && $this->is_wc_shipping_tax_active,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,22 +9,13 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Compat;
|
||||
|
||||
use Vendidero\Germanized\Shipments\ShipmentItem;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Shipment\ShipmentFactoryInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||
use Exception;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Vendidero\Germanized\Shipments\Shipment;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Compat\Assets\CompatAssets;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Endpoint\OrderTrackingEndpoint;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WP_REST_Request;
|
||||
use WP_REST_Response;
|
||||
|
||||
/**
|
||||
* Class CompatModule
|
||||
|
@ -124,230 +115,11 @@ class CompatModule implements ModuleInterface {
|
|||
* @return void
|
||||
*/
|
||||
protected function initialize_tracking_compat_layer( ContainerInterface $c ): void {
|
||||
$is_gzd_active = $c->get( 'compat.gzd.is_supported_plugin_version_active' );
|
||||
$is_wc_shipment_tracking_active = $c->get( 'compat.wc_shipment_tracking.is_supported_plugin_version_active' );
|
||||
$is_ywot_active = $c->get( 'compat.ywot.is_supported_plugin_version_active' );
|
||||
$order_tracking_integrations = $c->get( 'order-tracking.integrations' );
|
||||
|
||||
if ( $is_gzd_active ) {
|
||||
$this->initialize_gzd_compat_layer( $c );
|
||||
}
|
||||
|
||||
if ( $is_wc_shipment_tracking_active ) {
|
||||
$this->initialize_wc_shipment_tracking_compat_layer( $c );
|
||||
}
|
||||
|
||||
if ( $is_ywot_active ) {
|
||||
$this->initialize_ywot_compat_layer( $c );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the <a href="https://wordpress.org/plugins/woocommerce-germanized/">Germanized for WooCommerce</a>
|
||||
* plugin compatibility layer.
|
||||
*
|
||||
* @link https://wordpress.org/plugins/woocommerce-germanized/
|
||||
*
|
||||
* @param ContainerInterface $c The Container.
|
||||
* @return void
|
||||
*/
|
||||
protected function initialize_gzd_compat_layer( ContainerInterface $c ): void {
|
||||
add_action(
|
||||
'woocommerce_gzd_shipment_status_shipped',
|
||||
function( int $shipment_id, Shipment $shipment ) use ( $c ) {
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_gzd_tracking', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wc_order = $shipment->get_order();
|
||||
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$order_id = $wc_order->get_id();
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
$tracking_number = $shipment->get_tracking_id();
|
||||
$carrier = $shipment->get_shipping_provider();
|
||||
$items = array_map(
|
||||
function ( ShipmentItem $item ): int {
|
||||
return $item->get_order_item_id();
|
||||
},
|
||||
$shipment->get_items()
|
||||
);
|
||||
|
||||
if ( ! $tracking_number || ! $carrier || ! $transaction_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->create_tracking( $c, $order_id, $transaction_id, $tracking_number, $carrier, $items );
|
||||
},
|
||||
500,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the <a href="https://woocommerce.com/document/shipment-tracking/">Shipment Tracking</a>
|
||||
* plugin compatibility layer.
|
||||
*
|
||||
* @link https://woocommerce.com/document/shipment-tracking/
|
||||
*
|
||||
* @param ContainerInterface $c The Container.
|
||||
* @return void
|
||||
*/
|
||||
protected function initialize_wc_shipment_tracking_compat_layer( ContainerInterface $c ): void {
|
||||
add_action(
|
||||
'wp_ajax_wc_shipment_tracking_save_form',
|
||||
function() use ( $c ) {
|
||||
check_ajax_referer( 'create-tracking-item', 'security', true );
|
||||
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_wc_shipment_tracking', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$order_id = (int) wc_clean( wp_unslash( $_POST['order_id'] ?? '' ) );
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
$tracking_number = wc_clean( wp_unslash( $_POST['tracking_number'] ?? '' ) );
|
||||
$carrier = wc_clean( wp_unslash( $_POST['tracking_provider'] ?? '' ) );
|
||||
$carrier_other = wc_clean( wp_unslash( $_POST['custom_tracking_provider'] ?? '' ) );
|
||||
$carrier = $carrier ?: $carrier_other ?: '';
|
||||
|
||||
if ( ! $tracking_number || ! is_string( $tracking_number ) || ! $carrier || ! is_string( $carrier ) || ! $transaction_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->create_tracking( $c, $order_id, $transaction_id, $tracking_number, $carrier, array() );
|
||||
}
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'woocommerce_rest_prepare_order_shipment_tracking',
|
||||
function( WP_REST_Response $response, array $tracking_item, WP_REST_Request $request ) use ( $c ): WP_REST_Response {
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_wc_shipment_tracking', true ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$callback = $request->get_attributes()['callback']['1'] ?? '';
|
||||
if ( $callback !== 'create_item' ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$order_id = $tracking_item['order_id'] ?? 0;
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
$tracking_number = $tracking_item['tracking_number'] ?? '';
|
||||
$carrier = $tracking_item['tracking_provider'] ?? '';
|
||||
$carrier_other = $tracking_item['custom_tracking_provider'] ?? '';
|
||||
$carrier = $carrier ?: $carrier_other ?: '';
|
||||
|
||||
if ( ! $tracking_number || ! $carrier || ! $transaction_id ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$this->create_tracking( $c, $order_id, $transaction_id, $tracking_number, $carrier, array() );
|
||||
|
||||
return $response;
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the <a href="https://wordpress.org/plugins/yith-woocommerce-order-tracking/">YITH WooCommerce Order & Shipment Tracking</a>
|
||||
* plugin compatibility layer.
|
||||
*
|
||||
* @link https://wordpress.org/plugins/yith-woocommerce-order-tracking/
|
||||
*
|
||||
* @param ContainerInterface $c The Container.
|
||||
* @return void
|
||||
*/
|
||||
protected function initialize_ywot_compat_layer( ContainerInterface $c ): void {
|
||||
add_action(
|
||||
'woocommerce_process_shop_order_meta',
|
||||
function( int $order_id ) use ( $c ) {
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_ywot_tracking', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$tracking_number = wc_clean( wp_unslash( $_POST['ywot_tracking_code'] ?? '' ) );
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$carrier = wc_clean( wp_unslash( $_POST['ywot_carrier_name'] ?? '' ) );
|
||||
|
||||
if ( ! $tracking_number || ! is_string( $tracking_number ) || ! $carrier || ! is_string( $carrier ) || ! $transaction_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->create_tracking( $c, $order_id, $transaction_id, $tracking_number, $carrier, array() );
|
||||
},
|
||||
500,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates PayPal tracking.
|
||||
*
|
||||
* @param ContainerInterface $c The Container.
|
||||
* @param int $wc_order_id The WC order ID.
|
||||
* @param string $transaction_id The transaction ID.
|
||||
* @param string $tracking_number The tracking number.
|
||||
* @param string $carrier The shipment carrier.
|
||||
* @param int[] $line_items The list of shipment line item IDs.
|
||||
* @return void
|
||||
*/
|
||||
protected function create_tracking(
|
||||
ContainerInterface $c,
|
||||
int $wc_order_id,
|
||||
string $transaction_id,
|
||||
string $tracking_number,
|
||||
string $carrier,
|
||||
array $line_items
|
||||
) {
|
||||
$endpoint = $c->get( 'order-tracking.endpoint.controller' );
|
||||
assert( $endpoint instanceof OrderTrackingEndpoint );
|
||||
|
||||
$logger = $c->get( 'woocommerce.logger.woocommerce' );
|
||||
assert( $logger instanceof LoggerInterface );
|
||||
|
||||
$shipment_factory = $c->get( 'order-tracking.shipment.factory' );
|
||||
assert( $shipment_factory instanceof ShipmentFactoryInterface );
|
||||
|
||||
try {
|
||||
$ppcp_shipment = $shipment_factory->create_shipment(
|
||||
$wc_order_id,
|
||||
$transaction_id,
|
||||
$tracking_number,
|
||||
'SHIPPED',
|
||||
'OTHER',
|
||||
$carrier,
|
||||
$line_items
|
||||
);
|
||||
|
||||
$tracking_information = $endpoint->get_tracking_information( $wc_order_id, $tracking_number );
|
||||
|
||||
$tracking_information
|
||||
? $endpoint->update_tracking_information( $ppcp_shipment, $wc_order_id )
|
||||
: $endpoint->add_tracking_information( $ppcp_shipment, $wc_order_id );
|
||||
|
||||
} catch ( Exception $exception ) {
|
||||
$logger->error( "Couldn't sync tracking information: " . $exception->getMessage() );
|
||||
foreach ( $order_tracking_integrations as $integration ) {
|
||||
assert( $integration instanceof Integration );
|
||||
$integration->integrate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
modules/ppcp-compat/src/Integration.php
Normal file
18
modules/ppcp-compat/src/Integration.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* Interface for all integration controllers.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Compat
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Compat;
|
||||
|
||||
interface Integration {
|
||||
|
||||
/**
|
||||
* Integrates some (possibly external) service with PayPal Payments.
|
||||
*/
|
||||
public function integrate(): void;
|
||||
}
|
|
@ -50,103 +50,111 @@ class GooglepayModule implements ModuleInterface {
|
|||
}
|
||||
);
|
||||
|
||||
// Check if the module is applicable, correct country, currency, ... etc.
|
||||
if ( ! $c->get( 'googlepay.eligible' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the button handler.
|
||||
$button = $c->get( 'googlepay.button' );
|
||||
assert( $button instanceof ButtonInterface );
|
||||
$button->initialize();
|
||||
|
||||
// Show notice if there are product availability issues.
|
||||
$availability_notice = $c->get( 'googlepay.availability_notice' );
|
||||
assert( $availability_notice instanceof AvailabilityNotice );
|
||||
$availability_notice->execute();
|
||||
|
||||
// Check if this merchant can activate / use the buttons.
|
||||
// We allow non referral merchants as they can potentially still use GooglePay, we just have no way of checking the capability.
|
||||
if ( ( ! $c->get( 'googlepay.available' ) ) && $c->get( 'googlepay.is_referral' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initializes button rendering.
|
||||
add_action(
|
||||
'wp',
|
||||
static function () use ( $c, $button ) {
|
||||
if ( is_admin() ) {
|
||||
return;
|
||||
}
|
||||
$button->render();
|
||||
}
|
||||
);
|
||||
|
||||
// Enqueue frontend scripts.
|
||||
add_action(
|
||||
'wp_enqueue_scripts',
|
||||
static function () use ( $c, $button ) {
|
||||
$smart_button = $c->get( 'button.smart-button' );
|
||||
assert( $smart_button instanceof SmartButtonInterface );
|
||||
if ( $smart_button->should_load_ppcp_script() ) {
|
||||
$button->enqueue();
|
||||
}
|
||||
|
||||
if ( has_block( 'woocommerce/checkout' ) || has_block( 'woocommerce/cart' ) ) {
|
||||
/**
|
||||
* Should add this to the ButtonInterface.
|
||||
*
|
||||
* @psalm-suppress UndefinedInterfaceMethod
|
||||
*/
|
||||
$button->enqueue_styles();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Enqueue backend scripts.
|
||||
add_action(
|
||||
'admin_enqueue_scripts',
|
||||
static function () use ( $c, $button ) {
|
||||
if ( ! is_admin() ) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Should add this to the ButtonInterface.
|
||||
*
|
||||
* @psalm-suppress UndefinedInterfaceMethod
|
||||
*/
|
||||
$button->enqueue_admin();
|
||||
}
|
||||
);
|
||||
|
||||
// Registers buttons on blocks pages.
|
||||
add_action(
|
||||
'woocommerce_blocks_payment_method_type_registration',
|
||||
function( PaymentMethodRegistry $payment_method_registry ) use ( $c, $button ): void {
|
||||
if ( $button->is_enabled() ) {
|
||||
$payment_method_registry->register( $c->get( 'googlepay.blocks-payment-method' ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Adds GooglePay component to the backend button preview settings.
|
||||
add_action(
|
||||
'woocommerce_paypal_payments_admin_gateway_settings',
|
||||
function( array $settings ) use ( $c, $button ): array {
|
||||
if ( is_array( $settings['components'] ) ) {
|
||||
$settings['components'][] = 'googlepay';
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
);
|
||||
|
||||
// Initialize AJAX endpoints.
|
||||
add_action(
|
||||
'wc_ajax_' . UpdatePaymentDataEndpoint::ENDPOINT,
|
||||
'init',
|
||||
static function () use ( $c ) {
|
||||
$endpoint = $c->get( 'googlepay.endpoint.update-payment-data' );
|
||||
assert( $endpoint instanceof UpdatePaymentDataEndpoint );
|
||||
$endpoint->handle_request();
|
||||
|
||||
// Check if the module is applicable, correct country, currency, ... etc.
|
||||
if ( ! $c->get( 'googlepay.eligible' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the button handler.
|
||||
$button = $c->get( 'googlepay.button' );
|
||||
assert( $button instanceof ButtonInterface );
|
||||
$button->initialize();
|
||||
|
||||
// Show notice if there are product availability issues.
|
||||
$availability_notice = $c->get( 'googlepay.availability_notice' );
|
||||
assert( $availability_notice instanceof AvailabilityNotice );
|
||||
$availability_notice->execute();
|
||||
|
||||
// Check if this merchant can activate / use the buttons.
|
||||
// We allow non referral merchants as they can potentially still use GooglePay, we just have no way of checking the capability.
|
||||
if ( ( ! $c->get( 'googlepay.available' ) ) && $c->get( 'googlepay.is_referral' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initializes button rendering.
|
||||
add_action(
|
||||
'wp',
|
||||
static function () use ( $c, $button ) {
|
||||
if ( is_admin() ) {
|
||||
return;
|
||||
}
|
||||
$button->render();
|
||||
}
|
||||
);
|
||||
|
||||
// Enqueue frontend scripts.
|
||||
add_action(
|
||||
'wp_enqueue_scripts',
|
||||
static function () use ( $c, $button ) {
|
||||
$smart_button = $c->get( 'button.smart-button' );
|
||||
assert( $smart_button instanceof SmartButtonInterface );
|
||||
if ( $smart_button->should_load_ppcp_script() ) {
|
||||
$button->enqueue();
|
||||
}
|
||||
|
||||
if ( has_block( 'woocommerce/checkout' ) || has_block( 'woocommerce/cart' ) ) {
|
||||
/**
|
||||
* Should add this to the ButtonInterface.
|
||||
*
|
||||
* @psalm-suppress UndefinedInterfaceMethod
|
||||
*/
|
||||
$button->enqueue_styles();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Enqueue backend scripts.
|
||||
add_action(
|
||||
'admin_enqueue_scripts',
|
||||
static function () use ( $c, $button ) {
|
||||
if ( ! is_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should add this to the ButtonInterface.
|
||||
*
|
||||
* @psalm-suppress UndefinedInterfaceMethod
|
||||
*/
|
||||
$button->enqueue_admin();
|
||||
}
|
||||
);
|
||||
|
||||
// Registers buttons on blocks pages.
|
||||
add_action(
|
||||
'woocommerce_blocks_payment_method_type_registration',
|
||||
function( PaymentMethodRegistry $payment_method_registry ) use ( $c, $button ): void {
|
||||
if ( $button->is_enabled() ) {
|
||||
$payment_method_registry->register( $c->get( 'googlepay.blocks-payment-method' ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Adds GooglePay component to the backend button preview settings.
|
||||
add_action(
|
||||
'woocommerce_paypal_payments_admin_gateway_settings',
|
||||
function( array $settings ) use ( $c ): array {
|
||||
if ( is_array( $settings['components'] ) ) {
|
||||
$settings['components'][] = 'googlepay';
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
);
|
||||
|
||||
// Initialize AJAX endpoints.
|
||||
add_action(
|
||||
'wc_ajax_' . UpdatePaymentDataEndpoint::ENDPOINT,
|
||||
static function () use ( $c ) {
|
||||
$endpoint = $c->get( 'googlepay.endpoint.update-payment-data' );
|
||||
assert( $endpoint instanceof UpdatePaymentDataEndpoint );
|
||||
$endpoint->handle_request();
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
h4 {
|
||||
display: inline-block;
|
||||
margin: 10px 0px;
|
||||
max-width: 83%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
button {
|
||||
|
|
|
@ -9,15 +9,16 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\OrderTracking;
|
||||
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Integration\GermanizedShipmentIntegration;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Integration\ShipmentTrackingIntegration;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Integration\ShipStationIntegration;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Integration\WcShippingTaxIntegration;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Integration\YithShipmentIntegration;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Shipment\ShipmentFactoryInterface;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Shipment\ShipmentFactory;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Assets\OrderEditPageAssets;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Endpoint\OrderTrackingEndpoint;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
||||
return array(
|
||||
'order-tracking.assets' => function( ContainerInterface $container ) : OrderEditPageAssets {
|
||||
|
@ -92,4 +93,39 @@ return array(
|
|||
'order-tracking.is-merchant-country-us' => static function ( ContainerInterface $container ): bool {
|
||||
return $container->get( 'api.shop.country' ) === 'US';
|
||||
},
|
||||
'order-tracking.integrations' => static function ( ContainerInterface $container ): array {
|
||||
$shipment_factory = $container->get( 'order-tracking.shipment.factory' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
$endpoint = $container->get( 'order-tracking.endpoint.controller' );
|
||||
|
||||
$is_gzd_active = $container->get( 'compat.gzd.is_supported_plugin_version_active' );
|
||||
$is_wc_shipment_active = $container->get( 'compat.wc_shipment_tracking.is_supported_plugin_version_active' );
|
||||
$is_yith_ywot_active = $container->get( 'compat.ywot.is_supported_plugin_version_active' );
|
||||
$is_ship_station_active = $container->get( 'compat.shipstation.is_supported_plugin_version_active' );
|
||||
$is_wc_shipping_tax_active = $container->get( 'compat.wc_shipping_tax.is_supported_plugin_version_active' );
|
||||
|
||||
$integrations = array();
|
||||
|
||||
if ( $is_gzd_active ) {
|
||||
$integrations[] = new GermanizedShipmentIntegration( $shipment_factory, $logger, $endpoint );
|
||||
}
|
||||
|
||||
if ( $is_wc_shipment_active ) {
|
||||
$integrations[] = new ShipmentTrackingIntegration( $shipment_factory, $logger, $endpoint );
|
||||
}
|
||||
|
||||
if ( $is_yith_ywot_active ) {
|
||||
$integrations[] = new YithShipmentIntegration( $shipment_factory, $logger, $endpoint );
|
||||
}
|
||||
|
||||
if ( $is_ship_station_active ) {
|
||||
$integrations[] = new ShipStationIntegration( $shipment_factory, $logger, $endpoint );
|
||||
}
|
||||
|
||||
if ( $is_wc_shipping_tax_active ) {
|
||||
$integrations[] = new WcShippingTaxIntegration( $shipment_factory, $logger, $endpoint );
|
||||
}
|
||||
|
||||
return $integrations;
|
||||
},
|
||||
);
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
/**
|
||||
* The Shipment integration for Germanized plugin.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\OrderTracking\Shipment
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\OrderTracking\Integration;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Compat\Integration;
|
||||
use Vendidero\Germanized\Shipments\Shipment;
|
||||
use Vendidero\Germanized\Shipments\ShipmentItem;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Endpoint\OrderTrackingEndpoint;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Shipment\ShipmentFactoryInterface;
|
||||
|
||||
/**
|
||||
* Class GermanizedShipmentIntegration.
|
||||
*/
|
||||
class GermanizedShipmentIntegration implements Integration {
|
||||
|
||||
/**
|
||||
* The shipment factory.
|
||||
*
|
||||
* @var ShipmentFactoryInterface
|
||||
*/
|
||||
protected $shipment_factory;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* The order tracking endpoint.
|
||||
*
|
||||
* @var OrderTrackingEndpoint
|
||||
*/
|
||||
protected $endpoint;
|
||||
|
||||
/**
|
||||
* The Germanized Shipment Integration constructor.
|
||||
*
|
||||
* @param ShipmentFactoryInterface $shipment_factory The shipment factory.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param OrderTrackingEndpoint $endpoint The order tracking endpoint.
|
||||
*/
|
||||
public function __construct(
|
||||
ShipmentFactoryInterface $shipment_factory,
|
||||
LoggerInterface $logger,
|
||||
OrderTrackingEndpoint $endpoint
|
||||
) {
|
||||
$this->shipment_factory = $shipment_factory;
|
||||
$this->logger = $logger;
|
||||
$this->endpoint = $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function integrate(): void {
|
||||
|
||||
add_action(
|
||||
'woocommerce_gzd_shipment_status_shipped',
|
||||
function( int $shipment_id, Shipment $shipment ) {
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_gzd_tracking', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wc_order = $shipment->get_order();
|
||||
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wc_order_id = $wc_order->get_id();
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
$tracking_number = $shipment->get_tracking_id();
|
||||
$carrier = $shipment->get_shipping_provider();
|
||||
|
||||
$items = array_map(
|
||||
function ( ShipmentItem $item ): int {
|
||||
return $item->get_order_item_id();
|
||||
},
|
||||
$shipment->get_items()
|
||||
);
|
||||
|
||||
if ( ! $tracking_number || ! $carrier || ! $transaction_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$ppcp_shipment = $this->shipment_factory->create_shipment(
|
||||
$wc_order_id,
|
||||
$transaction_id,
|
||||
$tracking_number,
|
||||
'SHIPPED',
|
||||
'OTHER',
|
||||
$carrier,
|
||||
$items
|
||||
);
|
||||
|
||||
$tracking_information = $this->endpoint->get_tracking_information( $wc_order_id, $tracking_number );
|
||||
|
||||
$tracking_information
|
||||
? $this->endpoint->update_tracking_information( $ppcp_shipment, $wc_order_id )
|
||||
: $this->endpoint->add_tracking_information( $ppcp_shipment, $wc_order_id );
|
||||
|
||||
} catch ( Exception $exception ) {
|
||||
$this->logger->error( "Couldn't sync tracking information: " . $exception->getMessage() );
|
||||
}
|
||||
},
|
||||
500,
|
||||
2
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
/**
|
||||
* The Shipment integration for ShipStation plugin.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\OrderTracking\Shipment
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\OrderTracking\Integration;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Compat\Integration;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Endpoint\OrderTrackingEndpoint;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Shipment\ShipmentFactoryInterface;
|
||||
|
||||
/**
|
||||
* Class ShipStationIntegration.
|
||||
*/
|
||||
class ShipStationIntegration implements Integration {
|
||||
|
||||
/**
|
||||
* The shipment factory.
|
||||
*
|
||||
* @var ShipmentFactoryInterface
|
||||
*/
|
||||
protected $shipment_factory;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* The order tracking endpoint.
|
||||
*
|
||||
* @var OrderTrackingEndpoint
|
||||
*/
|
||||
protected $endpoint;
|
||||
|
||||
/**
|
||||
* The ShipStationIntegration constructor.
|
||||
*
|
||||
* @param ShipmentFactoryInterface $shipment_factory The shipment factory.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param OrderTrackingEndpoint $endpoint The order tracking endpoint.
|
||||
*/
|
||||
public function __construct(
|
||||
ShipmentFactoryInterface $shipment_factory,
|
||||
LoggerInterface $logger,
|
||||
OrderTrackingEndpoint $endpoint
|
||||
) {
|
||||
$this->shipment_factory = $shipment_factory;
|
||||
$this->logger = $logger;
|
||||
$this->endpoint = $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function integrate(): void {
|
||||
|
||||
add_action(
|
||||
'woocommerce_shipstation_shipnotify',
|
||||
/**
|
||||
* Param type for $wc_order can be different.
|
||||
*
|
||||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
function( $wc_order, array $data ) {
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_ship_station_tracking', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$order_id = $wc_order->get_id();
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
$tracking_number = $data['tracking_number'] ?? '';
|
||||
$carrier = $data['carrier'] ?? '';
|
||||
|
||||
if ( ! $tracking_number || ! is_string( $tracking_number ) || ! $carrier || ! is_string( $carrier ) || ! $transaction_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$ppcp_shipment = $this->shipment_factory->create_shipment(
|
||||
$order_id,
|
||||
$transaction_id,
|
||||
$tracking_number,
|
||||
'SHIPPED',
|
||||
'OTHER',
|
||||
$carrier,
|
||||
array()
|
||||
);
|
||||
|
||||
$tracking_information = $this->endpoint->get_tracking_information( $order_id, $tracking_number );
|
||||
|
||||
$tracking_information
|
||||
? $this->endpoint->update_tracking_information( $ppcp_shipment, $order_id )
|
||||
: $this->endpoint->add_tracking_information( $ppcp_shipment, $order_id );
|
||||
|
||||
} catch ( Exception $exception ) {
|
||||
$this->logger->error( "Couldn't sync tracking information: " . $exception->getMessage() );
|
||||
}
|
||||
},
|
||||
500,
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
/**
|
||||
* The Shipment integration for Shipment Tracking plugin.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\OrderTracking\Shipment
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\OrderTracking\Integration;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Compat\Integration;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Endpoint\OrderTrackingEndpoint;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Shipment\ShipmentFactoryInterface;
|
||||
use WP_REST_Request;
|
||||
use WP_REST_Response;
|
||||
|
||||
/**
|
||||
* Class ShipmentTrackingIntegration.
|
||||
*/
|
||||
class ShipmentTrackingIntegration implements Integration {
|
||||
|
||||
/**
|
||||
* The shipment factory.
|
||||
*
|
||||
* @var ShipmentFactoryInterface
|
||||
*/
|
||||
protected $shipment_factory;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* The order tracking endpoint.
|
||||
*
|
||||
* @var OrderTrackingEndpoint
|
||||
*/
|
||||
protected $endpoint;
|
||||
|
||||
/**
|
||||
* The Shipment Tracking Integration constructor.
|
||||
*
|
||||
* @param ShipmentFactoryInterface $shipment_factory The shipment factory.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param OrderTrackingEndpoint $endpoint The order tracking endpoint.
|
||||
*/
|
||||
public function __construct(
|
||||
ShipmentFactoryInterface $shipment_factory,
|
||||
LoggerInterface $logger,
|
||||
OrderTrackingEndpoint $endpoint
|
||||
) {
|
||||
$this->shipment_factory = $shipment_factory;
|
||||
$this->logger = $logger;
|
||||
$this->endpoint = $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function integrate(): void {
|
||||
|
||||
add_action(
|
||||
'wp_ajax_wc_shipment_tracking_save_form',
|
||||
function() {
|
||||
check_ajax_referer( 'create-tracking-item', 'security', true );
|
||||
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_wc_shipment_tracking', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$order_id = (int) wc_clean( wp_unslash( $_POST['order_id'] ?? '' ) );
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
$tracking_number = wc_clean( wp_unslash( $_POST['tracking_number'] ?? '' ) );
|
||||
$carrier = wc_clean( wp_unslash( $_POST['tracking_provider'] ?? '' ) );
|
||||
$carrier_other = wc_clean( wp_unslash( $_POST['custom_tracking_provider'] ?? '' ) );
|
||||
$carrier = $carrier ?: $carrier_other ?: '';
|
||||
|
||||
if ( ! $tracking_number || ! is_string( $tracking_number ) || ! $carrier || ! is_string( $carrier ) || ! $transaction_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->sync_tracking( $order_id, $transaction_id, $tracking_number, $carrier );
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Support the case when tracking is added via REST.
|
||||
*/
|
||||
add_filter(
|
||||
'woocommerce_rest_prepare_order_shipment_tracking',
|
||||
function( WP_REST_Response $response, array $tracking_item, WP_REST_Request $request ): WP_REST_Response {
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_wc_shipment_tracking', true ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$callback = $request->get_attributes()['callback']['1'] ?? '';
|
||||
if ( $callback !== 'create_item' ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$order_id = $tracking_item['order_id'] ?? 0;
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
$tracking_number = $tracking_item['tracking_number'] ?? '';
|
||||
$carrier = $tracking_item['tracking_provider'] ?? '';
|
||||
$carrier_other = $tracking_item['custom_tracking_provider'] ?? '';
|
||||
$carrier = $carrier ?: $carrier_other ?: '';
|
||||
|
||||
if ( ! $tracking_number || ! $carrier || ! $transaction_id ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$this->sync_tracking( $order_id, $transaction_id, $tracking_number, $carrier );
|
||||
|
||||
return $response;
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs (add | update) the PayPal tracking with given info.
|
||||
*
|
||||
* @param int $wc_order_id The WC order ID.
|
||||
* @param string $transaction_id The transaction ID.
|
||||
* @param string $tracking_number The tracking number.
|
||||
* @param string $carrier The shipment carrier.
|
||||
* @return void
|
||||
*/
|
||||
protected function sync_tracking(
|
||||
int $wc_order_id,
|
||||
string $transaction_id,
|
||||
string $tracking_number,
|
||||
string $carrier
|
||||
) {
|
||||
try {
|
||||
$ppcp_shipment = $this->shipment_factory->create_shipment(
|
||||
$wc_order_id,
|
||||
$transaction_id,
|
||||
$tracking_number,
|
||||
'SHIPPED',
|
||||
'OTHER',
|
||||
$carrier,
|
||||
array()
|
||||
);
|
||||
|
||||
$tracking_information = $this->endpoint->get_tracking_information( $wc_order_id, $tracking_number );
|
||||
|
||||
$tracking_information
|
||||
? $this->endpoint->update_tracking_information( $ppcp_shipment, $wc_order_id )
|
||||
: $this->endpoint->add_tracking_information( $ppcp_shipment, $wc_order_id );
|
||||
|
||||
} catch ( Exception $exception ) {
|
||||
$this->logger->error( "Couldn't sync tracking information: " . $exception->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
/**
|
||||
* The Shipment integration for WooCommerce Shipping & Tax plugin.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\OrderTracking\Shipment
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\OrderTracking\Integration;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Compat\Integration;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Endpoint\OrderTrackingEndpoint;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Shipment\ShipmentFactoryInterface;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\TrackingAvailabilityTrait;
|
||||
use WP_HTTP_Response;
|
||||
use WP_REST_Request;
|
||||
use WP_REST_Server;
|
||||
|
||||
/**
|
||||
* Class WcShippingTaxIntegration.
|
||||
*/
|
||||
class WcShippingTaxIntegration implements Integration {
|
||||
|
||||
use TrackingAvailabilityTrait;
|
||||
|
||||
/**
|
||||
* The shipment factory.
|
||||
*
|
||||
* @var ShipmentFactoryInterface
|
||||
*/
|
||||
protected $shipment_factory;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* The order tracking endpoint.
|
||||
*
|
||||
* @var OrderTrackingEndpoint
|
||||
*/
|
||||
protected $endpoint;
|
||||
|
||||
/**
|
||||
* The WcShippingTaxIntegration constructor.
|
||||
*
|
||||
* @param ShipmentFactoryInterface $shipment_factory The shipment factory.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param OrderTrackingEndpoint $endpoint The order tracking endpoint.
|
||||
*/
|
||||
public function __construct(
|
||||
ShipmentFactoryInterface $shipment_factory,
|
||||
LoggerInterface $logger,
|
||||
OrderTrackingEndpoint $endpoint
|
||||
) {
|
||||
$this->shipment_factory = $shipment_factory;
|
||||
$this->logger = $logger;
|
||||
$this->endpoint = $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function integrate(): void {
|
||||
|
||||
add_filter(
|
||||
'rest_post_dispatch',
|
||||
function( WP_HTTP_Response $response, WP_REST_Server $server, WP_REST_Request $request ): WP_HTTP_Response {
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_wc_shipping_tax', true ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$params = $request->get_params();
|
||||
$order_id = (int) ( $params['order_id'] ?? 0 );
|
||||
$label_id = (int) ( $params['label_ids'] ?? 0 );
|
||||
|
||||
if ( ! $order_id || "/wc/v1/connect/label/{$order_id}/{$label_id}" !== $request->get_route() ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$data = $response->get_data() ?? array();
|
||||
$labels = $data['labels'] ?? array();
|
||||
|
||||
foreach ( $labels as $label ) {
|
||||
$tracking_number = $label['tracking'] ?? '';
|
||||
if ( ! $tracking_number ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
$carrier = $label['carrier_id'] ?? $label['service_name'] ?? '';
|
||||
$items = array_map( 'intval', $label['product_ids'] ?? array() );
|
||||
|
||||
if ( ! $carrier || ! $transaction_id ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->sync_tracking( $order_id, $transaction_id, $tracking_number, $carrier, $items );
|
||||
}
|
||||
|
||||
return $response;
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs (add | update) the PayPal tracking with given info.
|
||||
*
|
||||
* @param int $wc_order_id The WC order ID.
|
||||
* @param string $transaction_id The transaction ID.
|
||||
* @param string $tracking_number The tracking number.
|
||||
* @param string $carrier The shipment carrier.
|
||||
* @param int[] $items The list of line items IDs.
|
||||
* @return void
|
||||
*/
|
||||
protected function sync_tracking(
|
||||
int $wc_order_id,
|
||||
string $transaction_id,
|
||||
string $tracking_number,
|
||||
string $carrier,
|
||||
array $items
|
||||
) {
|
||||
try {
|
||||
$ppcp_shipment = $this->shipment_factory->create_shipment(
|
||||
$wc_order_id,
|
||||
$transaction_id,
|
||||
$tracking_number,
|
||||
'SHIPPED',
|
||||
'OTHER',
|
||||
$carrier,
|
||||
$items
|
||||
);
|
||||
|
||||
$tracking_information = $this->endpoint->get_tracking_information( $wc_order_id, $tracking_number );
|
||||
|
||||
$tracking_information
|
||||
? $this->endpoint->update_tracking_information( $ppcp_shipment, $wc_order_id )
|
||||
: $this->endpoint->add_tracking_information( $ppcp_shipment, $wc_order_id );
|
||||
|
||||
} catch ( Exception $exception ) {
|
||||
$this->logger->error( "Couldn't sync tracking information: " . $exception->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
/**
|
||||
* The Shipment integration for YITH WooCommerce Order & Shipment Tracking plugin.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\OrderTracking\Shipment
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\OrderTracking\Integration;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Compat\Integration;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Endpoint\OrderTrackingEndpoint;
|
||||
use WooCommerce\PayPalCommerce\OrderTracking\Shipment\ShipmentFactoryInterface;
|
||||
|
||||
/**
|
||||
* Class YithShipmentIntegration.
|
||||
*/
|
||||
class YithShipmentIntegration implements Integration {
|
||||
|
||||
/**
|
||||
* The shipment factory.
|
||||
*
|
||||
* @var ShipmentFactoryInterface
|
||||
*/
|
||||
protected $shipment_factory;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* The order tracking endpoint.
|
||||
*
|
||||
* @var OrderTrackingEndpoint
|
||||
*/
|
||||
protected $endpoint;
|
||||
|
||||
/**
|
||||
* The YithShipmentIntegration constructor.
|
||||
*
|
||||
* @param ShipmentFactoryInterface $shipment_factory The shipment factory.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param OrderTrackingEndpoint $endpoint The order tracking endpoint.
|
||||
*/
|
||||
public function __construct(
|
||||
ShipmentFactoryInterface $shipment_factory,
|
||||
LoggerInterface $logger,
|
||||
OrderTrackingEndpoint $endpoint
|
||||
) {
|
||||
$this->shipment_factory = $shipment_factory;
|
||||
$this->logger = $logger;
|
||||
$this->endpoint = $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function integrate(): void {
|
||||
|
||||
add_action(
|
||||
'woocommerce_process_shop_order_meta',
|
||||
function( int $order_id ) {
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_sync_ywot_tracking', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transaction_id = $wc_order->get_transaction_id();
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$tracking_number = wc_clean( wp_unslash( $_POST['ywot_tracking_code'] ?? '' ) );
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$carrier = wc_clean( wp_unslash( $_POST['ywot_carrier_name'] ?? '' ) );
|
||||
|
||||
if ( ! $tracking_number || ! is_string( $tracking_number ) || ! $carrier || ! is_string( $carrier ) || ! $transaction_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$ppcp_shipment = $this->shipment_factory->create_shipment(
|
||||
$order_id,
|
||||
$transaction_id,
|
||||
$tracking_number,
|
||||
'SHIPPED',
|
||||
'OTHER',
|
||||
$carrier,
|
||||
array()
|
||||
);
|
||||
|
||||
$tracking_information = $this->endpoint->get_tracking_information( $order_id, $tracking_number );
|
||||
|
||||
$tracking_information
|
||||
? $this->endpoint->update_tracking_information( $ppcp_shipment, $order_id )
|
||||
: $this->endpoint->add_tracking_information( $ppcp_shipment, $order_id );
|
||||
|
||||
} catch ( Exception $exception ) {
|
||||
$this->logger->error( "Couldn't sync tracking information: " . $exception->getMessage() );
|
||||
}
|
||||
},
|
||||
500,
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
|
@ -102,7 +102,7 @@ class OrderTrackingModule implements ModuleInterface {
|
|||
__( 'PayPal Package Tracking', 'woocommerce-paypal-payments' ),
|
||||
array( $meta_box_renderer, 'render' ),
|
||||
$screen,
|
||||
'normal'
|
||||
'side'
|
||||
);
|
||||
},
|
||||
10,
|
||||
|
|
|
@ -171,13 +171,17 @@ class CardButtonGateway extends \WC_Payment_Gateway {
|
|||
$this->payment_token_repository = $payment_token_repository;
|
||||
$this->logger = $logger;
|
||||
|
||||
if ( $this->onboarded ) {
|
||||
$this->supports = array( 'refunds' );
|
||||
}
|
||||
if ( $this->gateways_enabled() ) {
|
||||
$this->supports = array(
|
||||
'refunds',
|
||||
'products',
|
||||
$this->supports = array(
|
||||
'refunds',
|
||||
'products',
|
||||
);
|
||||
|
||||
if (
|
||||
( $this->config->has( 'vault_enabled' ) && $this->config->get( 'vault_enabled' ) )
|
||||
|| ( $this->config->has( 'subscriptions_mode' ) && $this->config->get( 'subscriptions_mode' ) === 'subscriptions_api' )
|
||||
) {
|
||||
array_push(
|
||||
$this->supports,
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
'subscription_suspension',
|
||||
|
@ -187,7 +191,7 @@ class CardButtonGateway extends \WC_Payment_Gateway {
|
|||
'subscription_payment_method_change',
|
||||
'subscription_payment_method_change_customer',
|
||||
'subscription_payment_method_change_admin',
|
||||
'multiple_subscriptions',
|
||||
'multiple_subscriptions'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,21 +18,6 @@ use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException;
|
|||
* Trait ProcessPaymentTrait
|
||||
*/
|
||||
trait ProcessPaymentTrait {
|
||||
/**
|
||||
* Checks if PayPal or Credit Card gateways are enabled.
|
||||
*
|
||||
* @return bool Whether any of the gateways is enabled.
|
||||
*/
|
||||
protected function gateways_enabled(): bool {
|
||||
if ( $this->config->has( 'enabled' ) && $this->config->get( 'enabled' ) ) {
|
||||
return true;
|
||||
}
|
||||
if ( $this->config->has( 'dcc_enabled' ) && $this->config->get( 'dcc_enabled' ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the payment failure.
|
||||
*
|
||||
|
|
|
@ -180,7 +180,7 @@ If you encounter issues with the PayPal buttons not appearing after an update, p
|
|||
|
||||
== Changelog ==
|
||||
|
||||
= 2.4.0 - xxxx-xx-xx =
|
||||
= 2.4.0 - 2023-10-31 =
|
||||
* Fix - Mini-Cart Bug cause of wrong DOM-Structure in v2.3.1 #1735
|
||||
* Fix - ACDC disappearing after plugin updates #1751
|
||||
* Fix - Subscription module hooks #1748
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
|
|||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper;
|
||||
use WooCommerce\PayPalCommerce\TestCase;
|
||||
use Mockery;
|
||||
use WooCommerce\WooCommerce\Logging\Logger\NullLogger;
|
||||
|
@ -91,12 +92,16 @@ class ChangeCartEndpointTest extends TestCase
|
|||
->expects('from_wc_cart')
|
||||
->andReturn($pu);
|
||||
|
||||
$productsHelper = new CartProductsHelper(
|
||||
$dataStore
|
||||
);
|
||||
|
||||
$testee = new ChangeCartEndpoint(
|
||||
$cart,
|
||||
$shipping,
|
||||
$requestData,
|
||||
$purchase_unit_factory,
|
||||
$dataStore,
|
||||
$productsHelper,
|
||||
new NullLogger()
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue