Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(reader-revenue): add PayPal Payments gateway to wizard #3665

Merged
merged 3 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions includes/class-plugin-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,15 @@ public static function get_managed_plugins() {
'Download' => 'wporg',
'EditPath' => 'admin.php?page=wc-settings&tab=checkout&section=woocommerce_payments',
],
'woocommerce-paypal-payments' => [
'Name' => \esc_html__( 'WooCommerce PayPal Payments', 'newspack-plugin' ),
'Description' => \esc_html__( 'PayPal\'s latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.', 'newspack-plugin' ),
'Author' => \esc_html__( 'WooCommerce', 'newspack-plugin' ),
'PluginURI' => \esc_url( 'https://woocommerce.com/' ),
'AuthorURI' => \esc_url( 'https://woocommerce.com/' ),
'Download' => 'wporg',
'EditPath' => 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway',
],
'woocommerce-name-your-price' => [
'Name' => \esc_html__( 'WooCommerce Name Your Price', 'newspack-plugin' ),
'Description' => \esc_html__( 'WooCommerce Name Your Price allows customers to set their own price for products or donations.', 'newspack-plugin' ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,35 @@ class WooCommerce_Configuration_Manager extends Configuration_Manager {
*/
public $slug = 'woocommerce';

/**
* Fully-supported payment gateways.
*
* @var array
*/
public $supported_gateways = [
'ppcp-gateway' => [
'name' => 'PayPal Payments',
'plugin' => 'woocommerce-paypal-payments',
'url' => 'https://woocommerce.com/products/woocommerce-paypal-payments/',
'connect' => 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway&ppcp-tab=ppcp-connection',
'settings' => 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway',
],
'stripe' => [
'name' => 'Stripe',
'plugin' => 'woocommerce-gateway-stripe',
'url' => 'https://woocommerce.com/document/stripe/',
'connect' => 'admin.php?page=wc-settings&tab=checkout&section=stripe',
'settings' => 'admin.php?page=wc-settings&tab=checkout&section=stripe&panel=settings',
],
'woocommerce_payments' => [
'name' => 'WooCommerce Payments',
'plugin' => 'woocommerce-payments',
'url' => 'https://woocommerce.com/payments/',
'connect' => 'admin.php?page=wc-admin&path=%2Fpayments%2Foverview',
'settings' => 'admin.php?page=wc-settings&tab=checkout&section=woocommerce_payments',
],
];

/**
* Get whether the WooCommerce plugin is active and set up.
*
Expand Down Expand Up @@ -162,15 +191,25 @@ public static function get_stripe_gateway( $only_enabled = false ) {
}

/**
* Get WooPayments payment gateway, if available.
* Get slugs for supported payment gateways.
*
* @param bool $only_enabled If true, only return the gateway if enabled.
* @return array
*/
public function get_supported_payment_gateways() {
return array_keys( $this->supported_gateways );
}

/**
* Get payment gateway by slug, if available.
*
* @param string $gateway The slug for the payment gateway to get.
* @param bool $only_enabled If true, only return the gateway if enabled.
*
* @return WC_Gateway_Stripe|bool WC_Gateway_Stripe instance if Stripe payment gateway is available, false if not.
*/
public static function get_woopayments_gateway( $only_enabled = false ) {
public static function get_payment_gateway( $gateway, $only_enabled = false ) {
$gateways = self::get_payment_gateways( $only_enabled );
return isset( $gateways['woocommerce_payments'] ) ? $gateways['woocommerce_payments'] : false;
return isset( $gateways[ $gateway ] ) ? $gateways[ $gateway ] : false;
}

/**
Expand All @@ -197,20 +236,44 @@ public function stripe_data() {
}

/**
* Retrieve WooPayments data
* Retrieve data for the given payment gateway.
*
* @return Array|bool Array of WooPayments data, or false if WooPayments gateway isn't available.
* @param string $gateway_slug The slug for the payment gateway to get.
*
* @return Array|bool Array of gateway data, or false if gateway isn't available.
*/
public function woopayments_data() {
$woopayments_gateway = self::get_woopayments_gateway();
if ( ! $woopayments_gateway ) {
public function gateway_data( $gateway_slug ) {
if ( ! isset( $this->supported_gateways[ $gateway_slug ] ) ) {
return false;
}
$gateway = self::get_payment_gateway( $gateway_slug );
$is_connected = $gateway && method_exists( $gateway, 'is_connected' ) ? $gateway->is_connected() : false;
$test_mode = $gateway && 'yes' === $gateway->get_option( 'test_mode', false ) ? true : false;

// PayPal gateway doesn't provide helper functions, so we need to use its internal API.
if ( 'ppcp-gateway' === $gateway_slug && method_exists( 'WooCommerce\PayPalCommerce\PPCP', 'container' ) ) {
$paypal = \WooCommerce\PayPalCommerce\PPCP::container();
if ( $paypal ) {
$env = $paypal->get( 'onboarding.environment' );
if ( $env && $env->current_environment_is( $env::SANDBOX ) ) {
$test_mode = true;
}
$state = $paypal->get( 'onboarding.state' );
if ( $state && $state::STATE_ONBOARDED <= $state->current_state() ) {
$is_connected = true;
}
}
}

return [
'enabled' => 'yes' === $woopayments_gateway->get_option( 'enabled', false ) ? true : false,
'test_mode' => 'yes' === $woopayments_gateway->get_option( 'test_mode', false ) ? true : false,
'is_connected' => $woopayments_gateway->is_connected(),
'enabled' => $gateway && 'yes' === $gateway->get_option( 'enabled', false ) ? true : false,
'name' => esc_html( $this->supported_gateways[ $gateway_slug ]['name'] ),
'test_mode' => $test_mode,
'is_connected' => $is_connected,
'slug' => $gateway_slug,
'url' => $this->supported_gateways[ $gateway_slug ]['url'],
'connect' => \admin_url( $this->supported_gateways[ $gateway_slug ]['connect'] ),
'settings' => \admin_url( $this->supported_gateways[ $gateway_slug ]['settings'] ),
];
}

Expand Down Expand Up @@ -271,37 +334,49 @@ public function update_wc_stripe_settings( $args ) {
}

/**
* Update WooPayments settings
* Update settings for the given payment gateway.
*
* @param Array $args Settings.
* @param string $gateway_slug The slug for the payment gateway to update.
* @param Array $args Settings.
* @return Array|WP_Error The data that was updated or an error.
*/
public function update_wc_woopayments_settings( $args ) {
public function update_gateway_settings( $gateway_slug, $args ) {
if ( ! class_exists( 'WC_Payment_Gateways' ) ) {
return false;
}

// Get the WooPayments payment gateway instance.
$woopayments = self::get_woopayments_gateway();
if ( ! $woopayments ) {
if ( ! isset( $this->supported_gateways[ $gateway_slug ] ) ) {
return false;
}

// Get the payment gateway instance.
$gateway = self::get_payment_gateway( $gateway_slug );
if ( ! $gateway ) {
if ( isset( $args['enabled'] ) && $args['enabled'] ) {
// WooPayments gateway is not installed and we want to use it. Install/Activate/Initialize it.
Plugin_Manager::activate( 'woocommerce-payments' );
// Gateway is not installed and we want to use it. Install/Activate/Initialize it.
Plugin_Manager::activate( $this->supported_gateways[ $gateway_slug ]['plugin'] );
do_action( 'plugins_loaded' );
\WC_Payment_Gateways::instance()->init();
$woopayments = self::get_woopayments_gateway();
if ( ! $woopayments ) {
return new WP_Error( 'newspack_woopayments_gateway_error', __( 'Error activating WooPayments.', 'newspack-plugin' ) );
$gateway = self::get_payment_gateway( $gateway_slug );
if ( ! $gateway ) {
return new WP_Error(
'newspack_payment_gateway_error',
sprintf(
// Translators: %s is the slug of the payment gateway.
__( 'Error activating %s gateway.', 'newspack-plugin' ),
$gateway_slug
)
);
}
} else {
// WooPayments is not installed and we don't want to use it. No settings needed.
// Gateway is not installed and we don't want to use it. No settings needed.
return true;
}
}

// Update WooPayments settings.
// Update gateway settings.
if ( isset( $args['enabled'] ) ) {
$woopayments->update_option( 'enabled', $args['enabled'] ? 'yes' : 'no' );
$gateway->update_option( 'enabled', $args['enabled'] ? 'yes' : 'no' );
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
* WooCommerce Order UTM class.
*/
class WooCommerce_Cover_Fees {
const CUSTOM_FIELD_NAME = 'newspack-wc-pay-fees';
const SUPPORTED_GATEWAYS = [ 'stripe', 'woocommerce_payments' ];
const CUSTOM_FIELD_NAME = 'newspack-wc-pay-fees';

/**
* Initialize hooks.
Expand Down Expand Up @@ -135,7 +134,8 @@ private static function should_apply_fee( $data ) {
if ( ! self::should_allow_covering_fees() ) {
return false;
}
if ( ! isset( $data['payment_method'] ) || ! in_array( $data['payment_method'], self::SUPPORTED_GATEWAYS, true ) ) {
$wc_configuration_manager = Configuration_Managers::configuration_manager_class_for_plugin_slug( 'woocommerce' );
if ( ! isset( $data['payment_method'] ) || ! in_array( $data['payment_method'], $wc_configuration_manager->get_supported_payment_gateways(), true ) ) {
return false;
}
if ( ! isset( $data[ self::CUSTOM_FIELD_NAME ] ) || '1' !== $data[ self::CUSTOM_FIELD_NAME ] ) {
Expand All @@ -150,7 +150,8 @@ private static function should_apply_fee( $data ) {
* @param string $payment_gateway The slug for the payment gateway rendering these payment fields.
*/
public static function render_transaction_fee_input( $payment_gateway ) {
if ( ! self::should_allow_covering_fees() || ! in_array( $payment_gateway, self::SUPPORTED_GATEWAYS, true ) ) {
$wc_configuration_manager = Configuration_Managers::configuration_manager_class_for_plugin_slug( 'woocommerce' );
if ( ! self::should_allow_covering_fees() || ! in_array( $payment_gateway, $wc_configuration_manager->get_supported_payment_gateways(), true ) ) {
return;
}
?>
Expand Down
28 changes: 19 additions & 9 deletions includes/wizards/class-reader-revenue-wizard.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,13 @@ public function register_api_endpoints() {
]
);

// Save WooPayments info.
// Save payment gateway info.
register_rest_route(
NEWSPACK_API_NAMESPACE,
'/wizard/' . $this->slug . '/woopayments/',
'/wizard/' . $this->slug . '/gateway/',
[
'methods' => \WP_REST_Server::EDITABLE,
'callback' => [ $this, 'api_update_woopayments_settings' ],
'callback' => [ $this, 'api_update_gateway_settings' ],
'permission_callback' => [ $this, 'api_permissions_check' ],
'args' => [
'activate' => [
Expand All @@ -183,6 +183,9 @@ public function register_api_endpoints() {
'enabled' => [
'sanitize_callback' => 'Newspack\newspack_string_to_bool',
],
'slug' => [
'sanitize_callback' => 'Newspack\newspack_clean',
],
],
]
);
Expand Down Expand Up @@ -423,16 +426,23 @@ public function api_update_stripe_settings( $request ) {
}

/**
* Save WooPayments settings.
* Save payment gateway settings.
*
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response Response.
*/
public function api_update_woopayments_settings( $request ) {
public function api_update_gateway_settings( $request ) {
$wc_configuration_manager = Configuration_Managers::configuration_manager_class_for_plugin_slug( 'woocommerce' );

$params = $request->get_params();
$result = $wc_configuration_manager->update_wc_woopayments_settings( $params );
if ( ! isset( $params['slug'] ) ) {
return \rest_ensure_response(
new WP_Error( 'newspack_invalid_param', __( 'Gateway slug is required.', 'newspack' ) )
);
}
$slug = $params['slug'];
unset( $params['slug'] );
$result = $wc_configuration_manager->update_gateway_settings( $slug, $params );
return \rest_ensure_response( $result );
}

Expand Down Expand Up @@ -495,7 +505,6 @@ public function fetch_all_data() {
$platform = Donations::get_platform_slug();
$wc_configuration_manager = Configuration_Managers::configuration_manager_class_for_plugin_slug( 'woocommerce' );
$wc_installed = 'active' === Plugin_Manager::get_managed_plugin_status( 'woocommerce' );
$stripe_data = Stripe_Connection::get_stripe_data();

$billing_fields = null;
$order_notes_field = [];
Expand All @@ -516,8 +525,9 @@ public function fetch_all_data() {
'currency_fields' => newspack_get_currencies_options(),
'location_data' => [],
'payment_gateways' => [
'stripe' => $stripe_data,
'woopayments' => $wc_configuration_manager->woopayments_data(),
'stripe' => Stripe_Connection::get_stripe_data(),
'woocommerce_payments' => $wc_configuration_manager->gateway_data( 'woocommerce_payments' ),
'ppcp-gateway' => $wc_configuration_manager->gateway_data( 'ppcp-gateway' ),
],
'additional_settings' => [
'allow_covering_fees' => boolval( get_option( 'newspack_donations_allow_covering_fees', false ) ),
Expand Down
14 changes: 10 additions & 4 deletions src/wizards/readerRevenue/views/payment-methods/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ExternalLink } from '@wordpress/components';
*/
import { AdditionalSettings } from './additional-settings';
import { Stripe } from './stripe';
import { WooPayments } from './woopayments';
import { PaymentGateway } from './payment-gateway';
import { Notice, SectionHeader, Wizard } from '../../../../components/src';
import './style.scss';

Expand All @@ -26,7 +26,6 @@ const PaymentGateways = () => {
return null;
}

const { stripe = false, woopayments = false } = paymentGateways;
const hasPaymentGateway = Object.keys( paymentGateways ).some( gateway => paymentGateways[ gateway ]?.enabled );
return (
<>
Expand Down Expand Up @@ -64,8 +63,15 @@ const PaymentGateways = () => {
}
/>
) }
<Stripe stripe={ stripe } />
<WooPayments woopayments={ woopayments } />
{
Object.keys( paymentGateways ).map( gateway => {
// Stripe has unique connection status and badge level logic.
if ( 'stripe' === gateway ) {
return <Stripe key={ paymentGateways[ gateway ] } stripe={ paymentGateways[ gateway ] } />;
}
return <PaymentGateway key={ gateway } gateway={ paymentGateways[ gateway ] } />;
} )
}
{ hasPaymentGateway && (
<AdditionalSettings
settings={ settings }
Expand Down
Loading
Loading