mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-04 08:47:23 +08:00
Merge pull request #1711 from woocommerce/PCP-2030-remove-payment-vaulted-checker
Remove payment vaulted checker functionality (2030)
This commit is contained in:
commit
31f726155f
23 changed files with 344 additions and 2500 deletions
|
@ -11,6 +11,9 @@ if (!defined('MONTH_IN_SECONDS')) {
|
|||
if (!defined('HOUR_IN_SECONDS')) {
|
||||
define('HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS);
|
||||
}
|
||||
if (!defined('MINUTE_IN_SECONDS')) {
|
||||
define( 'MINUTE_IN_SECONDS', 60 );
|
||||
}
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
define('ABSPATH', '');
|
||||
|
@ -32,6 +35,17 @@ if (!defined('ABSPATH')) {
|
|||
*
|
||||
* @return string|null The scheduled action ID if a scheduled action was found, or null if no matching action found.
|
||||
*/
|
||||
function as_unschedule_action($hook, $args = array(), $group = '')
|
||||
{
|
||||
}
|
||||
function as_unschedule_action($hook, $args = array(), $group = '') {}
|
||||
|
||||
/**
|
||||
* Schedule an action to run one time
|
||||
*
|
||||
* @param int $timestamp When the job will run.
|
||||
* @param string $hook The hook to trigger.
|
||||
* @param array $args Arguments to pass when the hook triggers.
|
||||
* @param string $group The group to assign this job to.
|
||||
* @param bool $unique Whether the action should be unique.
|
||||
*
|
||||
* @return int The action ID.
|
||||
*/
|
||||
function as_schedule_single_action( $timestamp, $hook, $args = array(), $group = '', $unique = false ) {}
|
||||
|
|
|
@ -44,5 +44,13 @@ return function ( string $root_dir ): iterable {
|
|||
$modules[] = ( require "$modules_dir/ppcp-googlepay/module.php" )();
|
||||
}
|
||||
|
||||
if ( apply_filters(
|
||||
//phpcs:disable WordPress.NamingConventions.ValidHookName.UseUnderscores
|
||||
'woocommerce.deprecated_flags.woocommerce_paypal_payments.saved_payment_checker_enabled',
|
||||
getenv( 'PCP_SAVED_PAYMENT_CHECKER_ENABLED' ) === '1'
|
||||
) ) {
|
||||
$modules[] = ( require "$modules_dir/ppcp-saved-payment-checker/module.php" )();
|
||||
}
|
||||
|
||||
return $modules;
|
||||
};
|
||||
|
|
|
@ -194,7 +194,7 @@ class OrderEndpoint {
|
|||
): Order {
|
||||
$bearer = $this->bearer->bearer();
|
||||
$data = array(
|
||||
'intent' => ( $this->subscription_helper->cart_contains_subscription() || $this->subscription_helper->current_product_is_subscription() ) ? 'AUTHORIZE' : $this->intent,
|
||||
'intent' => apply_filters( 'woocommerce_paypal_payments_order_intent', $this->intent ),
|
||||
'purchase_units' => array_map(
|
||||
static function ( PurchaseUnit $item ) use ( $shipping_preference ): array {
|
||||
$data = $item->to_array();
|
||||
|
|
|
@ -1547,16 +1547,14 @@ class SmartButton implements SmartButtonInterface {
|
|||
* @throws NotFoundException If intent is not found.
|
||||
*/
|
||||
private function intent(): string {
|
||||
$intent = ( $this->settings->has( 'intent' ) ) ? $this->settings->get( 'intent' ) : 'capture';
|
||||
$product_intent = $this->subscription_helper->current_product_is_subscription() ? 'authorize' : $intent;
|
||||
$other_context_intent = $this->subscription_helper->cart_contains_subscription() ? 'authorize' : $intent;
|
||||
|
||||
$subscription_mode = $this->settings->has( 'subscriptions_mode' ) ? $this->settings->get( 'subscriptions_mode' ) : '';
|
||||
if ( $this->subscription_helper->need_subscription_intent( $subscription_mode ) ) {
|
||||
return 'subscription';
|
||||
}
|
||||
|
||||
return $this->context() === 'product' ? $product_intent : $other_context_intent;
|
||||
$intent = $this->settings->has( 'intent' ) ? $this->settings->get( 'intent' ) : 'capture';
|
||||
|
||||
return strtolower( apply_filters( 'woocommerce_paypal_payments_order_intent', $intent ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
3
modules/ppcp-saved-payment-checker/.gitignore
vendored
Normal file
3
modules/ppcp-saved-payment-checker/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
assets/js
|
||||
assets/css
|
17
modules/ppcp-saved-payment-checker/composer.json
Normal file
17
modules/ppcp-saved-payment-checker/composer.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "woocommerce/ppcp-saved-payment-checker",
|
||||
"type": "dhii-mod",
|
||||
"description": "Saved payments checker module",
|
||||
"license": "GPL-2.0",
|
||||
"require": {
|
||||
"php": "^7.2 | ^8.0",
|
||||
"dhii/module-interface": "^0.3.0-alpha1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"WooCommerce\\PayPalCommerce\\SavedPaymentChecker\\": "src"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
56
modules/ppcp-saved-payment-checker/extensions.php
Normal file
56
modules/ppcp-saved-payment-checker/extensions.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
/**
|
||||
* The SavedPaymentChecker module extensions.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\SavedPaymentChecker
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\SavedPaymentChecker;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
|
||||
return array(
|
||||
'wcgateway.settings.fields' => function ( ContainerInterface $container, array $fields ): array {
|
||||
$subscription_helper = $container->get( 'subscription.helper' );
|
||||
assert( $subscription_helper instanceof SubscriptionHelper );
|
||||
|
||||
$insert_after = function( array $array, string $key, array $new ): array {
|
||||
$keys = array_keys( $array );
|
||||
$index = array_search( $key, $keys, true );
|
||||
$pos = false === $index ? count( $array ) : $index + 1;
|
||||
|
||||
return array_merge( array_slice( $array, 0, $pos ), $new, array_slice( $array, $pos ) );
|
||||
};
|
||||
|
||||
return $insert_after(
|
||||
$fields,
|
||||
'vault_enabled',
|
||||
array(
|
||||
'subscription_behavior_when_vault_fails' => array(
|
||||
'title' => __( 'Subscription capture behavior if Vault fails', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'classes' => $subscription_helper->plugin_is_active() ? array() : array( 'hide' ),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'void_auth',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'By default, subscription payments are captured only when saving the payment method was successful. Without a saved payment method, automatic renewal payments are not possible.', 'woocommerce-paypal-payments' ),
|
||||
'description_with_tip' => __( 'Determines whether authorized payments for subscription orders are captured or voided if there is no saved payment method. This only applies when the intent Capture is used for the subscription order.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'void_auth' => __( 'Void authorization & fail the order/subscription', 'woocommerce-paypal-payments' ),
|
||||
'capture_auth' => __( 'Capture authorized payment & set subscription to Manual Renewal', 'woocommerce-paypal-payments' ),
|
||||
'capture_auth_ignore' => __( 'Capture authorized payment & disregard missing payment method', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => array( 'paypal' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
},
|
||||
);
|
16
modules/ppcp-saved-payment-checker/module.php
Normal file
16
modules/ppcp-saved-payment-checker/module.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* The SavedPaymentChecker module.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\SavedPaymentChecker
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\SavedPaymentChecker;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||
|
||||
return static function (): ModuleInterface {
|
||||
return new SavedPaymentCheckerModule();
|
||||
};
|
26
modules/ppcp-saved-payment-checker/services.php
Normal file
26
modules/ppcp-saved-payment-checker/services.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* The SavedPaymentChecker module services.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\SavedPaymentChecker
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\SavedPaymentChecker;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
|
||||
return array(
|
||||
'saved-payment-checker.payment-token-checker' => function( ContainerInterface $container ) : PaymentTokenChecker {
|
||||
return new PaymentTokenChecker(
|
||||
$container->get( 'vaulting.repository.payment-token' ),
|
||||
$container->get( 'api.repository.order' ),
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'wcgateway.processor.authorized-payments' ),
|
||||
$container->get( 'api.endpoint.payments' ),
|
||||
$container->get( 'api.endpoint.payment-token' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
);
|
|
@ -7,17 +7,17 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Vaulting;
|
||||
namespace WooCommerce\PayPalCommerce\SavedPaymentChecker;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use RuntimeException;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\OrderRepository;
|
||||
use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait;
|
||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
|
@ -203,6 +203,32 @@ class PaymentTokenChecker {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules the vaulted payment check.
|
||||
*
|
||||
* @param int $wc_order_id The WC order ID.
|
||||
* @param int $customer_id The customer ID.
|
||||
*/
|
||||
public function schedule_saved_payment_check( int $wc_order_id, int $customer_id ): void {
|
||||
$timestamp = 3 * MINUTE_IN_SECONDS;
|
||||
if (
|
||||
$this->settings->has( 'subscription_behavior_when_vault_fails' )
|
||||
&& $this->settings->get( 'subscription_behavior_when_vault_fails' ) === 'capture_auth'
|
||||
) {
|
||||
$timestamp = 0;
|
||||
}
|
||||
|
||||
as_schedule_single_action(
|
||||
time() + $timestamp,
|
||||
'woocommerce_paypal_payments_check_saved_payment',
|
||||
array(
|
||||
'order_id' => $wc_order_id,
|
||||
'customer_id' => $customer_id,
|
||||
'intent' => $this->settings->has( 'intent' ) ? $this->settings->get( 'intent' ) : '',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures authorized payments for the given WC order.
|
||||
*
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
/**
|
||||
* The SavedPaymentChecker module.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\SavedPaymentChecker
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\SavedPaymentChecker;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class SavedPaymentCheckerModule
|
||||
*/
|
||||
class SavedPaymentCheckerModule implements ModuleInterface {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setup(): ServiceProviderInterface {
|
||||
return new ServiceProvider(
|
||||
require __DIR__ . '/../services.php',
|
||||
require __DIR__ . '/../extensions.php'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function run( ContainerInterface $c ): void {
|
||||
|
||||
/**
|
||||
* Set authorize intent for vaulted subscriptions, so we can void if payment not saved.
|
||||
*/
|
||||
add_filter(
|
||||
'woocommerce_paypal_payments_order_intent',
|
||||
function( string $intent ) use ( $c ) {
|
||||
$subscription_helper = $c->get( 'subscription.helper' );
|
||||
assert( $subscription_helper instanceof SubscriptionHelper );
|
||||
|
||||
if ( $subscription_helper->cart_contains_subscription() || $subscription_helper->current_product_is_subscription() ) {
|
||||
return 'AUTHORIZE';
|
||||
}
|
||||
|
||||
return $intent;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Schedules saved payment checker before payment success handler.
|
||||
*/
|
||||
add_action(
|
||||
'woocommerce_paypal_payments_before_handle_payment_success',
|
||||
function( WC_Order $wc_order ) use ( $c ) {
|
||||
$subscription_helper = $c->get( 'subscription.helper' );
|
||||
assert( $subscription_helper instanceof SubscriptionHelper );
|
||||
|
||||
if ( $subscription_helper->has_subscription( $wc_order->get_id() ) ) {
|
||||
$payment_token_checker = $c->get( 'saved-payment-checker.payment-token-checker' );
|
||||
assert( $payment_token_checker instanceof PaymentTokenChecker );
|
||||
|
||||
$payment_token_checker->schedule_saved_payment_check( $wc_order->get_id(), $wc_order->get_customer_id() );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Triggers a payment token check for the given order and customer id.
|
||||
*/
|
||||
add_action(
|
||||
'woocommerce_paypal_payments_check_saved_payment',
|
||||
function ( int $order_id, int $customer_id, string $intent ) use ( $c ) {
|
||||
$payment_token_checker = $c->get( 'vaulting.payment-token-checker' );
|
||||
assert( $payment_token_checker instanceof PaymentTokenChecker );
|
||||
|
||||
$payment_token_checker->check_and_update( $order_id, $customer_id, $intent );
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds email content for vaulting failure.
|
||||
*/
|
||||
add_action(
|
||||
'woocommerce_email_before_order_table',
|
||||
function( WC_Order $order ) use ( $c ) {
|
||||
$subscription_helper = $c->get( 'subscription.helper' );
|
||||
assert( $subscription_helper instanceof SubscriptionHelper );
|
||||
$logger = $c->get( 'woocommerce.logger.woocommerce' );
|
||||
assert( $logger instanceof LoggerInterface );
|
||||
|
||||
$vault_failed = $order->get_meta( PaymentTokenChecker::VAULTING_FAILED_META_KEY );
|
||||
if ( $subscription_helper->has_subscription( $order->get_id() ) && ! empty( $vault_failed ) ) {
|
||||
$logger->info( "Adding vaulting failure info to email for order #{$order->get_id()}." );
|
||||
|
||||
if ( $vault_failed === 'void_auth' ) {
|
||||
echo wp_kses_post( '<p>' . __( 'The subscription payment failed because the payment method could not be saved. Please try again with a different payment method.', 'woocommerce-paypal-payments' ) . '</p>' );
|
||||
}
|
||||
|
||||
if ( $vault_failed === 'capture_auth' ) {
|
||||
echo wp_kses_post( '<p>' . __( 'The subscription has been activated, but the payment method could not be saved. Please contact the merchant to save a payment method for automatic subscription renewal payments.', 'woocommerce-paypal-payments' ) . '</p>' );
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds email content for vaulting changing manual renewal order.
|
||||
*/
|
||||
add_action(
|
||||
'woocommerce_email_after_order_table',
|
||||
function( WC_Order $order ) use ( $c ) {
|
||||
$subscription_helper = $c->get( 'subscription.helper' );
|
||||
assert( $subscription_helper instanceof SubscriptionHelper );
|
||||
$logger = $c->get( 'woocommerce.logger.woocommerce' );
|
||||
assert( $logger instanceof LoggerInterface );
|
||||
|
||||
$vault_failed = $order->get_meta( PaymentTokenChecker::VAULTING_FAILED_META_KEY );
|
||||
if ( $subscription_helper->has_subscription( $order->get_id() ) && ! empty( $vault_failed ) ) {
|
||||
$logger->info( "Changing subscription auto-renewal status for order #{$order->get_id()}." );
|
||||
|
||||
if ( $vault_failed === 'capture_auth' ) {
|
||||
$subscriptions = function_exists( 'wcs_get_subscriptions_for_order' ) ? wcs_get_subscriptions_for_order( $order->get_id() ) : array();
|
||||
foreach ( $subscriptions as $subscription ) {
|
||||
$subscription->set_requires_manual_renewal( true );
|
||||
$subscription->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
File diff suppressed because one or more lines are too long
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"name": "ppcp-vaulting",
|
||||
"version": "1.0.0",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"main": "resources/js/myaccount-payments.js",
|
||||
"browserslist": [
|
||||
"> 0.5%",
|
||||
"Safari >= 8",
|
||||
"Chrome >= 41",
|
||||
"Firefox >= 43",
|
||||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
"watch": "cross-env BABEL_ENV=default NODE_ENV=production webpack --watch",
|
||||
"dev": "cross-env BABEL_ENV=default webpack --watch"
|
||||
}
|
||||
}
|
|
@ -23,17 +23,6 @@ return array(
|
|||
$endpoint = $container->get( 'api.endpoint.payment-token' );
|
||||
return new PaymentTokenRepository( $factory, $endpoint );
|
||||
},
|
||||
'vaulting.payment-token-checker' => function( ContainerInterface $container ) : PaymentTokenChecker {
|
||||
return new PaymentTokenChecker(
|
||||
$container->get( 'vaulting.repository.payment-token' ),
|
||||
$container->get( 'api.repository.order' ),
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'wcgateway.processor.authorized-payments' ),
|
||||
$container->get( 'api.endpoint.payments' ),
|
||||
$container->get( 'api.endpoint.payment-token' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'vaulting.customer-approval-listener' => function( ContainerInterface $container ) : CustomerApprovalListener {
|
||||
return new CustomerApprovalListener(
|
||||
$container->get( 'api.endpoint.payment-token' ),
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Vaulting;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use RuntimeException;
|
||||
use WC_Payment_Token;
|
||||
use WC_Payment_Tokens;
|
||||
|
@ -16,9 +17,6 @@ use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
|||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
@ -68,19 +66,6 @@ class VaultingModule implements ModuleInterface {
|
|||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_paypal_payments_check_saved_payment',
|
||||
function ( int $order_id, int $customer_id, string $intent ) use ( $container ) {
|
||||
$payment_token_checker = $container->get( 'vaulting.payment-token-checker' );
|
||||
assert( $payment_token_checker instanceof PaymentTokenChecker );
|
||||
$payment_token_checker->check_and_update( $order_id, $customer_id, $intent );
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
$this->filterFailedVaultingEmailsForSubscriptionOrders( $container );
|
||||
|
||||
add_filter(
|
||||
'woocommerce_payment_token_class',
|
||||
/**
|
||||
|
@ -271,95 +256,8 @@ class VaultingModule implements ModuleInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the emails when vaulting is failed for subscription orders.
|
||||
*
|
||||
* @param ContainerInterface $container A services container instance.
|
||||
* @throws NotFoundException When service could not be found.
|
||||
*/
|
||||
protected function filterFailedVaultingEmailsForSubscriptionOrders( ContainerInterface $container ):void {
|
||||
add_action(
|
||||
'woocommerce_email_before_order_table',
|
||||
function( WC_Order $order ) use ( $container ) {
|
||||
/**
|
||||
* The SubscriptionHelper.
|
||||
*
|
||||
* @var SubscriptionHelper $subscription_helper
|
||||
*/
|
||||
$subscription_helper = $container->get( 'subscription.helper' );
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface $logger
|
||||
*/
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
|
||||
$vault_failed = $order->get_meta( PaymentTokenChecker::VAULTING_FAILED_META_KEY );
|
||||
if ( $subscription_helper->has_subscription( $order->get_id() ) && ! empty( $vault_failed ) ) {
|
||||
$logger->info( "Adding vaulting failure info to email for order #{$order->get_id()}." );
|
||||
|
||||
if ( $vault_failed === 'void_auth' ) {
|
||||
echo wp_kses_post( '<p>' . __( 'The subscription payment failed because the payment method could not be saved. Please try again with a different payment method.', 'woocommerce-paypal-payments' ) . '</p>' );
|
||||
}
|
||||
|
||||
if ( $vault_failed === 'capture_auth' ) {
|
||||
echo wp_kses_post( '<p>' . __( 'The subscription has been activated, but the payment method could not be saved. Please contact the merchant to save a payment method for automatic subscription renewal payments.', 'woocommerce-paypal-payments' ) . '</p>' );
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_email_after_order_table',
|
||||
function( WC_Order $order ) use ( $container ) {
|
||||
/**
|
||||
* The SubscriptionHelper.
|
||||
*
|
||||
* @var SubscriptionHelper $subscription_helper
|
||||
*/
|
||||
$subscription_helper = $container->get( 'subscription.helper' );
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface $logger
|
||||
*/
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
|
||||
$vault_failed = $order->get_meta( PaymentTokenChecker::VAULTING_FAILED_META_KEY );
|
||||
if ( $subscription_helper->has_subscription( $order->get_id() ) && ! empty( $vault_failed ) ) {
|
||||
$logger->info( "Changing subscription auto-renewal status for order #{$order->get_id()}." );
|
||||
|
||||
if ( $vault_failed === 'capture_auth' ) {
|
||||
$subscriptions = function_exists( 'wcs_get_subscriptions_for_order' ) ? wcs_get_subscriptions_for_order( $order->get_id() ) : array();
|
||||
foreach ( $subscriptions as $subscription ) {
|
||||
$subscription->set_requires_manual_renewal( true );
|
||||
$subscription->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getKey() { }
|
||||
|
||||
/**
|
||||
* Check if is payments page.
|
||||
*
|
||||
* @return bool Whethen page is payments or not.
|
||||
*/
|
||||
private function is_payments_page(): bool {
|
||||
global $wp;
|
||||
$request = explode( '/', wp_parse_url( $wp->request, PHP_URL_PATH ) );
|
||||
if ( end( $request ) === 'ppcp-paypal-payment-tokens' ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -441,7 +441,7 @@ return array(
|
|||
assert( $subscription_helper instanceof SubscriptionHelper );
|
||||
|
||||
$fields = array(
|
||||
'checkout_settings_heading' => array(
|
||||
'checkout_settings_heading' => array(
|
||||
'heading' => __( 'Standard Payments Settings', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-heading',
|
||||
'screens' => array(
|
||||
|
@ -451,7 +451,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'title' => array(
|
||||
'title' => array(
|
||||
'title' => __( 'Title', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'description' => __(
|
||||
|
@ -467,7 +467,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'dcc_enabled' => array(
|
||||
'dcc_enabled' => array(
|
||||
'title' => __( 'Enable/Disable', 'woocommerce-paypal-payments' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Once enabled, the Credit Card option will show up in the checkout.', 'woocommerce-paypal-payments' ),
|
||||
|
@ -482,7 +482,7 @@ return array(
|
|||
State::STATE_ONBOARDED,
|
||||
),
|
||||
),
|
||||
'dcc_gateway_title' => array(
|
||||
'dcc_gateway_title' => array(
|
||||
'title' => __( 'Title', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'description' => __(
|
||||
|
@ -499,7 +499,7 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'description' => array(
|
||||
'description' => array(
|
||||
'title' => __( 'Description', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => true,
|
||||
|
@ -518,7 +518,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'intent' => array(
|
||||
'intent' => array(
|
||||
'title' => __( 'Intent', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
|
@ -540,7 +540,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'capture_on_status_change' => array(
|
||||
'capture_on_status_change' => array(
|
||||
'title' => __( 'Capture On Status Change', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
|
@ -557,7 +557,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'capture_for_virtual_only' => array(
|
||||
'capture_for_virtual_only' => array(
|
||||
'title' => __( 'Capture Virtual-Only Orders ', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
|
@ -574,7 +574,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'payee_preferred' => array(
|
||||
'payee_preferred' => array(
|
||||
'title' => __( 'Instant Payments ', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
|
@ -591,7 +591,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'brand_name' => array(
|
||||
'brand_name' => array(
|
||||
'title' => __( 'Brand Name', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'default' => get_bloginfo( 'name' ),
|
||||
|
@ -607,7 +607,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'landing_page' => array(
|
||||
'landing_page' => array(
|
||||
'title' => __( 'Landing Page', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
|
@ -629,7 +629,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'alternative_payment_methods' => array(
|
||||
'alternative_payment_methods' => array(
|
||||
'heading' => __( 'Alternative Payment Methods', 'woocommerce-paypal-payments' ),
|
||||
'description' => sprintf(
|
||||
// translators: %1$s, %2$s, %3$s and %4$s are a link tags.
|
||||
|
@ -645,7 +645,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'disable_funding' => array(
|
||||
'disable_funding' => array(
|
||||
'title' => __( 'Disable Alternative Payment Methods', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-multiselect',
|
||||
'class' => array(),
|
||||
|
@ -669,7 +669,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'card_billing_data_mode' => array(
|
||||
'card_billing_data_mode' => array(
|
||||
'title' => __( 'Send checkout billing data to card fields', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
|
@ -689,7 +689,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => array( 'paypal', CardButtonGateway::ID ),
|
||||
),
|
||||
'allow_card_button_gateway' => array(
|
||||
'allow_card_button_gateway' => array(
|
||||
'title' => __( 'Create gateway for Standard Card Button', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
|
@ -703,7 +703,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'disable_cards' => array(
|
||||
'disable_cards' => array(
|
||||
'title' => __( 'Disable specific credit cards', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-multiselect',
|
||||
'class' => array(),
|
||||
|
@ -731,7 +731,7 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'card_icons' => array(
|
||||
'card_icons' => array(
|
||||
'title' => __( 'Show logo of the following credit cards', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-multiselect',
|
||||
'class' => array(),
|
||||
|
@ -761,7 +761,7 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'vault_enabled_dcc' => array(
|
||||
'vault_enabled_dcc' => array(
|
||||
'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
|
@ -780,7 +780,7 @@ return array(
|
|||
'gateway' => 'dcc',
|
||||
'input_class' => $container->get( 'wcgateway.helper.vaulting-scope' ) ? array() : array( 'ppcp-disabled-checkbox' ),
|
||||
),
|
||||
'3d_secure_heading' => array(
|
||||
'3d_secure_heading' => array(
|
||||
'heading' => __( '3D Secure', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-heading',
|
||||
'description' => wp_kses_post(
|
||||
|
@ -808,7 +808,7 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'3d_secure_contingency' => array(
|
||||
'3d_secure_contingency' => array(
|
||||
'title' => __( 'Contingency for 3D Secure', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'description' => sprintf(
|
||||
|
@ -836,7 +836,7 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'paypal_saved_payments' => array(
|
||||
'paypal_saved_payments' => array(
|
||||
'heading' => __( 'Saved payments', 'woocommerce-paypal-payments' ),
|
||||
'description' => sprintf(
|
||||
// translators: %1$s, %2$s, %3$s and %4$s are a link tags.
|
||||
|
@ -854,8 +854,8 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'subscriptions_mode' => $container->get( 'wcgateway.settings.fields.subscriptions_mode' ),
|
||||
'vault_enabled' => array(
|
||||
'subscriptions_mode' => $container->get( 'wcgateway.settings.fields.subscriptions_mode' ),
|
||||
'vault_enabled' => array(
|
||||
'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
|
@ -874,26 +874,6 @@ return array(
|
|||
'gateway' => 'paypal',
|
||||
'input_class' => $container->get( 'wcgateway.helper.vaulting-scope' ) ? array() : array( 'ppcp-disabled-checkbox' ),
|
||||
),
|
||||
'subscription_behavior_when_vault_fails' => array(
|
||||
'title' => __( 'Subscription capture behavior if Vault fails', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'classes' => $subscription_helper->plugin_is_active() ? array() : array( 'hide' ),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'void_auth',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'By default, subscription payments are captured only when saving the payment method was successful. Without a saved payment method, automatic renewal payments are not possible.', 'woocommerce-paypal-payments' ),
|
||||
'description_with_tip' => __( 'Determines whether authorized payments for subscription orders are captured or voided if there is no saved payment method. This only applies when the intent Capture is used for the subscription order.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'void_auth' => __( 'Void authorization & fail the order/subscription', 'woocommerce-paypal-payments' ),
|
||||
'capture_auth' => __( 'Capture authorized payment & set subscription to Manual Renewal', 'woocommerce-paypal-payments' ),
|
||||
'capture_auth_ignore' => __( 'Capture authorized payment & disregard missing payment method', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => array( 'paypal' ),
|
||||
),
|
||||
);
|
||||
|
||||
if ( ! $subscription_helper->plugin_is_active() ) {
|
||||
|
|
|
@ -299,9 +299,7 @@ class CardButtonGateway extends \WC_Payment_Gateway {
|
|||
);
|
||||
}
|
||||
|
||||
if ( $this->subscription_helper->has_subscription( $order_id ) ) {
|
||||
$this->schedule_saved_payment_check( $order_id, $wc_order->get_customer_id() );
|
||||
}
|
||||
do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order );
|
||||
|
||||
return $this->handle_payment_success( $wc_order );
|
||||
} catch ( PayPalApiException $error ) {
|
||||
|
|
|
@ -396,9 +396,7 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
);
|
||||
}
|
||||
|
||||
if ( $this->subscription_helper->has_subscription( $order_id ) ) {
|
||||
$this->schedule_saved_payment_check( $order_id, $wc_order->get_customer_id() );
|
||||
}
|
||||
do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order );
|
||||
|
||||
return $this->handle_payment_success( $wc_order );
|
||||
} catch ( PayPalApiException $error ) {
|
||||
|
|
|
@ -556,9 +556,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
);
|
||||
}
|
||||
|
||||
if ( $this->subscription_helper->has_subscription( $order_id ) ) {
|
||||
$this->schedule_saved_payment_check( $order_id, $wc_order->get_customer_id() );
|
||||
}
|
||||
do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order );
|
||||
|
||||
return $this->handle_payment_success( $wc_order );
|
||||
} catch ( PayPalApiException $error ) {
|
||||
|
|
|
@ -33,32 +33,6 @@ trait ProcessPaymentTrait {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scheduled the vaulted payment check.
|
||||
*
|
||||
* @param int $wc_order_id The WC order ID.
|
||||
* @param int $customer_id The customer ID.
|
||||
*/
|
||||
protected function schedule_saved_payment_check( int $wc_order_id, int $customer_id ): void {
|
||||
$timestamp = 3 * MINUTE_IN_SECONDS;
|
||||
if (
|
||||
$this->config->has( 'subscription_behavior_when_vault_fails' )
|
||||
&& $this->config->get( 'subscription_behavior_when_vault_fails' ) === 'capture_auth'
|
||||
) {
|
||||
$timestamp = 0;
|
||||
}
|
||||
|
||||
as_schedule_single_action(
|
||||
time() + $timestamp,
|
||||
'woocommerce_paypal_payments_check_saved_payment',
|
||||
array(
|
||||
'order_id' => $wc_order_id,
|
||||
'customer_id' => $customer_id,
|
||||
'intent' => $this->config->has( 'intent' ) ? $this->config->get( 'intent' ) : '',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the payment failure.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue