mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-04 08:47:23 +08:00
Merge pull request #2152 from woocommerce/PCP-2768-zero-sum-subscriptions-cause-cannot-be-zero-or-negative-when-using-vault-v-3
Zero sum subscriptions cause CANNOT_BE_ZERO_OR_NEGATIVE when using Vault v3 (2768)
This commit is contained in:
commit
ffe3a0b958
17 changed files with 422 additions and 46 deletions
|
@ -115,7 +115,7 @@ class PaymentMethodTokensEndpoint {
|
||||||
* @throws RuntimeException When something when wrong with the request.
|
* @throws RuntimeException When something when wrong with the request.
|
||||||
* @throws PayPalApiException When something when wrong setting up the token.
|
* @throws PayPalApiException When something when wrong setting up the token.
|
||||||
*/
|
*/
|
||||||
public function payment_tokens( PaymentSource $payment_source ): stdClass {
|
public function create_payment_token( PaymentSource $payment_source ): stdClass {
|
||||||
$data = array(
|
$data = array(
|
||||||
'payment_source' => array(
|
'payment_source' => array(
|
||||||
$payment_source->name() => $payment_source->properties(),
|
$payment_source->name() => $payment_source->properties(),
|
||||||
|
|
|
@ -137,7 +137,12 @@ const bootstrap = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;
|
const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;
|
||||||
if (isFreeTrial && data.fundingSource !== 'card' && ! PayPalCommerceGateway.subscription_plan_id) {
|
if (
|
||||||
|
isFreeTrial
|
||||||
|
&& data.fundingSource !== 'card'
|
||||||
|
&& ! PayPalCommerceGateway.subscription_plan_id
|
||||||
|
&& ! PayPalCommerceGateway.vault_v3_enabled
|
||||||
|
) {
|
||||||
freeTrialHandler.handle();
|
freeTrialHandler.handle();
|
||||||
return actions.reject();
|
return actions.reject();
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,54 @@ class CheckoutActionHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addPaymentMethodConfiguration() {
|
||||||
|
return {
|
||||||
|
createVaultSetupToken: async () => {
|
||||||
|
const response = await fetch(this.config.ajax.create_setup_token.endpoint, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
nonce: this.config.ajax.create_setup_token.nonce,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json()
|
||||||
|
if (result.data.id) {
|
||||||
|
return result.data.id
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(result)
|
||||||
|
},
|
||||||
|
onApprove: async ({vaultSetupToken}) => {
|
||||||
|
const response = await fetch(this.config.ajax.create_payment_token_for_guest.endpoint, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
nonce: this.config.ajax.create_payment_token_for_guest.nonce,
|
||||||
|
vault_setup_token: vaultSetupToken,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
if (result.success === true) {
|
||||||
|
document.querySelector('#place_order').click()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(result)
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CheckoutActionHandler;
|
export default CheckoutActionHandler;
|
||||||
|
|
|
@ -116,6 +116,14 @@ class CheckoutBootstap {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
PayPalCommerceGateway.is_free_trial_cart
|
||||||
|
&& PayPalCommerceGateway.vault_v3_enabled
|
||||||
|
) {
|
||||||
|
this.renderer.render(actionHandler.addPaymentMethodConfiguration(), {}, actionHandler.configuration());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.renderer.render(actionHandler.configuration(), {}, actionHandler.configuration());
|
this.renderer.render(actionHandler.configuration(), {}, actionHandler.configuration());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,8 @@ return array(
|
||||||
$container->get( 'button.early-wc-checkout-validation-enabled' ),
|
$container->get( 'button.early-wc-checkout-validation-enabled' ),
|
||||||
$container->get( 'button.pay-now-contexts' ),
|
$container->get( 'button.pay-now-contexts' ),
|
||||||
$container->get( 'wcgateway.funding-sources-without-redirect' ),
|
$container->get( 'wcgateway.funding-sources-without-redirect' ),
|
||||||
|
$container->get( 'vaulting.vault-v3-enabled' ),
|
||||||
|
$container->get( 'api.endpoint.payment-tokens' ),
|
||||||
$container->get( 'woocommerce.logger.woocommerce' )
|
$container->get( 'woocommerce.logger.woocommerce' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,6 +14,7 @@ use Psr\Log\LoggerInterface;
|
||||||
use WC_Order;
|
use WC_Order;
|
||||||
use WC_Product;
|
use WC_Product;
|
||||||
use WC_Product_Variation;
|
use WC_Product_Variation;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
|
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
|
||||||
|
@ -33,6 +34,9 @@ use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
||||||
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||||
use WooCommerce\PayPalCommerce\PayLaterBlock\PayLaterBlockModule;
|
use WooCommerce\PayPalCommerce\PayLaterBlock\PayLaterBlockModule;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentTokenForGuest;
|
||||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
|
@ -184,13 +188,6 @@ class SmartButton implements SmartButtonInterface {
|
||||||
*/
|
*/
|
||||||
private $funding_sources_without_redirect;
|
private $funding_sources_without_redirect;
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger.
|
|
||||||
*
|
|
||||||
* @var LoggerInterface
|
|
||||||
*/
|
|
||||||
private $logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session handler.
|
* Session handler.
|
||||||
*
|
*
|
||||||
|
@ -198,6 +195,27 @@ class SmartButton implements SmartButtonInterface {
|
||||||
*/
|
*/
|
||||||
private $session_handler;
|
private $session_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Vault v3 module is enabled.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $vault_v3_enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment tokens endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentTokensEndpoint
|
||||||
|
*/
|
||||||
|
private $payment_tokens_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SmartButton constructor.
|
* SmartButton constructor.
|
||||||
*
|
*
|
||||||
|
@ -220,6 +238,8 @@ class SmartButton implements SmartButtonInterface {
|
||||||
* @param bool $early_validation_enabled Whether to execute WC validation of the checkout form.
|
* @param bool $early_validation_enabled Whether to execute WC validation of the checkout form.
|
||||||
* @param array $pay_now_contexts The contexts that should have the Pay Now button.
|
* @param array $pay_now_contexts The contexts that should have the Pay Now button.
|
||||||
* @param string[] $funding_sources_without_redirect The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back.
|
* @param string[] $funding_sources_without_redirect The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back.
|
||||||
|
* @param bool $vault_v3_enabled Whether Vault v3 module is enabled.
|
||||||
|
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
|
||||||
* @param LoggerInterface $logger The logger.
|
* @param LoggerInterface $logger The logger.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
@ -242,6 +262,8 @@ class SmartButton implements SmartButtonInterface {
|
||||||
bool $early_validation_enabled,
|
bool $early_validation_enabled,
|
||||||
array $pay_now_contexts,
|
array $pay_now_contexts,
|
||||||
array $funding_sources_without_redirect,
|
array $funding_sources_without_redirect,
|
||||||
|
bool $vault_v3_enabled,
|
||||||
|
PaymentTokensEndpoint $payment_tokens_endpoint,
|
||||||
LoggerInterface $logger
|
LoggerInterface $logger
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -264,7 +286,9 @@ class SmartButton implements SmartButtonInterface {
|
||||||
$this->early_validation_enabled = $early_validation_enabled;
|
$this->early_validation_enabled = $early_validation_enabled;
|
||||||
$this->pay_now_contexts = $pay_now_contexts;
|
$this->pay_now_contexts = $pay_now_contexts;
|
||||||
$this->funding_sources_without_redirect = $funding_sources_without_redirect;
|
$this->funding_sources_without_redirect = $funding_sources_without_redirect;
|
||||||
|
$this->vault_v3_enabled = $vault_v3_enabled;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1035,44 +1059,57 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
'redirect' => wc_get_checkout_url(),
|
'redirect' => wc_get_checkout_url(),
|
||||||
'context' => $this->context(),
|
'context' => $this->context(),
|
||||||
'ajax' => array(
|
'ajax' => array(
|
||||||
'simulate_cart' => array(
|
'simulate_cart' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( SimulateCartEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( SimulateCartEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( SimulateCartEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( SimulateCartEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'change_cart' => array(
|
'change_cart' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( ChangeCartEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( ChangeCartEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( ChangeCartEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( ChangeCartEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'create_order' => array(
|
'create_order' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( CreateOrderEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( CreateOrderEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( CreateOrderEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( CreateOrderEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'approve_order' => array(
|
'approve_order' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( ApproveOrderEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( ApproveOrderEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( ApproveOrderEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( ApproveOrderEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'approve_subscription' => array(
|
'approve_subscription' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( ApproveSubscriptionEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( ApproveSubscriptionEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( ApproveSubscriptionEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( ApproveSubscriptionEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'vault_paypal' => array(
|
'vault_paypal' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( StartPayPalVaultingEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( StartPayPalVaultingEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( StartPayPalVaultingEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( StartPayPalVaultingEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'save_checkout_form' => array(
|
'save_checkout_form' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( SaveCheckoutFormEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( SaveCheckoutFormEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( SaveCheckoutFormEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( SaveCheckoutFormEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'validate_checkout' => array(
|
'validate_checkout' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( ValidateCheckoutEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( ValidateCheckoutEndpoint::ENDPOINT ),
|
||||||
'nonce' => wp_create_nonce( ValidateCheckoutEndpoint::nonce() ),
|
'nonce' => wp_create_nonce( ValidateCheckoutEndpoint::nonce() ),
|
||||||
),
|
),
|
||||||
'cart_script_params' => array(
|
'cart_script_params' => array(
|
||||||
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
|
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
|
||||||
),
|
),
|
||||||
|
'create_setup_token' => array(
|
||||||
|
'endpoint' => \WC_AJAX::get_endpoint( CreateSetupToken::ENDPOINT ),
|
||||||
|
'nonce' => wp_create_nonce( CreateSetupToken::nonce() ),
|
||||||
|
),
|
||||||
|
'create_payment_token' => array(
|
||||||
|
'endpoint' => \WC_AJAX::get_endpoint( CreatePaymentToken::ENDPOINT ),
|
||||||
|
'nonce' => wp_create_nonce( CreatePaymentToken::nonce() ),
|
||||||
|
),
|
||||||
|
'create_payment_token_for_guest' => array(
|
||||||
|
'endpoint' => \WC_AJAX::get_endpoint( CreatePaymentTokenForGuest::ENDPOINT ),
|
||||||
|
'nonce' => wp_create_nonce( CreatePaymentTokenForGuest::nonce() ),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
'cart_contains_subscription' => $this->subscription_helper->cart_contains_subscription(),
|
'cart_contains_subscription' => $this->subscription_helper->cart_contains_subscription(),
|
||||||
'subscription_plan_id' => $this->subscription_helper->paypal_subscription_id(),
|
'subscription_plan_id' => $this->subscription_helper->paypal_subscription_id(),
|
||||||
|
'vault_v3_enabled' => $this->vault_v3_enabled,
|
||||||
'variable_paypal_subscription_variations' => $this->subscription_helper->variable_paypal_subscription_variations(),
|
'variable_paypal_subscription_variations' => $this->subscription_helper->variable_paypal_subscription_variations(),
|
||||||
'subscription_product_allowed' => $this->subscription_helper->checkout_subscription_product_allowed(),
|
'subscription_product_allowed' => $this->subscription_helper->checkout_subscription_product_allowed(),
|
||||||
'locations_with_subscription_product' => $this->subscription_helper->locations_with_subscription_product(),
|
'locations_with_subscription_product' => $this->subscription_helper->locations_with_subscription_product(),
|
||||||
|
@ -1904,8 +1941,18 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
*/
|
*/
|
||||||
private function get_vaulted_paypal_email(): string {
|
private function get_vaulted_paypal_email(): string {
|
||||||
try {
|
try {
|
||||||
$tokens = $this->get_payment_tokens();
|
$customer_id = get_user_meta( get_current_user_id(), '_ppcp_target_customer_id', true );
|
||||||
|
if ( $customer_id ) {
|
||||||
|
$customer_tokens = $this->payment_tokens_endpoint->payment_tokens_for_customer( $customer_id );
|
||||||
|
foreach ( $customer_tokens as $token ) {
|
||||||
|
$email_address = $token['payment_source']->properties()->email_address ?? '';
|
||||||
|
if ( $email_address ) {
|
||||||
|
return $email_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tokens = $this->get_payment_tokens();
|
||||||
foreach ( $tokens as $token ) {
|
foreach ( $tokens as $token ) {
|
||||||
if ( isset( $token->source()->paypal ) ) {
|
if ( isset( $token->source()->paypal ) ) {
|
||||||
return $token->source()->paypal->payer->email_address;
|
return $token->source()->paypal->payer->email_address;
|
||||||
|
@ -1914,6 +1961,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
} catch ( Exception $exception ) {
|
} catch ( Exception $exception ) {
|
||||||
$this->logger->error( 'Failed to get PayPal vaulted email. ' . $exception->getMessage() );
|
$this->logger->error( 'Failed to get PayPal vaulted email. ' . $exception->getMessage() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import ErrorHandler from "../../../ppcp-button/resources/js/modules/ErrorHandler
|
||||||
import {cardFieldStyles} from "../../../ppcp-button/resources/js/modules/Helper/CardFieldsHelper";
|
import {cardFieldStyles} from "../../../ppcp-button/resources/js/modules/Helper/CardFieldsHelper";
|
||||||
|
|
||||||
const errorHandler = new ErrorHandler(
|
const errorHandler = new ErrorHandler(
|
||||||
PayPalCommerceGateway.labels.error.generic,
|
ppcp_add_payment_method.labels.error.generic,
|
||||||
document.querySelector('.woocommerce-notices-wrapper')
|
document.querySelector('.woocommerce-notices-wrapper')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\SavePaymentMethods;
|
||||||
|
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentTokenForGuest;
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Helper\SavePaymentMethodsApplies;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Helper\SavePaymentMethodsApplies;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
@ -811,4 +812,10 @@ return array(
|
||||||
$container->get( 'vaulting.wc-payment-tokens' )
|
$container->get( 'vaulting.wc-payment-tokens' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
'save-payment-methods.endpoint.create-payment-token-for-guest' => static function ( ContainerInterface $container ): CreatePaymentTokenForGuest {
|
||||||
|
return new CreatePaymentTokenForGuest(
|
||||||
|
$container->get( 'button.request-data' ),
|
||||||
|
$container->get( 'api.endpoint.payment-method-tokens' )
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -94,7 +94,7 @@ class CreatePaymentToken implements EndpointInterface {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$result = $this->payment_method_tokens_endpoint->payment_tokens( $payment_source );
|
$result = $this->payment_method_tokens_endpoint->create_payment_token( $payment_source );
|
||||||
|
|
||||||
if ( is_user_logged_in() && isset( $result->customer->id ) ) {
|
if ( is_user_logged_in() && isset( $result->customer->id ) ) {
|
||||||
$current_user_id = get_current_user_id();
|
$current_user_id = get_current_user_id();
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Create payment token for guest user.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentMethodTokensEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||||
|
use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UpdateCustomerId
|
||||||
|
*/
|
||||||
|
class CreatePaymentTokenForGuest implements EndpointInterface {
|
||||||
|
|
||||||
|
const ENDPOINT = 'ppc-update-customer-id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request data.
|
||||||
|
*
|
||||||
|
* @var RequestData
|
||||||
|
*/
|
||||||
|
private $request_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The payment method tokens endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentMethodTokensEndpoint
|
||||||
|
*/
|
||||||
|
private $payment_method_tokens_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreatePaymentToken constructor.
|
||||||
|
*
|
||||||
|
* @param RequestData $request_data The request data.
|
||||||
|
* @param PaymentMethodTokensEndpoint $payment_method_tokens_endpoint The payment method tokens endpoint.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
RequestData $request_data,
|
||||||
|
PaymentMethodTokensEndpoint $payment_method_tokens_endpoint
|
||||||
|
) {
|
||||||
|
$this->request_data = $request_data;
|
||||||
|
$this->payment_method_tokens_endpoint = $payment_method_tokens_endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nonce.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function nonce(): string {
|
||||||
|
return self::ENDPOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @throws Exception On Error.
|
||||||
|
*/
|
||||||
|
public function handle_request(): bool {
|
||||||
|
$data = $this->request_data->read_request( $this->nonce() );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppress ArgumentTypeCoercion
|
||||||
|
*
|
||||||
|
* @psalm-suppress ArgumentTypeCoercion
|
||||||
|
*/
|
||||||
|
$payment_source = new PaymentSource(
|
||||||
|
'token',
|
||||||
|
(object) array(
|
||||||
|
'id' => $data['vault_setup_token'],
|
||||||
|
'type' => 'SETUP_TOKEN',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $this->payment_method_tokens_endpoint->create_payment_token( $payment_source );
|
||||||
|
WC()->session->set( 'ppcp_guest_payment_for_free_trial', $result );
|
||||||
|
|
||||||
|
wp_send_json_success();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||||
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentToken;
|
||||||
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreatePaymentTokenForGuest;
|
||||||
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
use WooCommerce\PayPalCommerce\SavePaymentMethods\Endpoint\CreateSetupToken;
|
||||||
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
|
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||||
|
@ -316,6 +317,14 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
'nonce' => wp_create_nonce( SubscriptionChangePaymentMethod::nonce() ),
|
'nonce' => wp_create_nonce( SubscriptionChangePaymentMethod::nonce() ),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
'labels' => array(
|
||||||
|
'error' => array(
|
||||||
|
'generic' => __(
|
||||||
|
'Something went wrong. Please try again or choose another payment source.',
|
||||||
|
'woocommerce-paypal-payments'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch ( RuntimeException $exception ) {
|
} catch ( RuntimeException $exception ) {
|
||||||
|
@ -363,6 +372,16 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_action(
|
||||||
|
'wc_ajax_' . CreatePaymentTokenForGuest::ENDPOINT,
|
||||||
|
static function () use ( $c ) {
|
||||||
|
$endpoint = $c->get( 'save-payment-methods.endpoint.create-payment-token-for-guest' );
|
||||||
|
assert( $endpoint instanceof CreatePaymentTokenForGuest );
|
||||||
|
|
||||||
|
$endpoint->handle_request();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
add_action(
|
add_action(
|
||||||
'woocommerce_paypal_payments_before_delete_payment_token',
|
'woocommerce_paypal_payments_before_delete_payment_token',
|
||||||
function( string $token_id ) use ( $c ) {
|
function( string $token_id ) use ( $c ) {
|
||||||
|
|
|
@ -64,4 +64,7 @@ return array(
|
||||||
$container->get( 'woocommerce.logger.woocommerce' )
|
$container->get( 'woocommerce.logger.woocommerce' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
'vaulting.vault-v3-enabled' => static function( ContainerInterface $container ): bool {
|
||||||
|
return $container->has( 'save-payment-methods.eligible' ) && $container->get( 'save-payment-methods.eligible' );
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -103,7 +103,10 @@ return array(
|
||||||
$api_shop_country,
|
$api_shop_country,
|
||||||
$container->get( 'api.endpoint.order' ),
|
$container->get( 'api.endpoint.order' ),
|
||||||
$container->get( 'api.factory.paypal-checkout-url' ),
|
$container->get( 'api.factory.paypal-checkout-url' ),
|
||||||
$container->get( 'wcgateway.place-order-button-text' )
|
$container->get( 'wcgateway.place-order-button-text' ),
|
||||||
|
$container->get( 'api.endpoint.payment-tokens' ),
|
||||||
|
$container->get( 'vaulting.vault-v3-enabled' ),
|
||||||
|
$container->get( 'vaulting.wc-payment-tokens' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
|
'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
|
||||||
|
|
|
@ -33,6 +33,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
|
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||||
|
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,7 +41,7 @@ use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
*/
|
*/
|
||||||
class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
|
|
||||||
use ProcessPaymentTrait, GatewaySettingsRendererTrait, TransactionIdHandlingTrait, PaymentsStatusHandlingTrait;
|
use ProcessPaymentTrait, GatewaySettingsRendererTrait, TransactionIdHandlingTrait, PaymentsStatusHandlingTrait, FreeTrialHandlerTrait;
|
||||||
|
|
||||||
const ID = 'ppcp-credit-card-gateway';
|
const ID = 'ppcp-credit-card-gateway';
|
||||||
|
|
||||||
|
@ -454,6 +455,17 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
||||||
|
|
||||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||||
$card_payment_token_id = wc_clean( wp_unslash( $_POST['wc-ppcp-credit-card-gateway-payment-token'] ?? '' ) );
|
$card_payment_token_id = wc_clean( wp_unslash( $_POST['wc-ppcp-credit-card-gateway-payment-token'] ?? '' ) );
|
||||||
|
|
||||||
|
if ( $this->is_free_trial_order( $wc_order ) && $card_payment_token_id ) {
|
||||||
|
$customer_tokens = $this->wc_payment_tokens->customer_tokens( get_current_user_id() );
|
||||||
|
foreach ( $customer_tokens as $token ) {
|
||||||
|
if ( $token['payment_source']->name() === 'card' ) {
|
||||||
|
$wc_order->payment_complete();
|
||||||
|
return $this->handle_payment_success( $wc_order );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( $card_payment_token_id ) {
|
if ( $card_payment_token_id ) {
|
||||||
$customer_tokens = $this->wc_payment_tokens->customer_tokens( get_current_user_id() );
|
$customer_tokens = $this->wc_payment_tokens->customer_tokens( get_current_user_id() );
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,14 @@ use Psr\Log\LoggerInterface;
|
||||||
use WC_Order;
|
use WC_Order;
|
||||||
use WC_Payment_Tokens;
|
use WC_Payment_Tokens;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||||
|
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
||||||
|
@ -179,26 +181,50 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
*/
|
*/
|
||||||
private $paypal_checkout_url_factory;
|
private $paypal_checkout_url_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment tokens endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentTokensEndpoint
|
||||||
|
*/
|
||||||
|
private $payment_tokens_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Vault v3 module is enabled.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $vault_v3_enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WooCommerce payment tokens.
|
||||||
|
*
|
||||||
|
* @var WooCommercePaymentTokens
|
||||||
|
*/
|
||||||
|
private $wc_payment_tokens;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PayPalGateway constructor.
|
* PayPalGateway constructor.
|
||||||
*
|
*
|
||||||
* @param SettingsRenderer $settings_renderer The Settings Renderer.
|
* @param SettingsRenderer $settings_renderer The Settings Renderer.
|
||||||
* @param FundingSourceRenderer $funding_source_renderer The funding source renderer.
|
* @param FundingSourceRenderer $funding_source_renderer The funding source renderer.
|
||||||
* @param OrderProcessor $order_processor The Order Processor.
|
* @param OrderProcessor $order_processor The Order Processor.
|
||||||
* @param ContainerInterface $config The settings.
|
* @param ContainerInterface $config The settings.
|
||||||
* @param SessionHandler $session_handler The Session Handler.
|
* @param SessionHandler $session_handler The Session Handler.
|
||||||
* @param RefundProcessor $refund_processor The Refund Processor.
|
* @param RefundProcessor $refund_processor The Refund Processor.
|
||||||
* @param State $state The state.
|
* @param State $state The state.
|
||||||
* @param TransactionUrlProvider $transaction_url_provider Service providing transaction view URL based on order.
|
* @param TransactionUrlProvider $transaction_url_provider Service providing transaction view URL based on order.
|
||||||
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
||||||
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
||||||
* @param Environment $environment The environment.
|
* @param Environment $environment The environment.
|
||||||
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
|
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
|
||||||
* @param LoggerInterface $logger The logger.
|
* @param LoggerInterface $logger The logger.
|
||||||
* @param string $api_shop_country The api shop country.
|
* @param string $api_shop_country The api shop country.
|
||||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||||
* @param callable(string):string $paypal_checkout_url_factory The function return the PayPal checkout URL for the given order ID.
|
* @param callable(string):string $paypal_checkout_url_factory The function return the PayPal checkout URL for the given order ID.
|
||||||
* @param string $place_order_button_text The text for the standard "Place order" button.
|
* @param string $place_order_button_text The text for the standard "Place order" button.
|
||||||
|
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
|
||||||
|
* @param bool $vault_v3_enabled Whether Vault v3 module is enabled.
|
||||||
|
* @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SettingsRenderer $settings_renderer,
|
SettingsRenderer $settings_renderer,
|
||||||
|
@ -217,7 +243,10 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
string $api_shop_country,
|
string $api_shop_country,
|
||||||
OrderEndpoint $order_endpoint,
|
OrderEndpoint $order_endpoint,
|
||||||
callable $paypal_checkout_url_factory,
|
callable $paypal_checkout_url_factory,
|
||||||
string $place_order_button_text
|
string $place_order_button_text,
|
||||||
|
PaymentTokensEndpoint $payment_tokens_endpoint,
|
||||||
|
bool $vault_v3_enabled,
|
||||||
|
WooCommercePaymentTokens $wc_payment_tokens
|
||||||
) {
|
) {
|
||||||
$this->id = self::ID;
|
$this->id = self::ID;
|
||||||
$this->settings_renderer = $settings_renderer;
|
$this->settings_renderer = $settings_renderer;
|
||||||
|
@ -237,6 +266,10 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
$this->api_shop_country = $api_shop_country;
|
$this->api_shop_country = $api_shop_country;
|
||||||
$this->paypal_checkout_url_factory = $paypal_checkout_url_factory;
|
$this->paypal_checkout_url_factory = $paypal_checkout_url_factory;
|
||||||
$this->order_button_text = $place_order_button_text;
|
$this->order_button_text = $place_order_button_text;
|
||||||
|
$this->order_endpoint = $order_endpoint;
|
||||||
|
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
|
||||||
|
$this->vault_v3_enabled = $vault_v3_enabled;
|
||||||
|
$this->wc_payment_tokens = $wc_payment_tokens;
|
||||||
|
|
||||||
if ( $this->onboarded ) {
|
if ( $this->onboarded ) {
|
||||||
$this->supports = array( 'refunds', 'tokenization' );
|
$this->supports = array( 'refunds', 'tokenization' );
|
||||||
|
@ -299,8 +332,6 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
'process_admin_options',
|
'process_admin_options',
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->order_endpoint = $order_endpoint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -500,7 +531,49 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
$wc_order->save();
|
$wc_order->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'card' !== $funding_source && $this->is_free_trial_order( $wc_order ) && ! $this->subscription_helper->paypal_subscription_id() ) {
|
if (
|
||||||
|
'card' !== $funding_source
|
||||||
|
&& $this->is_free_trial_order( $wc_order )
|
||||||
|
&& ! $this->subscription_helper->paypal_subscription_id()
|
||||||
|
) {
|
||||||
|
$ppcp_guest_payment_for_free_trial = WC()->session->get( 'ppcp_guest_payment_for_free_trial' ) ?? null;
|
||||||
|
if ( $this->vault_v3_enabled && $ppcp_guest_payment_for_free_trial ) {
|
||||||
|
$customer_id = $ppcp_guest_payment_for_free_trial->customer->id ?? '';
|
||||||
|
if ( $customer_id ) {
|
||||||
|
update_user_meta( $wc_order->get_customer_id(), '_ppcp_target_customer_id', $customer_id );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $ppcp_guest_payment_for_free_trial->payment_source->paypal ) ) {
|
||||||
|
$email = '';
|
||||||
|
if ( isset( $ppcp_guest_payment_for_free_trial->payment_source->paypal->email_address ) ) {
|
||||||
|
$email = $ppcp_guest_payment_for_free_trial->payment_source->paypal->email_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->wc_payment_tokens->create_payment_token_paypal(
|
||||||
|
$wc_order->get_customer_id(),
|
||||||
|
$ppcp_guest_payment_for_free_trial->id,
|
||||||
|
$email
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
WC()->session->set( 'ppcp_guest_payment_for_free_trial', null );
|
||||||
|
|
||||||
|
$wc_order->payment_complete();
|
||||||
|
return $this->handle_payment_success( $wc_order );
|
||||||
|
}
|
||||||
|
|
||||||
|
$customer_id = get_user_meta( $wc_order->get_customer_id(), '_ppcp_target_customer_id', true );
|
||||||
|
if ( $customer_id ) {
|
||||||
|
$customer_tokens = $this->payment_tokens_endpoint->payment_tokens_for_customer( $customer_id );
|
||||||
|
foreach ( $customer_tokens as $token ) {
|
||||||
|
$payment_source_name = $token['payment_source']->name() ?? '';
|
||||||
|
if ( $payment_source_name === 'paypal' || $payment_source_name === 'venmo' ) {
|
||||||
|
$wc_order->payment_complete();
|
||||||
|
return $this->handle_payment_success( $wc_order );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$user_id = (int) $wc_order->get_customer_id();
|
$user_id = (int) $wc_order->get_customer_id();
|
||||||
$tokens = $this->payment_token_repository->all_for_user_id( $user_id );
|
$tokens = $this->payment_token_repository->all_for_user_id( $user_id );
|
||||||
if ( ! array_filter(
|
if ( ! array_filter(
|
||||||
|
@ -513,7 +586,6 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
}
|
}
|
||||||
|
|
||||||
$wc_order->payment_complete();
|
$wc_order->payment_complete();
|
||||||
|
|
||||||
return $this->handle_payment_success( $wc_order );
|
return $this->handle_payment_success( $wc_order );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,13 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||||
|
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
|
||||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||||
use WooCommerce\PayPalCommerce\TestCase;
|
use WooCommerce\PayPalCommerce\TestCase;
|
||||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
||||||
|
@ -44,6 +46,9 @@ class WcGatewayTest extends TestCase
|
||||||
private $logger;
|
private $logger;
|
||||||
private $apiShopCountry;
|
private $apiShopCountry;
|
||||||
private $orderEndpoint;
|
private $orderEndpoint;
|
||||||
|
private $paymentTokensEndpoint;
|
||||||
|
private $vaultV3Enabled;
|
||||||
|
private $wcPaymentTokens;
|
||||||
|
|
||||||
public function setUp(): void {
|
public function setUp(): void {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
@ -88,6 +93,10 @@ class WcGatewayTest extends TestCase
|
||||||
|
|
||||||
$this->logger->shouldReceive('info');
|
$this->logger->shouldReceive('info');
|
||||||
$this->logger->shouldReceive('error');
|
$this->logger->shouldReceive('error');
|
||||||
|
|
||||||
|
$this->paymentTokensEndpoint = Mockery::mock(PaymentTokensEndpoint::class);
|
||||||
|
$this->vaultV3Enabled = true;
|
||||||
|
$this->wcPaymentTokens = Mockery::mock(WooCommercePaymentTokens::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createGateway()
|
private function createGateway()
|
||||||
|
@ -111,7 +120,10 @@ class WcGatewayTest extends TestCase
|
||||||
function ($id) {
|
function ($id) {
|
||||||
return 'checkoutnow=' . $id;
|
return 'checkoutnow=' . $id;
|
||||||
},
|
},
|
||||||
'Pay via PayPal'
|
'Pay via PayPal',
|
||||||
|
$this->paymentTokensEndpoint,
|
||||||
|
$this->vaultV3Enabled,
|
||||||
|
$this->wcPaymentTokens
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,53 @@ test('Save during purchase', async ({page}) => {
|
||||||
await expectOrderReceivedPage(page);
|
await expectOrderReceivedPage(page);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('PayPal add payment method', async ({page}) => {
|
||||||
|
await loginAsCustomer(page);
|
||||||
|
await page.goto('/my-account/add-payment-method');
|
||||||
|
|
||||||
|
const popup = await openPaypalPopup(page);
|
||||||
|
await loginIntoPaypal(popup);
|
||||||
|
popup.locator('#consentButton').click();
|
||||||
|
|
||||||
|
await page.waitForURL('/my-account/payment-methods');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ACDC add payment method', async ({page}) => {
|
||||||
|
await loginAsCustomer(page);
|
||||||
|
await page.goto('/my-account/add-payment-method');
|
||||||
|
|
||||||
|
await page.click("text=Debit & Credit Cards");
|
||||||
|
|
||||||
|
const creditCardNumber = await page.frameLocator('[title="paypal_card_number_field"]').locator('.card-field-number');
|
||||||
|
await creditCardNumber.fill('4005519200000004');
|
||||||
|
|
||||||
|
const expirationDate = await page.frameLocator('[title="paypal_card_expiry_field"]').locator('.card-field-expiry');
|
||||||
|
await expirationDate.fill('01/25');
|
||||||
|
|
||||||
|
const cvv = await page.frameLocator('[title="paypal_card_cvv_field"]').locator('.card-field-cvv');
|
||||||
|
await cvv.fill('123');
|
||||||
|
|
||||||
|
await page.waitForURL('/my-account/payment-methods');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('PayPal logged-in user free trial subscription without payment token', async ({page}) => {
|
||||||
|
await loginAsCustomer(page);
|
||||||
|
|
||||||
|
await page.goto('/shop');
|
||||||
|
await page.click("text=Sign up now");
|
||||||
|
await page.goto('/classic-checkout');
|
||||||
|
|
||||||
|
const popup = await openPaypalPopup(page);
|
||||||
|
await loginIntoPaypal(popup);
|
||||||
|
popup.locator('#consentButton').click();
|
||||||
|
|
||||||
|
await page.click("text=Proceed to PayPal");
|
||||||
|
|
||||||
|
const title = await page.locator('.entry-title');
|
||||||
|
await expect(title).toHaveText('Order received');
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue