mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-05 08:59:14 +08:00
Merge branch 'trunk' into PCP-1393-update-to-vault-v-3
This commit is contained in:
commit
9f41d5c874
29 changed files with 755 additions and 492 deletions
|
@ -14,6 +14,14 @@
|
|||
* Enhancement - Cart simulation improvements #1753
|
||||
* Enhancement - Billing schedule fields not greyed out when PayPal Subscriptions product is connected #1755
|
||||
* Enhancement - Check validation errors when submitting in block #1528
|
||||
* Enhancement - Improve handling of server error when submitting block #1785
|
||||
* Enhancement - Extend Apple Pay country eligibility #1781
|
||||
* Enhancement - Apple Pay validation notice improvements #1783
|
||||
* Enhancement - Apple Pay payment process issues #1789
|
||||
* Enhancement - Disable the tracking if payment is not captured #1780
|
||||
* Enhancement - Place order button remains - Could not retrieve order #1786
|
||||
* Enhancement - Google Pay for variable product greyed out but clickable #1788
|
||||
* Enhancement - Merchant credential validation & remove PAYEE object #1795
|
||||
|
||||
= 2.3.1 - 2023-09-26 =
|
||||
* Fix - Fatal error when saving product while WooCommerce Subscriptions plugin is not active #1731
|
||||
|
|
|
@ -308,8 +308,6 @@ return array(
|
|||
'api.factory.purchase-unit' => static function ( ContainerInterface $container ): PurchaseUnitFactory {
|
||||
|
||||
$amount_factory = $container->get( 'api.factory.amount' );
|
||||
$payee_repository = $container->get( 'api.repository.payee' );
|
||||
$payee_factory = $container->get( 'api.factory.payee' );
|
||||
$item_factory = $container->get( 'api.factory.item' );
|
||||
$shipping_factory = $container->get( 'api.factory.shipping' );
|
||||
$payments_factory = $container->get( 'api.factory.payments' );
|
||||
|
@ -319,8 +317,6 @@ return array(
|
|||
|
||||
return new PurchaseUnitFactory(
|
||||
$amount_factory,
|
||||
$payee_repository,
|
||||
$payee_factory,
|
||||
$item_factory,
|
||||
$shipping_factory,
|
||||
$payments_factory,
|
||||
|
|
|
@ -51,13 +51,6 @@ class PurchaseUnit {
|
|||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* The Payee.
|
||||
*
|
||||
* @var Payee|null
|
||||
*/
|
||||
private $payee;
|
||||
|
||||
/**
|
||||
* The custom id.
|
||||
*
|
||||
|
@ -108,7 +101,6 @@ class PurchaseUnit {
|
|||
* @param Shipping|null $shipping The Shipping.
|
||||
* @param string $reference_id The reference ID.
|
||||
* @param string $description The description.
|
||||
* @param Payee|null $payee The Payee.
|
||||
* @param string $custom_id The custom ID.
|
||||
* @param string $invoice_id The invoice ID.
|
||||
* @param string $soft_descriptor The soft descriptor.
|
||||
|
@ -120,7 +112,6 @@ class PurchaseUnit {
|
|||
Shipping $shipping = null,
|
||||
string $reference_id = 'default',
|
||||
string $description = '',
|
||||
Payee $payee = null,
|
||||
string $custom_id = '',
|
||||
string $invoice_id = '',
|
||||
string $soft_descriptor = '',
|
||||
|
@ -150,7 +141,6 @@ class PurchaseUnit {
|
|||
}
|
||||
)
|
||||
);
|
||||
$this->payee = $payee;
|
||||
$this->custom_id = $custom_id;
|
||||
$this->invoice_id = $invoice_id;
|
||||
$this->soft_descriptor = $soft_descriptor;
|
||||
|
@ -257,15 +247,6 @@ class PurchaseUnit {
|
|||
return $this->soft_descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Payee.
|
||||
*
|
||||
* @return Payee|null
|
||||
*/
|
||||
public function payee() {
|
||||
return $this->payee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Payments.
|
||||
*
|
||||
|
@ -314,10 +295,6 @@ class PurchaseUnit {
|
|||
),
|
||||
);
|
||||
|
||||
if ( $this->payee() ) {
|
||||
$purchase_unit['payee'] = $this->payee()->to_array();
|
||||
}
|
||||
|
||||
if ( $this->payments() ) {
|
||||
$purchase_unit['payments'] = $this->payments()->to_array();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\PurchaseUnitSanitizer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\CustomIds;
|
||||
|
||||
/**
|
||||
|
@ -29,20 +28,6 @@ class PurchaseUnitFactory {
|
|||
*/
|
||||
private $amount_factory;
|
||||
|
||||
/**
|
||||
* The payee repository.
|
||||
*
|
||||
* @var PayeeRepository
|
||||
*/
|
||||
private $payee_repository;
|
||||
|
||||
/**
|
||||
* The payee factory.
|
||||
*
|
||||
* @var PayeeFactory
|
||||
*/
|
||||
private $payee_factory;
|
||||
|
||||
/**
|
||||
* The item factory.
|
||||
*
|
||||
|
@ -89,8 +74,6 @@ class PurchaseUnitFactory {
|
|||
* PurchaseUnitFactory constructor.
|
||||
*
|
||||
* @param AmountFactory $amount_factory The amount factory.
|
||||
* @param PayeeRepository $payee_repository The Payee repository.
|
||||
* @param PayeeFactory $payee_factory The Payee factory.
|
||||
* @param ItemFactory $item_factory The item factory.
|
||||
* @param ShippingFactory $shipping_factory The shipping factory.
|
||||
* @param PaymentsFactory $payments_factory The payments factory.
|
||||
|
@ -100,8 +83,6 @@ class PurchaseUnitFactory {
|
|||
*/
|
||||
public function __construct(
|
||||
AmountFactory $amount_factory,
|
||||
PayeeRepository $payee_repository,
|
||||
PayeeFactory $payee_factory,
|
||||
ItemFactory $item_factory,
|
||||
ShippingFactory $shipping_factory,
|
||||
PaymentsFactory $payments_factory,
|
||||
|
@ -111,8 +92,6 @@ class PurchaseUnitFactory {
|
|||
) {
|
||||
|
||||
$this->amount_factory = $amount_factory;
|
||||
$this->payee_repository = $payee_repository;
|
||||
$this->payee_factory = $payee_factory;
|
||||
$this->item_factory = $item_factory;
|
||||
$this->shipping_factory = $shipping_factory;
|
||||
$this->payments_factory = $payments_factory;
|
||||
|
@ -146,7 +125,6 @@ class PurchaseUnitFactory {
|
|||
}
|
||||
$reference_id = 'default';
|
||||
$description = '';
|
||||
$payee = $this->payee_repository->payee();
|
||||
$custom_id = (string) $order->get_id();
|
||||
$invoice_id = $this->prefix . $order->get_order_number();
|
||||
$soft_descriptor = $this->soft_descriptor;
|
||||
|
@ -157,7 +135,6 @@ class PurchaseUnitFactory {
|
|||
$shipping,
|
||||
$reference_id,
|
||||
$description,
|
||||
$payee,
|
||||
$custom_id,
|
||||
$invoice_id,
|
||||
$soft_descriptor
|
||||
|
@ -211,8 +188,6 @@ class PurchaseUnitFactory {
|
|||
$reference_id = 'default';
|
||||
$description = '';
|
||||
|
||||
$payee = $this->payee_repository->payee();
|
||||
|
||||
$custom_id = '';
|
||||
$session = WC()->session;
|
||||
if ( $session instanceof WC_Session_Handler ) {
|
||||
|
@ -229,7 +204,6 @@ class PurchaseUnitFactory {
|
|||
$shipping,
|
||||
$reference_id,
|
||||
$description,
|
||||
$payee,
|
||||
$custom_id,
|
||||
$invoice_id,
|
||||
$soft_descriptor
|
||||
|
@ -269,7 +243,6 @@ class PurchaseUnitFactory {
|
|||
$data->items
|
||||
);
|
||||
}
|
||||
$payee = isset( $data->payee ) ? $this->payee_factory->from_paypal_response( $data->payee ) : null;
|
||||
$shipping = null;
|
||||
try {
|
||||
if ( isset( $data->shipping ) ) {
|
||||
|
@ -293,7 +266,6 @@ class PurchaseUnitFactory {
|
|||
$shipping,
|
||||
$data->reference_id,
|
||||
$description,
|
||||
$payee,
|
||||
$custom_id,
|
||||
$invoice_id,
|
||||
$soft_descriptor,
|
||||
|
|
|
@ -24,7 +24,7 @@ return array(
|
|||
return $fields;
|
||||
}
|
||||
|
||||
$is_available = $container->get( 'applepay.enabled' );
|
||||
$is_available = $container->get( 'applepay.available' );
|
||||
$is_referral = $container->get( 'applepay.is_referral' );
|
||||
|
||||
$insert_after = function ( array $array, string $key, array $new ): array {
|
||||
|
|
|
@ -24,9 +24,7 @@ class ApplepayButton {
|
|||
);
|
||||
|
||||
//PRODUCT DETAIL PAGE
|
||||
if(this.context === 'product') {
|
||||
this.productQuantity = document.querySelector('input.qty').value
|
||||
}
|
||||
this.refreshContextData();
|
||||
|
||||
this.updated_contact_info = []
|
||||
this.selectedShippingMethod = []
|
||||
|
@ -43,6 +41,8 @@ class ApplepayButton {
|
|||
if (this.isInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.log('Init', this.context);
|
||||
this.initEventHandlers();
|
||||
this.isInitialized = true;
|
||||
this.applePayConfig = config;
|
||||
|
@ -76,6 +76,16 @@ class ApplepayButton {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
reinit() {
|
||||
if (!this.applePayConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isInitialized = false;
|
||||
this.init(this.applePayConfig);
|
||||
}
|
||||
|
||||
async fetchTransactionInfo() {
|
||||
this.transactionInfo = await this.contextHandler.transactionInfo();
|
||||
}
|
||||
|
@ -123,6 +133,7 @@ class ApplepayButton {
|
|||
}
|
||||
|
||||
applePaySession(paymentRequest) {
|
||||
this.log('applePaySession', paymentRequest);
|
||||
const session = new ApplePaySession(4, paymentRequest)
|
||||
session.begin()
|
||||
|
||||
|
@ -172,6 +183,8 @@ class ApplepayButton {
|
|||
* Show Apple Pay payment sheet when Apple Pay payment button is clicked
|
||||
*/
|
||||
async onButtonClick() {
|
||||
this.log('onButtonClick', this.context);
|
||||
|
||||
const paymentDataRequest = this.paymentDataRequest();
|
||||
// trigger woocommerce validation if we are in the checkout page
|
||||
if (this.context === 'checkout') {
|
||||
|
@ -183,7 +196,8 @@ class ApplepayButton {
|
|||
try {
|
||||
const formData = new FormData(document.querySelector(checkoutFormSelector));
|
||||
this.form_saved = Object.fromEntries(formData.entries());
|
||||
this.update_request_data_with_form(paymentDataRequest);
|
||||
// This line should be reviewed, the paypal.Applepay().confirmOrder fails if we add it.
|
||||
//this.update_request_data_with_form(paymentDataRequest);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
@ -241,17 +255,29 @@ class ApplepayButton {
|
|||
return paymentDataRequest
|
||||
}
|
||||
|
||||
refreshContextData() {
|
||||
switch (this.context) {
|
||||
case 'product':
|
||||
// Refresh product data that makes the price change.
|
||||
this.productQuantity = document.querySelector('input.qty').value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Payment process
|
||||
//------------------------
|
||||
|
||||
onvalidatemerchant(session) {
|
||||
this.log('onvalidatemerchant', this.buttonConfig.ajax_url);
|
||||
return (applePayValidateMerchantEvent) => {
|
||||
this.log('onvalidatemerchant call');
|
||||
|
||||
paypal.Applepay().validateMerchant({
|
||||
validationUrl: applePayValidateMerchantEvent.validationURL
|
||||
})
|
||||
.then(validateResult => {
|
||||
this.log('onvalidatemerchant ok');
|
||||
session.completeMerchantValidation(validateResult.merchantSession);
|
||||
//call backend to update validation to true
|
||||
jQuery.ajax({
|
||||
|
@ -265,6 +291,7 @@ class ApplepayButton {
|
|||
})
|
||||
})
|
||||
.catch(validateError => {
|
||||
this.log('onvalidatemerchant error', validateError);
|
||||
console.error(validateError);
|
||||
//call backend to update validation to false
|
||||
jQuery.ajax({
|
||||
|
@ -276,19 +303,24 @@ class ApplepayButton {
|
|||
'woocommerce-process-checkout-nonce': this.nonce,
|
||||
}
|
||||
})
|
||||
this.log('onvalidatemerchant session abort');
|
||||
session.abort();
|
||||
});
|
||||
};
|
||||
}
|
||||
onshippingmethodselected(session) {
|
||||
this.log('onshippingmethodselected', this.buttonConfig.ajax_url);
|
||||
const ajax_url = this.buttonConfig.ajax_url
|
||||
return (event) => {
|
||||
this.log('onshippingmethodselected call');
|
||||
|
||||
const data = this.getShippingMethodData(event);
|
||||
jQuery.ajax({
|
||||
url: ajax_url,
|
||||
method: 'POST',
|
||||
data: data,
|
||||
success: (applePayShippingMethodUpdate, textStatus, jqXHR) => {
|
||||
this.log('onshippingmethodselected ok');
|
||||
let response = applePayShippingMethodUpdate.data
|
||||
if (applePayShippingMethodUpdate.success === false) {
|
||||
response.errors = createAppleErrors(response.errors)
|
||||
|
@ -309,6 +341,7 @@ class ApplepayButton {
|
|||
session.completeShippingMethodSelection(response)
|
||||
},
|
||||
error: (jqXHR, textStatus, errorThrown) => {
|
||||
this.log('onshippingmethodselected error', textStatus);
|
||||
console.warn(textStatus, errorThrown)
|
||||
session.abort()
|
||||
},
|
||||
|
@ -316,14 +349,18 @@ class ApplepayButton {
|
|||
};
|
||||
}
|
||||
onshippingcontactselected(session) {
|
||||
this.log('onshippingcontactselected', this.buttonConfig.ajax_url);
|
||||
const ajax_url = this.buttonConfig.ajax_url
|
||||
return (event) => {
|
||||
this.log('onshippingcontactselected call');
|
||||
|
||||
const data = this.getShippingContactData(event);
|
||||
jQuery.ajax({
|
||||
url: ajax_url,
|
||||
method: 'POST',
|
||||
data: data,
|
||||
success: (applePayShippingContactUpdate, textStatus, jqXHR) => {
|
||||
this.log('onshippingcontactselected ok');
|
||||
let response = applePayShippingContactUpdate.data
|
||||
this.updated_contact_info = event.shippingContact
|
||||
if (applePayShippingContactUpdate.success === false) {
|
||||
|
@ -335,6 +372,7 @@ class ApplepayButton {
|
|||
session.completeShippingContactSelection(response)
|
||||
},
|
||||
error: (jqXHR, textStatus, errorThrown) => {
|
||||
this.log('onshippingcontactselected error', textStatus);
|
||||
console.warn(textStatus, errorThrown)
|
||||
session.abort()
|
||||
},
|
||||
|
@ -344,6 +382,8 @@ class ApplepayButton {
|
|||
getShippingContactData(event) {
|
||||
const product_id = this.buttonConfig.product.id;
|
||||
|
||||
this.refreshContextData();
|
||||
|
||||
switch (this.context) {
|
||||
case 'product':
|
||||
return {
|
||||
|
@ -371,6 +411,9 @@ class ApplepayButton {
|
|||
}
|
||||
getShippingMethodData(event) {
|
||||
const product_id = this.buttonConfig.product.id;
|
||||
|
||||
this.refreshContextData();
|
||||
|
||||
switch (this.context) {
|
||||
case 'product': return {
|
||||
action: 'ppcp_update_shipping_method',
|
||||
|
@ -397,7 +440,10 @@ class ApplepayButton {
|
|||
}
|
||||
|
||||
onpaymentauthorized(session) {
|
||||
this.log('onpaymentauthorized');
|
||||
return async (event) => {
|
||||
this.log('onpaymentauthorized call');
|
||||
|
||||
function form() {
|
||||
return document.querySelector('form.cart');
|
||||
}
|
||||
|
@ -420,32 +466,45 @@ class ApplepayButton {
|
|||
'_wp_http_referer': '/?wc-ajax=update_order_review',
|
||||
'paypal_order_id': data.paypal_order_id,
|
||||
};
|
||||
|
||||
this.log('onpaymentauthorized request', this.buttonConfig.ajax_url, data);
|
||||
|
||||
jQuery.ajax({
|
||||
url: this.buttonConfig.ajax_url,
|
||||
method: 'POST',
|
||||
data: request_data,
|
||||
complete: (jqXHR, textStatus) => {
|
||||
this.log('onpaymentauthorized complete');
|
||||
},
|
||||
success: (authorizationResult, textStatus, jqXHR) => {
|
||||
this.log('onpaymentauthorized ok');
|
||||
resolve(authorizationResult)
|
||||
},
|
||||
error: (jqXHR, textStatus, errorThrown) => {
|
||||
this.log('onpaymentauthorized error', textStatus);
|
||||
reject(new Error(errorThrown));
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
this.log('onpaymentauthorized catch', error);
|
||||
console.log(error) // handle error
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let id = await this.contextHandler.createOrder();
|
||||
|
||||
this.log('onpaymentauthorized paypal order ID', id, event.payment.token, event.payment.billingContact);
|
||||
|
||||
try {
|
||||
const confirmOrderResponse = await paypal.Applepay().confirmOrder({
|
||||
orderId: id,
|
||||
token: event.payment.token,
|
||||
billingContact: event.payment.billingContact,
|
||||
});
|
||||
|
||||
this.log('onpaymentauthorized confirmOrderResponse', confirmOrderResponse);
|
||||
|
||||
if (confirmOrderResponse && confirmOrderResponse.approveApplePayPayment) {
|
||||
if (confirmOrderResponse.approveApplePayPayment.status === "APPROVED") {
|
||||
try {
|
||||
|
|
|
@ -35,6 +35,12 @@ class ApplepayManager {
|
|||
})();
|
||||
}
|
||||
|
||||
reinit() {
|
||||
for (const button of this.buttons) {
|
||||
button.reinit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ApplePay configuration of the PayPal merchant.
|
||||
* @returns {Promise<null>}
|
||||
|
|
|
@ -8,11 +8,19 @@ import ApplepayManager from "./ApplepayManager";
|
|||
jQuery
|
||||
}) {
|
||||
|
||||
let manager;
|
||||
|
||||
const bootstrap = function () {
|
||||
const manager = new ApplepayManager(buttonConfig, ppcpConfig);
|
||||
manager = new ApplepayManager(buttonConfig, ppcpConfig);
|
||||
manager.init();
|
||||
};
|
||||
|
||||
jQuery(document.body).on('updated_cart_totals updated_checkout', () => {
|
||||
if (manager) {
|
||||
manager.reinit();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
() => {
|
||||
|
@ -20,7 +28,6 @@ import ApplepayManager from "./ApplepayManager";
|
|||
(typeof (buttonConfig) === 'undefined') ||
|
||||
(typeof (ppcpConfig) === 'undefined')
|
||||
) {
|
||||
console.error('PayPal button could not be configured.');
|
||||
return;
|
||||
}
|
||||
const isMiniCart = ppcpConfig.mini_cart_buttons_enabled;
|
||||
|
|
|
@ -16,11 +16,10 @@ use WooCommerce\PayPalCommerce\Applepay\Assets\AppleProductStatus;
|
|||
use WooCommerce\PayPalCommerce\Applepay\Assets\DataToAppleButtonScripts;
|
||||
use WooCommerce\PayPalCommerce\Applepay\Assets\BlocksPaymentMethod;
|
||||
use WooCommerce\PayPalCommerce\Applepay\Helper\ApmApplies;
|
||||
use WooCommerce\PayPalCommerce\Googlepay\Helper\ApmProductStatus;
|
||||
use WooCommerce\PayPalCommerce\Applepay\Helper\AvailabilityNotice;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
return array(
|
||||
'applepay.eligible' => static function ( ContainerInterface $container ): bool {
|
||||
|
@ -47,23 +46,37 @@ return array(
|
|||
|
||||
return ! $status->has_request_failure();
|
||||
},
|
||||
|
||||
'applepay.availability_notice' => static function ( ContainerInterface $container ): AvailabilityNotice {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
|
||||
return new AvailabilityNotice(
|
||||
$container->get( 'applepay.apple-product-status' ),
|
||||
$container->get( 'wcgateway.is-wc-gateways-list-page' ),
|
||||
$container->get( 'wcgateway.is-ppcp-settings-page' ),
|
||||
$container->get( 'applepay.available' ) || ( ! $container->get( 'applepay.is_referral' ) ),
|
||||
$container->get( 'applepay.server_supported' ),
|
||||
$settings->has( 'applepay_validated' ) ? $settings->get( 'applepay_validated' ) === true : false,
|
||||
$container->get( 'applepay.button' )
|
||||
);
|
||||
},
|
||||
|
||||
'applepay.apple-product-status' => static function( ContainerInterface $container ): AppleProductStatus {
|
||||
return new AppleProductStatus(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'api.endpoint.partners' ),
|
||||
$container->get( 'applepay.status-cache' ),
|
||||
$container->get( 'onboarding.state' ),
|
||||
$container->get( 'api.helper.failure-registry' )
|
||||
);
|
||||
},
|
||||
'applepay.enabled' => static function ( ContainerInterface $container ): bool {
|
||||
if ( apply_filters( 'woocommerce_paypal_payments_applepay_validate_product_status', false ) ) {
|
||||
'applepay.available' => static function ( ContainerInterface $container ): bool {
|
||||
if ( apply_filters( 'woocommerce_paypal_payments_applepay_validate_product_status', true ) ) {
|
||||
$status = $container->get( 'applepay.apple-product-status' );
|
||||
assert( $status instanceof AppleProductStatus );
|
||||
/**
|
||||
* If merchant isn't onboarded via /v1/customer/partner-referrals this returns false as the API call fails.
|
||||
*/
|
||||
return apply_filters( 'woocommerce_paypal_payments_applepay_product_status', $status->apple_is_active() );
|
||||
return apply_filters( 'woocommerce_paypal_payments_applepay_product_status', $status->is_active() );
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
@ -117,6 +130,24 @@ return array(
|
|||
return apply_filters(
|
||||
'woocommerce_paypal_payments_applepay_supported_country_currency_matrix',
|
||||
array(
|
||||
'GB' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'US' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
|
@ -125,6 +156,24 @@ return array(
|
|||
'JPY',
|
||||
'USD',
|
||||
),
|
||||
'CA' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
)
|
||||
);
|
||||
},
|
||||
|
@ -149,7 +198,7 @@ return array(
|
|||
$environment = $container->get( 'onboarding.environment' );
|
||||
assert( $environment instanceof Environment );
|
||||
|
||||
$enabled = $product_status->apple_is_active();
|
||||
$enabled = $product_status->is_active();
|
||||
|
||||
$enabled_status_text = esc_html__( 'Status: Available', 'woocommerce-paypal-payments' );
|
||||
$disabled_status_text = esc_html__( 'Status: Not yet enabled', 'woocommerce-paypal-payments' );
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -12,23 +12,16 @@ namespace WooCommerce\PayPalCommerce\Applepay\Assets;
|
|||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Cart;
|
||||
use WC_Checkout;
|
||||
use WC_Order;
|
||||
use WC_Session_Handler;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\ButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Session\MemoryWcSession;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\Handler\RequestHandlerTrait;
|
||||
|
||||
/**
|
||||
* Class PayPalPaymentMethod
|
||||
* Class ApplePayButton
|
||||
*/
|
||||
class ApplePayButton implements ButtonInterface {
|
||||
use RequestHandlerTrait;
|
||||
|
@ -178,21 +171,6 @@ class ApplePayButton implements ButtonInterface {
|
|||
$data['products'][0] = 'PAYMENT_METHODS';
|
||||
}
|
||||
$data['capabilities'][] = 'APPLE_PAY';
|
||||
$data['operations'][] = array(
|
||||
'operation' => 'API_INTEGRATION',
|
||||
'api_integration_preference' => array(
|
||||
'rest_api_integration' => array(
|
||||
'integration_method' => 'PAYPAL',
|
||||
'integration_type' => 'THIRD_PARTY',
|
||||
'third_party_details' => array(
|
||||
'features' => array(
|
||||
'PAYMENT',
|
||||
'REFUND',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
@ -422,7 +400,7 @@ class ApplePayButton implements ButtonInterface {
|
|||
}
|
||||
$applepay_request_data_object->order_data( $context );
|
||||
$this->update_posted_data( $applepay_request_data_object );
|
||||
if ( $context == 'product' ) {
|
||||
if ( $context === 'product' ) {
|
||||
$cart_item_key = $this->prepare_cart( $applepay_request_data_object );
|
||||
$cart = WC()->cart;
|
||||
$address = $applepay_request_data_object->shipping_address();
|
||||
|
@ -902,15 +880,19 @@ class ApplePayButton implements ButtonInterface {
|
|||
* Renders the Apple Pay button on the page
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @psalm-suppress RedundantCondition
|
||||
*/
|
||||
public function render(): bool {
|
||||
$is_applepay_button_enabled = $this->settings->has( 'applepay_button_enabled' ) ? $this->settings->get( 'applepay_button_enabled' ) : false;
|
||||
if ( ! $this->is_enabled() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$button_enabled_product = $is_applepay_button_enabled && $this->settings_status->is_smart_button_enabled_for_location( 'product' );
|
||||
$button_enabled_cart = $is_applepay_button_enabled && $this->settings_status->is_smart_button_enabled_for_location( 'cart' );
|
||||
$button_enabled_checkout = $is_applepay_button_enabled;
|
||||
$button_enabled_payorder = $is_applepay_button_enabled;
|
||||
$button_enabled_minicart = $is_applepay_button_enabled && $this->settings_status->is_smart_button_enabled_for_location( 'mini-cart' );
|
||||
$button_enabled_product = $this->settings_status->is_smart_button_enabled_for_location( 'product' );
|
||||
$button_enabled_cart = $this->settings_status->is_smart_button_enabled_for_location( 'cart' );
|
||||
$button_enabled_checkout = true;
|
||||
$button_enabled_payorder = true;
|
||||
$button_enabled_minicart = $this->settings_status->is_smart_button_enabled_for_location( 'mini-cart' );
|
||||
|
||||
add_filter(
|
||||
'woocommerce_paypal_payments_sdk_components_hook',
|
||||
|
@ -1017,13 +999,7 @@ class ApplePayButton implements ButtonInterface {
|
|||
);
|
||||
wp_enqueue_script( 'wc-ppcp-applepay' );
|
||||
|
||||
wp_register_style(
|
||||
'wc-ppcp-applepay',
|
||||
untrailingslashit( $this->module_url ) . '/assets/css/styles.css',
|
||||
array(),
|
||||
$this->version
|
||||
);
|
||||
wp_enqueue_style( 'wc-ppcp-applepay' );
|
||||
$this->enqueue_styles();
|
||||
|
||||
wp_localize_script(
|
||||
'wc-ppcp-applepay',
|
||||
|
@ -1038,6 +1014,23 @@ class ApplePayButton implements ButtonInterface {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues styles.
|
||||
*/
|
||||
public function enqueue_styles(): void {
|
||||
if ( ! $this->is_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_register_style(
|
||||
'wc-ppcp-applepay',
|
||||
untrailingslashit( $this->module_url ) . '/assets/css/styles.css',
|
||||
array(),
|
||||
$this->version
|
||||
);
|
||||
wp_enqueue_style( 'wc-ppcp-applepay' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the script data.
|
||||
*
|
||||
|
@ -1054,7 +1047,6 @@ class ApplePayButton implements ButtonInterface {
|
|||
*/
|
||||
public function is_enabled(): bool {
|
||||
try {
|
||||
// todo add also onboarded apple and enabled buttons.
|
||||
return $this->settings->has( 'applepay_button_enabled' ) && $this->settings->get( 'applepay_button_enabled' );
|
||||
} catch ( Exception $e ) {
|
||||
return false;
|
||||
|
|
|
@ -300,6 +300,10 @@ 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.
|
||||
if ( null === $value ) {
|
||||
continue;
|
||||
}
|
||||
if ( $key === 'woocommerce-process-checkout-nonce' ) {
|
||||
$key = 'nonce';
|
||||
}
|
||||
|
|
|
@ -1,41 +1,37 @@
|
|||
<?php
|
||||
/**
|
||||
* Manage the Seller status.
|
||||
* Status of the ApplePay merchant connection.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\WcGateway\Helper
|
||||
* @package WooCommerce\PayPalCommerce\Applepay\Assets
|
||||
*/
|
||||
|
||||
declare( strict_types=1 );
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Applepay\Assets;
|
||||
|
||||
use Throwable;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\FailureRegistry;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
* Class PayUponInvoiceProductStatus
|
||||
* Class AppleProductStatus
|
||||
*/
|
||||
class AppleProductStatus {
|
||||
const CAPABILITY_NAME = 'APPLE_PAY';
|
||||
const SETTINGS_KEY = 'products_apple_enabled';
|
||||
|
||||
const APPLE_STATUS_CACHE_KEY = 'apple_status_cache';
|
||||
const SETTINGS_VALUE_ENABLED = 'yes';
|
||||
const SETTINGS_VALUE_DISABLED = 'no';
|
||||
const SETTINGS_VALUE_UNDEFINED = '';
|
||||
|
||||
/**
|
||||
* The Cache.
|
||||
*
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Caches the status for the current load.
|
||||
* The current status stored in memory.
|
||||
*
|
||||
* @var bool|null
|
||||
*/
|
||||
private $current_status_cache;
|
||||
private $current_status = null;
|
||||
|
||||
/**
|
||||
* If there was a request failure.
|
||||
|
@ -73,24 +69,21 @@ class AppleProductStatus {
|
|||
private $api_failure_registry;
|
||||
|
||||
/**
|
||||
* PayUponInvoiceProductStatus constructor.
|
||||
* AppleProductStatus constructor.
|
||||
*
|
||||
* @param Settings $settings The Settings.
|
||||
* @param PartnersEndpoint $partners_endpoint The Partner Endpoint.
|
||||
* @param Cache $cache The cache.
|
||||
* @param State $onboarding_state The onboarding state.
|
||||
* @param FailureRegistry $api_failure_registry The API failure registry.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
PartnersEndpoint $partners_endpoint,
|
||||
Cache $cache,
|
||||
State $onboarding_state,
|
||||
FailureRegistry $api_failure_registry
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->partners_endpoint = $partners_endpoint;
|
||||
$this->cache = $cache;
|
||||
$this->onboarding_state = $onboarding_state;
|
||||
$this->api_failure_registry = $api_failure_registry;
|
||||
}
|
||||
|
@ -100,55 +93,71 @@ class AppleProductStatus {
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function apple_is_active() : bool {
|
||||
if ( $this->onboarding_state->current_state() < State::STATE_ONBOARDED ) {
|
||||
public function is_active() : bool {
|
||||
|
||||
// If not onboarded then makes no sense to check status.
|
||||
if ( ! $this->is_onboarded() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->cache->has( self::APPLE_STATUS_CACHE_KEY ) ) {
|
||||
return $this->cache->get( self::APPLE_STATUS_CACHE_KEY ) === 'true';
|
||||
// If status was already checked on this request return the same result.
|
||||
if ( null !== $this->current_status ) {
|
||||
return $this->current_status;
|
||||
}
|
||||
|
||||
if ( $this->current_status_cache === true ) {
|
||||
return $this->current_status_cache;
|
||||
}
|
||||
if ( $this->settings->has( 'products_apple_enabled' ) && $this->settings->get( 'products_apple_enabled' ) === true ) {
|
||||
$this->current_status_cache = true;
|
||||
return true;
|
||||
// Check if status was checked on previous requests.
|
||||
if ( $this->settings->has( self::SETTINGS_KEY ) && ( $this->settings->get( self::SETTINGS_KEY ) ) ) {
|
||||
$this->current_status = wc_string_to_bool( $this->settings->get( self::SETTINGS_KEY ) );
|
||||
return $this->current_status;
|
||||
}
|
||||
|
||||
// Check API failure registry to prevent multiple failed API requests.
|
||||
if ( $this->api_failure_registry->has_failure_in_timeframe( FailureRegistry::SELLER_STATUS_KEY, HOUR_IN_SECONDS ) ) {
|
||||
$this->has_request_failure = true;
|
||||
$this->current_status_cache = false;
|
||||
return $this->current_status_cache;
|
||||
$this->has_request_failure = true;
|
||||
$this->current_status = false;
|
||||
return $this->current_status;
|
||||
}
|
||||
|
||||
// Request seller status via PayPal API.
|
||||
try {
|
||||
$seller_status = $this->partners_endpoint->seller_status();
|
||||
} catch ( Throwable $error ) {
|
||||
$this->has_request_failure = true;
|
||||
$this->current_status_cache = false;
|
||||
return false;
|
||||
$this->has_request_failure = true;
|
||||
$this->current_status = false;
|
||||
return $this->current_status;
|
||||
}
|
||||
|
||||
// Check the seller status for the intended capability.
|
||||
foreach ( $seller_status->products() as $product ) {
|
||||
if ( $product->name() !== 'PAYMENT_METHODS' ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( in_array( 'APPLE_PAY', $product->capabilities(), true ) ) {
|
||||
$this->settings->set( 'products_apple_enabled', true );
|
||||
if ( in_array( self::CAPABILITY_NAME, $product->capabilities(), true ) ) {
|
||||
// Capability found, persist status and return true.
|
||||
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_ENABLED );
|
||||
$this->settings->persist();
|
||||
$this->current_status_cache = true;
|
||||
$this->cache->set( self::APPLE_STATUS_CACHE_KEY, 'true', 3 * MONTH_IN_SECONDS );
|
||||
return true;
|
||||
|
||||
$this->current_status = true;
|
||||
return $this->current_status;
|
||||
}
|
||||
}
|
||||
$this->cache->set( self::APPLE_STATUS_CACHE_KEY, 'false', 3 * MONTH_IN_SECONDS );
|
||||
|
||||
$this->current_status_cache = false;
|
||||
return false;
|
||||
// Capability not found, persist status and return false.
|
||||
$this->settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_DISABLED );
|
||||
$this->settings->persist();
|
||||
|
||||
$this->current_status = false;
|
||||
return $this->current_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the seller is onboarded.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_onboarded(): bool {
|
||||
return $this->onboarding_state->current_state() >= State::STATE_ONBOARDED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,4 +169,24 @@ class AppleProductStatus {
|
|||
return $this->has_request_failure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the persisted result to force a recheck.
|
||||
*
|
||||
* @param Settings|null $settings The settings object.
|
||||
* We accept a Settings object to don't override other sequential settings that are being updated elsewhere.
|
||||
* @return void
|
||||
*/
|
||||
public function clear( Settings $settings = null ): void {
|
||||
if ( null === $settings ) {
|
||||
$settings = $this->settings;
|
||||
}
|
||||
|
||||
$this->current_status = null;
|
||||
|
||||
if ( $settings->has( self::SETTINGS_KEY ) ) {
|
||||
$settings->set( self::SETTINGS_KEY, self::SETTINGS_VALUE_UNDEFINED );
|
||||
$settings->persist();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
291
modules/ppcp-applepay/src/Helper/AvailabilityNotice.php
Normal file
291
modules/ppcp-applepay/src/Helper/AvailabilityNotice.php
Normal file
|
@ -0,0 +1,291 @@
|
|||
<?php
|
||||
/**
|
||||
* Adds availability notice if applicable.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Applepay\Helper
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Applepay\Helper;
|
||||
|
||||
use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
|
||||
use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
|
||||
use WooCommerce\PayPalCommerce\Applepay\Assets\ApplePayButton;
|
||||
use WooCommerce\PayPalCommerce\Applepay\Assets\AppleProductStatus;
|
||||
|
||||
/**
|
||||
* Class AvailabilityNotice
|
||||
*/
|
||||
class AvailabilityNotice {
|
||||
|
||||
/**
|
||||
* The product status handler.
|
||||
*
|
||||
* @var AppleProductStatus
|
||||
*/
|
||||
private $product_status;
|
||||
|
||||
/**
|
||||
* Indicates if we're on the WooCommerce gateways list page.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_wc_gateways_list_page;
|
||||
|
||||
/**
|
||||
* Indicates if we're on a PPCP Settings page.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_ppcp_settings_page;
|
||||
|
||||
/**
|
||||
* Indicates if ApplePay is available to be enabled.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_available;
|
||||
|
||||
/**
|
||||
* Indicates if this server is supported for ApplePay.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_server_supported;
|
||||
|
||||
/**
|
||||
* Indicates if the merchant is validated for ApplePay.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_merchant_validated;
|
||||
|
||||
/**
|
||||
* The button.
|
||||
*
|
||||
* @var ApplePayButton
|
||||
*/
|
||||
private $button;
|
||||
|
||||
/**
|
||||
* Class ApmProductStatus constructor.
|
||||
*
|
||||
* @param AppleProductStatus $product_status The product status handler.
|
||||
* @param bool $is_wc_gateways_list_page Indicates if we're on the WooCommerce gateways list page.
|
||||
* @param bool $is_ppcp_settings_page Indicates if we're on a PPCP Settings page.
|
||||
* @param bool $is_available Indicates if ApplePay is available to be enabled.
|
||||
* @param bool $is_server_supported Indicates if this server is supported for ApplePay.
|
||||
* @param bool $is_merchant_validated Indicates if the merchant is validated for ApplePay.
|
||||
* @param ApplePayButton $button The button.
|
||||
*/
|
||||
public function __construct(
|
||||
AppleProductStatus $product_status,
|
||||
bool $is_wc_gateways_list_page,
|
||||
bool $is_ppcp_settings_page,
|
||||
bool $is_available,
|
||||
bool $is_server_supported,
|
||||
bool $is_merchant_validated,
|
||||
ApplePayButton $button
|
||||
) {
|
||||
$this->product_status = $product_status;
|
||||
$this->is_wc_gateways_list_page = $is_wc_gateways_list_page;
|
||||
$this->is_ppcp_settings_page = $is_ppcp_settings_page;
|
||||
$this->is_available = $is_available;
|
||||
$this->is_server_supported = $is_server_supported;
|
||||
$this->is_merchant_validated = $is_merchant_validated;
|
||||
$this->button = $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds availability notice if applicable.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute(): void {
|
||||
if ( ! $this->should_display() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to check is active before checking failure requests, otherwise failure status won't be set.
|
||||
$is_active = $this->product_status->is_active();
|
||||
|
||||
if ( $this->product_status->has_request_failure() ) {
|
||||
$this->add_seller_status_failure_notice();
|
||||
} elseif ( ! $is_active ) {
|
||||
$this->add_not_available_notice();
|
||||
}
|
||||
|
||||
if ( ! $this->is_available ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! $this->is_server_supported ) {
|
||||
$this->add_server_not_supported_notice();
|
||||
}
|
||||
|
||||
$button_enabled = $this->button->is_enabled();
|
||||
|
||||
// We do this check on $_POST because this is called before settings are saved.
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
if ( isset( $_POST['ppcp'] ) ) {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$post_data = wc_clean( (array) wp_unslash( $_POST['ppcp'] ) );
|
||||
$button_enabled = wc_string_to_bool( $post_data['applepay_button_enabled'] ?? false );
|
||||
}
|
||||
|
||||
if ( ! $button_enabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! $this->is_merchant_validated ) {
|
||||
$this->add_merchant_not_validated_notice();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the message should display.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function should_display(): bool {
|
||||
if ( ! $this->product_status->is_onboarded() ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! $this->is_wc_gateways_list_page && ! $this->is_ppcp_settings_page ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds seller status failure notice.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_seller_status_failure_notice(): void {
|
||||
add_filter(
|
||||
Repository::NOTICES_FILTER,
|
||||
/**
|
||||
* Adds seller status notice.
|
||||
*
|
||||
* @param array $notices The notices.
|
||||
* @return array
|
||||
*
|
||||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
static function ( $notices ): array {
|
||||
$message = sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__(
|
||||
'<p>Notice: We could not determine your PayPal seller status to list your available features. Disconnect and reconnect your PayPal account through our %1$sonboarding process%2$s to resolve this.</p><p>Don\'t worry if you cannot use the %1$sonboarding process%2$s; most functionalities available to your account should work.</p>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#connect-paypal-account" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
// Name the key so it can be overridden in other modules.
|
||||
$notices['error_product_status'] = new Message( $message, 'warning', true, 'ppcp-notice-wrapper' );
|
||||
return $notices;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds not available notice.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_not_available_notice(): void {
|
||||
add_filter(
|
||||
Repository::NOTICES_FILTER,
|
||||
/**
|
||||
* Adds ApplePay not available notice.
|
||||
*
|
||||
* @param array $notices The notices.
|
||||
* @return array
|
||||
*
|
||||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
static function ( $notices ): array {
|
||||
$message = sprintf(
|
||||
__(
|
||||
'Apple Pay is not available on your PayPal seller account.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
|
||||
$notices[] = new Message( $message, 'warning', true, 'ppcp-notice-wrapper' );
|
||||
return $notices;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds ApplePay server not supported notice.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_server_not_supported_notice(): void {
|
||||
add_filter(
|
||||
Repository::NOTICES_FILTER,
|
||||
/**
|
||||
* Adds ApplePay server not supported notice.
|
||||
*
|
||||
* @param array $notices The notices.
|
||||
* @return array
|
||||
*
|
||||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
static function ( $notices ): array {
|
||||
$message = sprintf(
|
||||
__(
|
||||
'Apple Pay is not supported on this server. Please contact your hosting provider to enable it.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
|
||||
$notices[] = new Message( $message, 'error', true, 'ppcp-notice-wrapper' );
|
||||
return $notices;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds ApplePay merchant not validated notice.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_merchant_not_validated_notice(): void {
|
||||
add_filter(
|
||||
Repository::NOTICES_FILTER,
|
||||
/**
|
||||
* Adds ApplePay merchant not validated notice.
|
||||
*
|
||||
* @param array $notices The notices.
|
||||
* @return array
|
||||
*
|
||||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
static function ( $notices ): array {
|
||||
$message = sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag for the well-known file, %3$s and %4$s are the opening and closing of HTML <a> tag for the help document.
|
||||
__(
|
||||
'Apple Pay Validation Error. Please ensure the presentment of the correct %1$sdomain association file%2$s for Apple to validate your domain. %3$sLearn more%4$s about the Apple Pay requirements',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'<a href="/.well-known/apple-developer-merchantid-domain-association" target="_blank">',
|
||||
'</a>',
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#apple-pay" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
$notices[] = new Message( $message, 'error', true, 'ppcp-notice-wrapper' );
|
||||
return $notices;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -19,7 +19,7 @@ const PayPalComponent = ({
|
|||
shippingData,
|
||||
isEditing,
|
||||
}) => {
|
||||
const {onPaymentSetup, onCheckoutAfterProcessingWithError, onCheckoutValidation} = eventRegistration;
|
||||
const {onPaymentSetup, onCheckoutFail, onCheckoutValidation} = eventRegistration;
|
||||
const {responseTypes} = emitResponse;
|
||||
|
||||
const [paypalOrder, setPaypalOrder] = useState(null);
|
||||
|
@ -253,21 +253,24 @@ const PayPalComponent = ({
|
|||
}, [onPaymentSetup, paypalOrder, activePaymentMethod]);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = onCheckoutAfterProcessingWithError(({ processingResponse }) => {
|
||||
if (activePaymentMethod !== config.id) {
|
||||
return;
|
||||
}
|
||||
const unsubscribe = onCheckoutFail(({ processingResponse }) => {
|
||||
console.error(processingResponse)
|
||||
if (onClose) {
|
||||
onClose();
|
||||
}
|
||||
if (processingResponse?.paymentDetails?.errorMessage) {
|
||||
return {
|
||||
type: emitResponse.responseTypes.ERROR,
|
||||
message: processingResponse.paymentDetails.errorMessage,
|
||||
messageContext: config.scriptData.continuation ? emitResponse.noticeContexts.PAYMENTS : emitResponse.noticeContexts.EXPRESS_PAYMENTS,
|
||||
};
|
||||
if (config.scriptData.continuation) {
|
||||
return true;
|
||||
}
|
||||
if (!config.finalReviewEnabled) {
|
||||
location.href = getCheckoutRedirectUrl();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return unsubscribe;
|
||||
}, [onCheckoutAfterProcessingWithError, onClose]);
|
||||
}, [onCheckoutFail, onClose, activePaymentMethod]);
|
||||
|
||||
if (config.scriptData.continuation) {
|
||||
return (
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
cursor: not-allowed;
|
||||
-webkit-filter: grayscale(100%);
|
||||
filter: grayscale(100%);
|
||||
|
||||
* {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ppc-button-wrapper #ppcp-messages:first-child {
|
||||
|
|
|
@ -189,7 +189,6 @@ class GooglepayButton {
|
|||
callback(el);
|
||||
} else if (timeElapsed > timeout) {
|
||||
clearInterval(interval);
|
||||
console.error('Waiting for wrapper timed out.', selector);
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,9 @@ import GooglepayManager from "./GooglepayManager";
|
|||
};
|
||||
|
||||
jQuery(document.body).on('updated_cart_totals updated_checkout', () => {
|
||||
manager.reinit();
|
||||
if (manager) {
|
||||
manager.reinit();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener(
|
||||
|
|
|
@ -204,21 +204,6 @@ class Button implements ButtonInterface {
|
|||
}
|
||||
|
||||
$data['capabilities'][] = 'GOOGLE_PAY';
|
||||
$data['operations'][] = array(
|
||||
'operation' => 'API_INTEGRATION',
|
||||
'api_integration_preference' => array(
|
||||
'rest_api_integration' => array(
|
||||
'integration_method' => 'PAYPAL',
|
||||
'integration_type' => 'THIRD_PARTY',
|
||||
'third_party_details' => array(
|
||||
'features' => array(
|
||||
'PAYMENT',
|
||||
'REFUND',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
@ -363,6 +348,23 @@ class Button implements ButtonInterface {
|
|||
);
|
||||
wp_enqueue_script( 'wc-ppcp-googlepay' );
|
||||
|
||||
$this->enqueue_styles();
|
||||
|
||||
wp_localize_script(
|
||||
'wc-ppcp-googlepay',
|
||||
'wc_ppcp_googlepay',
|
||||
$this->script_data()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues styles.
|
||||
*/
|
||||
public function enqueue_styles(): void {
|
||||
if ( ! $this->is_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_register_style(
|
||||
'wc-ppcp-googlepay',
|
||||
untrailingslashit( $this->module_url ) . '/assets/css/styles.css',
|
||||
|
@ -370,12 +372,6 @@ class Button implements ButtonInterface {
|
|||
$this->version
|
||||
);
|
||||
wp_enqueue_style( 'wc-ppcp-googlepay' );
|
||||
|
||||
wp_localize_script(
|
||||
'wc-ppcp-googlepay',
|
||||
'wc_ppcp_googlepay',
|
||||
$this->script_data()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Googlepay;
|
|||
|
||||
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\ButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Googlepay\Endpoint\UpdatePaymentDataEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Googlepay\Helper\ApmProductStatus;
|
||||
use WooCommerce\PayPalCommerce\Googlepay\Helper\AvailabilityNotice;
|
||||
|
@ -45,7 +46,6 @@ class GooglepayModule implements ModuleInterface {
|
|||
function( Settings $settings = null ) use ( $c ): void {
|
||||
$apm_status = $c->get( 'googlepay.helpers.apm-product-status' );
|
||||
assert( $apm_status instanceof ApmProductStatus );
|
||||
|
||||
$apm_status->clear( $settings );
|
||||
}
|
||||
);
|
||||
|
@ -86,7 +86,20 @@ class GooglepayModule implements ModuleInterface {
|
|||
add_action(
|
||||
'wp_enqueue_scripts',
|
||||
static function () use ( $c, $button ) {
|
||||
$button->enqueue();
|
||||
$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();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -107,7 +107,6 @@ class AvailabilityNotice {
|
|||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
static function ( $notices ): array {
|
||||
|
||||
$message = sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__(
|
||||
|
@ -142,7 +141,6 @@ class AvailabilityNotice {
|
|||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
static function ( $notices ): array {
|
||||
|
||||
$message = sprintf(
|
||||
__(
|
||||
'Google Pay is not available on your PayPal seller account.',
|
||||
|
|
|
@ -9,25 +9,40 @@ 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\Compat\AdminContextTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
|
||||
trait TrackingAvailabilityTrait {
|
||||
|
||||
use AdminContextTrait;
|
||||
|
||||
/**
|
||||
* Checks if tracking is enabled.
|
||||
* Checks if tracking should be enabled for current post.
|
||||
*
|
||||
* @param Bearer $bearer The Bearer.
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_tracking_enabled( Bearer $bearer ): bool {
|
||||
$post_id = (int) wc_clean( wp_unslash( $_GET['id'] ?? $_GET['post'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
if ( ! $post_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$order = wc_get_order( $post_id );
|
||||
if ( ! is_a( $order, WC_Order::class ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$captured = $order->get_meta( AuthorizedPaymentsProcessor::CAPTURED_META_KEY );
|
||||
$is_captured = empty( $captured ) || wc_string_to_bool( $captured );
|
||||
$is_paypal_order_edit_page = $order->get_meta( PayPalGateway::ORDER_ID_META_KEY ) && ! empty( $order->get_transaction_id() );
|
||||
|
||||
try {
|
||||
$token = $bearer->bearer();
|
||||
return $token->is_tracking_available()
|
||||
&& $this->is_paypal_order_edit_page()
|
||||
return $is_paypal_order_edit_page
|
||||
&& $is_captured
|
||||
&& $token->is_tracking_available()
|
||||
&& apply_filters( 'woocommerce_paypal_payments_shipment_tracking_enabled', true );
|
||||
} catch ( RuntimeException $exception ) {
|
||||
return false;
|
||||
|
|
|
@ -318,6 +318,8 @@ return array(
|
|||
$pui_status_cache,
|
||||
$dcc_status_cache,
|
||||
$container->get( 'http.redirector' ),
|
||||
$container->get( 'api.partner_merchant_id-production' ),
|
||||
$container->get( 'api.partner_merchant_id-sandbox' ),
|
||||
$logger
|
||||
);
|
||||
},
|
||||
|
|
|
@ -124,13 +124,6 @@ class SettingsListener {
|
|||
*/
|
||||
protected $redirector;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* Max onboarding URL retries.
|
||||
*
|
||||
|
@ -145,6 +138,27 @@ class SettingsListener {
|
|||
*/
|
||||
private $onboarding_retry_delay = 2;
|
||||
|
||||
/**
|
||||
* Partner merchant ID production.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $partner_merchant_id_production;
|
||||
|
||||
/**
|
||||
* Partner merchant ID sandbox.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $partner_merchant_id_sandbox;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* SettingsListener constructor.
|
||||
*
|
||||
|
@ -160,6 +174,8 @@ class SettingsListener {
|
|||
* @param Cache $pui_status_cache The PUI status cache.
|
||||
* @param Cache $dcc_status_cache The DCC status cache.
|
||||
* @param RedirectorInterface $redirector The HTTP redirector.
|
||||
* @param string $partner_merchant_id_production Partner merchant ID production.
|
||||
* @param string $partner_merchant_id_sandbox Partner merchant ID sandbox.
|
||||
* @param ?LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -175,22 +191,26 @@ class SettingsListener {
|
|||
Cache $pui_status_cache,
|
||||
Cache $dcc_status_cache,
|
||||
RedirectorInterface $redirector,
|
||||
string $partner_merchant_id_production,
|
||||
string $partner_merchant_id_sandbox,
|
||||
LoggerInterface $logger = null
|
||||
) {
|
||||
|
||||
$this->settings = $settings;
|
||||
$this->setting_fields = $setting_fields;
|
||||
$this->webhook_registrar = $webhook_registrar;
|
||||
$this->cache = $cache;
|
||||
$this->state = $state;
|
||||
$this->bearer = $bearer;
|
||||
$this->page_id = $page_id;
|
||||
$this->signup_link_cache = $signup_link_cache;
|
||||
$this->signup_link_ids = $signup_link_ids;
|
||||
$this->pui_status_cache = $pui_status_cache;
|
||||
$this->dcc_status_cache = $dcc_status_cache;
|
||||
$this->redirector = $redirector;
|
||||
$this->logger = $logger ?: new NullLogger();
|
||||
$this->settings = $settings;
|
||||
$this->setting_fields = $setting_fields;
|
||||
$this->webhook_registrar = $webhook_registrar;
|
||||
$this->cache = $cache;
|
||||
$this->state = $state;
|
||||
$this->bearer = $bearer;
|
||||
$this->page_id = $page_id;
|
||||
$this->signup_link_cache = $signup_link_cache;
|
||||
$this->signup_link_ids = $signup_link_ids;
|
||||
$this->pui_status_cache = $pui_status_cache;
|
||||
$this->dcc_status_cache = $dcc_status_cache;
|
||||
$this->redirector = $redirector;
|
||||
$this->partner_merchant_id_production = $partner_merchant_id_production;
|
||||
$this->partner_merchant_id_sandbox = $partner_merchant_id_sandbox;
|
||||
$this->logger = $logger ?: new NullLogger();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,7 +230,11 @@ class SettingsListener {
|
|||
return;
|
||||
}
|
||||
|
||||
$merchant_id = sanitize_text_field( wp_unslash( $_GET['merchantIdInPayPal'] ) );
|
||||
$merchant_id = sanitize_text_field( wp_unslash( $_GET['merchantIdInPayPal'] ) );
|
||||
if ( $merchant_id === $this->partner_merchant_id_production || $merchant_id === $this->partner_merchant_id_sandbox ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$merchant_email = $this->sanitize_onboarding_email( sanitize_text_field( wp_unslash( $_GET['merchantId'] ) ) );
|
||||
$onboarding_token = sanitize_text_field( wp_unslash( $_GET['ppcpToken'] ) );
|
||||
$retry_count = isset( $_GET['ppcpRetry'] ) ? ( (int) sanitize_text_field( wp_unslash( $_GET['ppcpRetry'] ) ) ) : 0;
|
||||
|
@ -498,10 +522,18 @@ class SettingsListener {
|
|||
if ( ! isset( $settings['client_id_sandbox'] ) && ! isset( $settings['client_id_production'] ) ) {
|
||||
return $settings;
|
||||
}
|
||||
$is_sandbox = isset( $settings['sandbox_on'] ) && $settings['sandbox_on'];
|
||||
$settings['client_id'] = $is_sandbox ? $settings['client_id_sandbox'] : $settings['client_id_production'];
|
||||
$settings['client_secret'] = $is_sandbox ? $settings['client_secret_sandbox'] : $settings['client_secret_production'];
|
||||
$settings['merchant_id'] = $is_sandbox ? $settings['merchant_id_sandbox'] : $settings['merchant_id_production'];
|
||||
$is_sandbox = isset( $settings['sandbox_on'] ) && $settings['sandbox_on'];
|
||||
$settings['client_id'] = $is_sandbox ? $settings['client_id_sandbox'] : $settings['client_id_production'];
|
||||
$settings['client_secret'] = $is_sandbox ? $settings['client_secret_sandbox'] : $settings['client_secret_production'];
|
||||
|
||||
if ( $settings['merchant_id_sandbox'] === $this->partner_merchant_id_sandbox || $settings['merchant_id_sandbox'] === $this->partner_merchant_id_production ) {
|
||||
$settings['merchant_id_sandbox'] = '';
|
||||
}
|
||||
if ( $settings['merchant_id_production'] === $this->partner_merchant_id_sandbox || $settings['merchant_id_sandbox'] === $this->partner_merchant_id_production ) {
|
||||
$settings['merchant_id_production'] = '';
|
||||
}
|
||||
$settings['merchant_id'] = $is_sandbox ? $settings['merchant_id_sandbox'] : $settings['merchant_id_production'];
|
||||
|
||||
$settings['merchant_email'] = $is_sandbox ? $settings['merchant_email_sandbox'] : $settings['merchant_email_production'];
|
||||
return $settings;
|
||||
}
|
||||
|
|
|
@ -180,6 +180,7 @@ If you encounter issues with the PayPal buttons not appearing after an update, p
|
|||
|
||||
== Changelog ==
|
||||
|
||||
= 2.4.0 - xxxx-xx-xx =
|
||||
* 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
|
||||
|
@ -193,6 +194,14 @@ If you encounter issues with the PayPal buttons not appearing after an update, p
|
|||
* Enhancement - Cart simulation improvements #1753
|
||||
* Enhancement - Billing schedule fields not greyed out when PayPal Subscriptions product is connected #1755
|
||||
* Enhancement - Check validation errors when submitting in block #1528
|
||||
* Enhancement - Improve handling of server error when submitting block #1785
|
||||
* Enhancement - Extend Apple Pay country eligibility #1781
|
||||
* Enhancement - Apple Pay validation notice improvements #1783
|
||||
* Enhancement - Apple Pay payment process issues #1789
|
||||
* Enhancement - Disable the tracking if payment is not captured #1780
|
||||
* Enhancement - Place order button remains - Could not retrieve order #1786
|
||||
* Enhancement - Google Pay for variable product greyed out but clickable #1788
|
||||
* Enhancement - Merchant credential validation & remove PAYEE object #1795
|
||||
|
||||
= 2.3.1 - 2023-09-26 =
|
||||
* Fix - Fatal error when saving product while WooCommerce Subscriptions plugin is not active #1731
|
||||
|
|
|
@ -45,7 +45,6 @@ class PurchaseUnitTest extends TestCase
|
|||
$shipping,
|
||||
'referenceId',
|
||||
'description',
|
||||
null,
|
||||
'customId',
|
||||
'invoiceId',
|
||||
'softDescriptor'
|
||||
|
@ -54,7 +53,6 @@ class PurchaseUnitTest extends TestCase
|
|||
$this->assertEquals($amount, $testee->amount());
|
||||
$this->assertEquals('referenceId', $testee->reference_id());
|
||||
$this->assertEquals('description', $testee->description());
|
||||
$this->assertNull($testee->payee());
|
||||
$this->assertEquals('customId', $testee->custom_id());
|
||||
$this->assertEquals('invoiceId', $testee->invoice_id());
|
||||
$this->assertEquals('softDescriptor', $testee->soft_descriptor());
|
||||
|
@ -808,46 +806,4 @@ class PurchaseUnitTest extends TestCase
|
|||
|
||||
return $values;
|
||||
}
|
||||
|
||||
public function testPayee()
|
||||
{
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amount->shouldReceive('breakdown')->andReturnNull();
|
||||
$amount->shouldReceive('to_array')->andReturn(['amount']);
|
||||
$item1 = Mockery::mock(Item::class);
|
||||
$item1->shouldReceive('to_array')->andReturn(['item1']);
|
||||
$item2 = Mockery::mock(Item::class);
|
||||
$item2->shouldReceive('to_array')->andReturn(['item2']);
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shipping->shouldReceive('to_array')->andReturn(['shipping']);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payee->shouldReceive('to_array')->andReturn(['payee']);
|
||||
$testee = new PurchaseUnit(
|
||||
$amount,
|
||||
[],
|
||||
$shipping,
|
||||
'referenceId',
|
||||
'description',
|
||||
$payee,
|
||||
'customId',
|
||||
'invoiceId',
|
||||
'softDescriptor'
|
||||
);
|
||||
|
||||
$this->assertEquals($payee, $testee->payee());
|
||||
|
||||
$expected = [
|
||||
'reference_id' => 'referenceId',
|
||||
'amount' => ['amount'],
|
||||
'description' => 'description',
|
||||
'items' => [],
|
||||
'shipping' => ['shipping'],
|
||||
'custom_id' => 'customId',
|
||||
'invoice_id' => 'invoiceId',
|
||||
'soft_descriptor' => 'softDescriptor',
|
||||
'payee' => ['payee'],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $testee->to_array());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,9 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Address;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Amount;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payee;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Shipping;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
|
||||
use WooCommerce\PayPalCommerce\TestCase;
|
||||
use Mockery;
|
||||
|
||||
|
@ -45,11 +43,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
->shouldReceive('from_wc_order')
|
||||
->with($wcOrder)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->shouldReceive('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->shouldReceive('from_wc_order')
|
||||
|
@ -75,8 +68,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -84,7 +75,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
|
||||
$unit = $testee->from_wc_order($wcOrder);
|
||||
$this->assertTrue(is_a($unit, PurchaseUnit::class));
|
||||
$this->assertEquals($payee, $unit->payee());
|
||||
$this->assertEquals('', $unit->description());
|
||||
$this->assertEquals('default', $unit->reference_id());
|
||||
$this->assertEquals($this->wcOrderId, $unit->custom_id());
|
||||
|
@ -106,11 +96,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
->shouldReceive('from_wc_order')
|
||||
->with($wcOrder)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->shouldReceive('payee')->andReturn($payee);
|
||||
|
||||
$fee = Mockery::mock(Item::class, [
|
||||
'category' => Item::DIGITAL_GOODS,
|
||||
|
@ -139,8 +124,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -162,11 +145,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
->expects('from_wc_order')
|
||||
->with($wcOrder)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->expects('from_wc_order')
|
||||
|
@ -194,8 +172,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -216,11 +192,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
->expects('from_wc_order')
|
||||
->with($wcOrder)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->expects('from_wc_order')
|
||||
|
@ -243,8 +214,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -267,11 +236,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
->expects('from_wc_cart')
|
||||
->with($wcCart)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
|
@ -299,8 +263,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -308,7 +270,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
|
||||
$unit = $testee->from_wc_cart($wcCart);
|
||||
$this->assertTrue(is_a($unit, PurchaseUnit::class));
|
||||
$this->assertEquals($payee, $unit->payee());
|
||||
$this->assertEquals('', $unit->description());
|
||||
$this->assertEquals('default', $unit->reference_id());
|
||||
$this->assertEquals('', $unit->custom_id());
|
||||
|
@ -331,11 +292,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
->expects('from_wc_cart')
|
||||
->with($wcCart)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
|
@ -346,8 +302,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -369,11 +323,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
->expects('from_wc_cart')
|
||||
->with($wcCart)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->expects('from_wc_cart')
|
||||
|
@ -395,8 +344,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -410,15 +357,10 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
{
|
||||
$rawItem = (object) ['items' => 1];
|
||||
$rawAmount = (object) ['amount' => 1];
|
||||
$rawPayee = (object) ['payee' => 1];
|
||||
$rawShipping = (object) ['shipping' => 1];
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('from_paypal_response')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeFactory->expects('from_paypal_response')->with($rawPayee)->andReturn($payee);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory->expects('from_paypal_response')->with($rawItem)->andReturn($this->item);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
|
@ -427,8 +369,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -442,13 +382,11 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
'soft_descriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'payee' => $rawPayee,
|
||||
'shipping' => $rawShipping,
|
||||
];
|
||||
|
||||
$unit = $testee->from_paypal_response($response);
|
||||
$this->assertTrue(is_a($unit, PurchaseUnit::class));
|
||||
$this->assertEquals($payee, $unit->payee());
|
||||
$this->assertEquals('description', $unit->description());
|
||||
$this->assertEquals('default', $unit->reference_id());
|
||||
$this->assertEquals('customId', $unit->custom_id());
|
||||
|
@ -459,67 +397,19 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
$this->assertEquals($shipping, $unit->shipping());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponsePayeeIsNull()
|
||||
{
|
||||
$rawItem = (object) ['items' => 1];
|
||||
$rawAmount = (object) ['amount' => 1];
|
||||
$rawPayee = (object) ['payee' => 1];
|
||||
$rawShipping = (object) ['shipping' => 1];
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('from_paypal_response')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory->expects('from_paypal_response')->with($rawItem)->andReturn($this->item);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shippingFactory->expects('from_paypal_response')->with($rawShipping)->andReturn($shipping);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$response = (object) [
|
||||
'reference_id' => 'default',
|
||||
'description' => 'description',
|
||||
'customId' => 'customId',
|
||||
'invoiceId' => 'invoiceId',
|
||||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'shipping' => $rawShipping,
|
||||
];
|
||||
|
||||
$unit = $testee->from_paypal_response($response);
|
||||
$this->assertNull($unit->payee());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseShippingIsNull()
|
||||
{
|
||||
$rawItem = (object) ['items' => 1];
|
||||
$rawAmount = (object) ['amount' => 1];
|
||||
$rawPayee = (object) ['payee' => 1];
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('from_paypal_response')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeFactory->expects('from_paypal_response')->with($rawPayee)->andReturn($payee);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory->expects('from_paypal_response')->with($rawItem)->andReturn($this->item);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -533,7 +423,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'payee' => $rawPayee,
|
||||
];
|
||||
|
||||
$unit = $testee->from_paypal_response($response);
|
||||
|
@ -543,15 +432,11 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
public function testFromPayPalResponseNeedsReferenceId()
|
||||
{
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
|
@ -564,7 +449,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => '',
|
||||
'items' => [],
|
||||
'payee' => '',
|
||||
'shipping' => '',
|
||||
];
|
||||
|
||||
|
@ -576,17 +460,12 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
{
|
||||
$rawItem = (object)['items' => 1];
|
||||
$rawAmount = (object)['amount' => 1];
|
||||
$rawPayee = (object)['payee' => 1];
|
||||
$rawShipping = (object)['shipping' => 1];
|
||||
$rawPayments = (object)['payments' => 1];
|
||||
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('from_paypal_response')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeFactory->expects('from_paypal_response')->with($rawPayee)->andReturn($payee);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$item = Mockery::mock(Item::class, ['category' => Item::PHYSICAL_GOODS]);
|
||||
$itemFactory->expects('from_paypal_response')->with($rawItem)->andReturn($item);
|
||||
|
@ -600,8 +479,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFactory
|
||||
|
@ -615,7 +492,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'payee' => $rawPayee,
|
||||
'shipping' => $rawShipping,
|
||||
'payments' => $rawPayments,
|
||||
];
|
||||
|
@ -628,17 +504,12 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
{
|
||||
$rawItem = (object)['items' => 1];
|
||||
$rawAmount = (object)['amount' => 1];
|
||||
$rawPayee = (object)['payee' => 1];
|
||||
$rawShipping = (object)['shipping' => 1];
|
||||
$rawPayments = (object)['payments' => 1];
|
||||
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('from_paypal_response')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeFactory->expects('from_paypal_response')->with($rawPayee)->andReturn($payee);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$item = Mockery::mock(Item::class, ['category' => Item::PHYSICAL_GOODS]);
|
||||
$itemFactory->expects('from_paypal_response')->with($rawItem)->andReturn($item);
|
||||
|
@ -650,8 +521,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFactory
|
||||
|
@ -665,7 +534,6 @@ class PurchaseUnitFactoryTest extends TestCase
|
|||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'payee' => $rawPayee,
|
||||
'shipping' => $rawShipping,
|
||||
];
|
||||
|
||||
|
|
|
@ -53,7 +53,9 @@ class SettingsListenerTest extends ModularTestCase
|
|||
$signup_link_ids,
|
||||
$pui_status_cache,
|
||||
$dcc_status_cache,
|
||||
new RedirectorStub()
|
||||
new RedirectorStub(),
|
||||
'',
|
||||
''
|
||||
);
|
||||
|
||||
$_GET['section'] = PayPalGateway::ID;
|
||||
|
|
|
@ -23,7 +23,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
|||
|
||||
define( 'PAYPAL_API_URL', 'https://api-m.paypal.com' );
|
||||
define( 'PAYPAL_SANDBOX_API_URL', 'https://api-m.sandbox.paypal.com' );
|
||||
define( 'PAYPAL_INTEGRATION_DATE', '2023-10-18' );
|
||||
define( 'PAYPAL_INTEGRATION_DATE', '2023-10-25' );
|
||||
|
||||
! defined( 'CONNECT_WOO_CLIENT_ID' ) && define( 'CONNECT_WOO_CLIENT_ID', 'AcCAsWta_JTL__OfpjspNyH7c1GGHH332fLwonA5CwX4Y10mhybRZmHLA0GdRbwKwjQIhpDQy0pluX_P' );
|
||||
! defined( 'CONNECT_WOO_SANDBOX_CLIENT_ID' ) && define( 'CONNECT_WOO_SANDBOX_CLIENT_ID', 'AYmOHbt1VHg-OZ_oihPdzKEVbU3qg0qXonBcAztuzniQRaKE0w1Hr762cSFwd4n8wxOl-TCWohEa0XM_' );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue