woocommerce-paypal-payments/modules/ppcp-googlepay/src/GooglepayModule.php

290 lines
8.1 KiB
PHP

<?php
/**
* The Googlepay module.
*
* @package WooCommerce\PayPalCommerce\Googlepay
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Googlepay;
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
use WC_Payment_Gateway;
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;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExecutableModule;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExtendingModule;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
/**
* Class GooglepayModule
*/
class GooglepayModule implements ServiceModule, ExtendingModule, ExecutableModule {
use ModuleClassNameIdTrait;
/**
* {@inheritDoc}
*/
public function services(): array {
return require __DIR__ . '/../services.php';
}
/**
* {@inheritDoc}
*/
public function extensions(): array {
return require __DIR__ . '/../extensions.php';
}
/**
* {@inheritDoc}
*/
public function run( ContainerInterface $c ): bool {
// Clears product status when appropriate.
add_action(
'woocommerce_paypal_payments_clear_apm_product_status',
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 );
}
);
add_action(
'init',
static function () use ( $c ) {
// Check if the module is applicable, correct country, currency, ... etc.
if ( ! $c->get( 'googlepay.eligible' ) ) {
return;
}
// Load the button handler.
$button = $c->get( 'googlepay.button' );
assert( $button instanceof ButtonInterface );
$button->initialize();
// Show notice if there are product availability issues.
$availability_notice = $c->get( 'googlepay.availability_notice' );
assert( $availability_notice instanceof AvailabilityNotice );
$availability_notice->execute();
// Check if this merchant can activate / use the buttons.
// We allow non referral merchants as they can potentially still use GooglePay, we just have no way of checking the capability.
if ( ( ! $c->get( 'googlepay.available' ) ) && $c->get( 'googlepay.is_referral' ) ) {
return;
}
// Initializes button rendering.
add_action(
'wp',
static function () use ( $c, $button ) {
if ( is_admin() ) {
return;
}
$button->render();
}
);
// Enqueue frontend scripts.
add_action(
'wp_enqueue_scripts',
static function () use ( $c, $button ) {
$smart_button = $c->get( 'button.smart-button' );
assert( $smart_button instanceof SmartButtonInterface );
if ( $smart_button->should_load_ppcp_script() ) {
$button->enqueue();
return;
}
/*
* Checkout page, but no PPCP scripts were loaded. Most likely in continuation mode.
* Need to enqueue some Google Pay scripts to populate the billing form with details
* provided by Google Pay.
*/
if ( is_checkout() ) {
$button->enqueue();
}
if ( has_block( 'woocommerce/checkout' ) || has_block( 'woocommerce/cart' ) ) {
/**
* Should add this to the ButtonInterface.
*
* @psalm-suppress UndefinedInterfaceMethod
*/
$button->enqueue_styles();
}
}
);
// Enqueue backend scripts.
add_action(
'admin_enqueue_scripts',
static function () use ( $c, $button ) {
if ( ! is_admin() || ! $c->get( 'wcgateway.is-ppcp-settings-payment-methods-page' ) ) {
return;
}
/**
* Should add this to the ButtonInterface.
*
* @psalm-suppress UndefinedInterfaceMethod
*/
$button->enqueue_admin();
}
);
// Registers buttons on blocks pages.
add_action(
'woocommerce_blocks_payment_method_type_registration',
function( PaymentMethodRegistry $payment_method_registry ) use ( $c, $button ): void {
if ( $button->is_enabled() ) {
$payment_method_registry->register( $c->get( 'googlepay.blocks-payment-method' ) );
}
}
);
// Adds GooglePay component to the backend button preview settings.
add_action(
'woocommerce_paypal_payments_admin_gateway_settings',
function( array $settings ) use ( $c ): array {
if ( is_array( $settings['components'] ) ) {
$settings['components'][] = 'googlepay';
}
return $settings;
}
);
// Initialize AJAX endpoints.
add_action(
'wc_ajax_' . UpdatePaymentDataEndpoint::ENDPOINT,
static function () use ( $c ) {
$endpoint = $c->get( 'googlepay.endpoint.update-payment-data' );
assert( $endpoint instanceof UpdatePaymentDataEndpoint );
$endpoint->handle_request();
}
);
},
1
);
add_filter(
'woocommerce_payment_gateways',
/**
* Param types removed to avoid third-party issues.
*
* @psalm-suppress MissingClosureParamType
*/
static function ( $methods ) use ( $c ): array {
if ( ! is_array( $methods ) ) {
return $methods;
}
$settings = $c->get( 'wcgateway.settings' );
assert( $settings instanceof Settings );
if ( $settings->has( 'googlepay_button_enabled' ) && $settings->get( 'googlepay_button_enabled' ) ) {
$googlepay_gateway = $c->get( 'googlepay.wc-gateway' );
assert( $googlepay_gateway instanceof WC_Payment_Gateway );
$methods[] = $googlepay_gateway;
}
return $methods;
}
);
add_action(
'woocommerce_review_order_after_submit',
function () {
echo '<div id="ppc-button-' . esc_attr( GooglePayGateway::ID ) . '"></div>';
}
);
add_action(
'woocommerce_pay_order_after_submit',
function () {
echo '<div id="ppc-button-' . esc_attr( GooglePayGateway::ID ) . '"></div>';
}
);
add_filter(
'woocommerce_paypal_payments_selected_button_locations',
function( array $locations, string $setting_name ): array {
$gateway = WC()->payment_gateways()->payment_gateways()[ GooglePayGateway::ID ] ?? '';
if ( $gateway && $gateway->enabled === 'yes' && $setting_name === 'smart_button_locations' ) {
$locations[] = 'checkout';
}
return $locations;
},
10,
2
);
add_filter(
'woocommerce_paypal_payments_rest_common_merchant_features',
function ( array $features ) use ( $c ): array {
$product_status = $c->get( 'googlepay.helpers.apm-product-status' );
assert( $product_status instanceof ApmProductStatus );
$google_pay_enabled = $product_status->is_active();
$features['google_pay'] = array(
'enabled' => $google_pay_enabled,
);
return $features;
}
);
add_filter(
'ppcp_create_order_request_body_data',
static function ( array $data, string $payment_method, array $request ) use ( $c ) : array {
$funding_source = $request['funding_source'] ?? '';
if ( $payment_method !== GooglePayGateway::ID && $funding_source !== 'googlepay' ) {
return $data;
}
$settings = $c->get( 'wcgateway.settings' );
assert( $settings instanceof Settings );
$three_d_secure_contingency =
$settings->has( '3d_secure_contingency' )
? apply_filters( 'woocommerce_paypal_payments_three_d_secure_contingency', $settings->get( '3d_secure_contingency' ) )
: '';
if (
$three_d_secure_contingency === 'SCA_ALWAYS'
|| $three_d_secure_contingency === 'SCA_WHEN_REQUIRED'
) {
$data['payment_source']['google_pay'] = array(
'attributes' => array(
'verification' => array(
'method' => $three_d_secure_contingency,
),
),
);
}
return $data;
},
10,
3
);
return true;
}
}