woocommerce-paypal-payments/modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php

377 lines
11 KiB
PHP
Raw Normal View History

2020-04-02 08:38:00 +03:00
<?php
2020-08-28 08:13:45 +03:00
/**
* The PayPal Payment Gateway
*
2020-09-11 14:11:10 +03:00
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway
2020-08-28 08:13:45 +03:00
*/
2020-04-13 14:25:20 +03:00
2020-04-02 08:38:00 +03:00
declare(strict_types=1);
2020-09-11 14:11:10 +03:00
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
2020-04-02 08:38:00 +03:00
2020-09-28 11:47:24 +03:00
use WooCommerce\PayPalCommerce\Onboarding\State;
2020-09-11 14:11:10 +03:00
use WooCommerce\PayPalCommerce\Session\SessionHandler;
2021-05-19 15:39:33 +02:00
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
2020-09-11 14:11:10 +03:00
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
2020-09-28 11:47:24 +03:00
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
2020-09-11 14:11:10 +03:00
use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
2020-07-02 14:30:03 +03:00
use Psr\Container\ContainerInterface;
2020-04-02 08:38:00 +03:00
2020-08-28 08:13:45 +03:00
/**
* Class PayPalGateway
*/
2020-08-27 11:08:36 +03:00
class PayPalGateway extends \WC_Payment_Gateway {
use ProcessPaymentTrait;
2021-02-22 13:47:32 +02:00
const ID = 'ppcp-gateway';
const CAPTURED_META_KEY = '_ppcp_paypal_captured';
const INTENT_META_KEY = '_ppcp_paypal_intent';
const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
2020-08-27 11:08:36 +03:00
2020-08-28 08:13:45 +03:00
/**
* The Settings Renderer.
*
* @var SettingsRenderer
*/
protected $settings_renderer;
/**
* The processor for authorized payments.
*
* @var AuthorizedPaymentsProcessor
*/
protected $authorized_payments;
/**
* The Authorized Order Action Notice.
*
* @var AuthorizeOrderActionNotice
*/
2020-08-27 11:08:36 +03:00
protected $notice;
2020-08-28 08:13:45 +03:00
/**
* The processor for orders.
*
* @var OrderProcessor
*/
protected $order_processor;
/**
* The settings.
*
* @var ContainerInterface
*/
2020-08-27 11:08:36 +03:00
protected $config;
2020-08-28 08:13:45 +03:00
/**
* The Session Handler.
*
* @var SessionHandler
*/
protected $session_handler;
2021-02-22 13:47:32 +02:00
/**
* Service able to provide transaction url for an order.
*
* @var TransactionUrlProvider
*/
protected $transaction_url_provider;
2021-05-19 15:39:33 +02:00
/**
* The subscription helper.
*
* @var SubscriptionHelper
*/
protected $subscription_helper;
2020-09-28 11:47:24 +03:00
/**
* The Refund Processor.
*
* @var RefundProcessor
*/
private $refund_processor;
2020-08-28 08:13:45 +03:00
/**
* PayPalGateway constructor.
*
* @param SettingsRenderer $settings_renderer The Settings Renderer.
* @param OrderProcessor $order_processor The Order Processor.
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
* @param AuthorizeOrderActionNotice $notice The Order Action Notice object.
* @param ContainerInterface $config The settings.
* @param SessionHandler $session_handler The Session Handler.
2020-09-28 11:47:24 +03:00
* @param RefundProcessor $refund_processor The Refund Processor.
* @param State $state The state.
2021-02-22 13:47:32 +02:00
* @param TransactionUrlProvider $transaction_url_provider Service providing transaction view URL based on order.
2021-05-19 15:39:33 +02:00
* @param SubscriptionHelper $subscription_helper The subscription helper.
2020-08-28 08:13:45 +03:00
*/
2020-08-27 11:08:36 +03:00
public function __construct(
2020-08-28 08:13:45 +03:00
SettingsRenderer $settings_renderer,
OrderProcessor $order_processor,
AuthorizedPaymentsProcessor $authorized_payments_processor,
2020-08-27 11:08:36 +03:00
AuthorizeOrderActionNotice $notice,
ContainerInterface $config,
2020-09-28 11:47:24 +03:00
SessionHandler $session_handler,
RefundProcessor $refund_processor,
State $state,
2021-05-19 15:39:33 +02:00
TransactionUrlProvider $transaction_url_provider,
SubscriptionHelper $subscription_helper
2020-08-27 11:08:36 +03:00
) {
2021-02-22 13:47:32 +02:00
$this->id = self::ID;
$this->order_processor = $order_processor;
$this->authorized_payments = $authorized_payments_processor;
$this->notice = $notice;
$this->settings_renderer = $settings_renderer;
$this->config = $config;
$this->session_handler = $session_handler;
$this->refund_processor = $refund_processor;
$this->transaction_url_provider = $transaction_url_provider;
2020-09-28 11:47:24 +03:00
if ( $state->current_state() === State::STATE_ONBOARDED ) {
$this->supports = array( 'refunds' );
}
2020-08-27 11:08:36 +03:00
if (
defined( 'PPCP_FLAG_SUBSCRIPTION' )
&& PPCP_FLAG_SUBSCRIPTION
&& $this->gateways_enabled()
&& $this->vault_setting_enabled()
2020-08-27 11:08:36 +03:00
) {
$this->supports = array(
2020-09-28 11:47:24 +03:00
'refunds',
2020-08-27 11:08:36 +03:00
'products',
'subscriptions',
'subscription_cancellation',
'subscription_suspension',
'subscription_reactivation',
'subscription_amount_changes',
'subscription_date_changes',
'subscription_payment_method_change',
'subscription_payment_method_change_customer',
'subscription_payment_method_change_admin',
'multiple_subscriptions',
);
}
$this->method_title = $this->define_method_title();
$this->method_description = $this->define_method_description();
2020-08-27 11:08:36 +03:00
$this->title = $this->config->has( 'title' ) ?
$this->config->get( 'title' ) : $this->method_title;
$this->description = $this->config->has( 'description' ) ?
$this->config->get( 'description' ) : $this->method_description;
$this->init_form_fields();
$this->init_settings();
add_action(
'woocommerce_update_options_payment_gateways_' . $this->id,
array(
$this,
'process_admin_options',
)
);
2021-05-19 15:39:33 +02:00
$this->subscription_helper = $subscription_helper;
2020-08-27 11:08:36 +03:00
}
2020-08-28 08:13:45 +03:00
/**
* Whether the Gateway needs to be setup.
*
* @return bool
*/
2020-08-27 11:08:36 +03:00
public function needs_setup(): bool {
return true;
}
2020-08-28 08:13:45 +03:00
/**
* Initializes the form fields.
*/
2020-08-27 11:08:36 +03:00
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce-paypal-payments' ),
'type' => 'checkbox',
'desc_tip' => true,
'description' => __( 'In order to use PayPal or PayPal Card Processing, you need to enable the Gateway.', 'woocommerce-paypal-payments' ),
'label' => __( 'Enable the PayPal Gateway', 'woocommerce-paypal-payments' ),
'default' => 'no',
2020-08-27 11:08:36 +03:00
),
'ppcp' => array(
'type' => 'ppcp',
),
);
$should_show_enabled_checkbox = ! $this->is_credit_card_tab() && ( $this->config->has( 'merchant_email' ) && $this->config->get( 'merchant_email' ) );
if ( ! $should_show_enabled_checkbox ) {
unset( $this->form_fields['enabled'] );
}
2020-08-27 11:08:36 +03:00
}
2020-08-28 08:13:45 +03:00
/**
2020-09-03 07:05:50 +03:00
* Captures an authorized payment for an WooCommerce order.
2020-08-28 08:13:45 +03:00
*
2020-09-03 07:05:50 +03:00
* @param \WC_Order $wc_order The WooCommerce order.
2020-08-28 08:13:45 +03:00
*
* @return bool
*/
public function capture_authorized_payment( \WC_Order $wc_order ): bool {
$is_processed = $this->authorized_payments->process( $wc_order );
$this->render_authorization_message_for_status( $this->authorized_payments->last_status() );
2020-08-27 11:08:36 +03:00
2020-08-28 08:13:45 +03:00
if ( $is_processed ) {
$wc_order->add_order_note(
__( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
2020-08-27 11:08:36 +03:00
);
2020-08-28 08:13:45 +03:00
$wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
$wc_order->save();
$wc_order->payment_complete();
2020-08-27 11:08:36 +03:00
return true;
}
2020-08-28 08:13:45 +03:00
if ( $this->authorized_payments->last_status() === AuthorizedPaymentsProcessor::ALREADY_CAPTURED ) {
if ( $wc_order->get_status() === 'on-hold' ) {
$wc_order->add_order_note(
__( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
2020-08-27 11:08:36 +03:00
);
}
2020-08-28 08:13:45 +03:00
$wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
$wc_order->save();
$wc_order->payment_complete();
2020-08-27 11:08:36 +03:00
return true;
}
return false;
}
2020-08-28 08:13:45 +03:00
/**
* Displays the notice for a status.
*
* @param string $status The status.
*/
private function render_authorization_message_for_status( string $status ) {
2020-08-27 11:08:36 +03:00
2020-08-28 08:13:45 +03:00
$message_mapping = array(
2020-08-27 11:08:36 +03:00
AuthorizedPaymentsProcessor::SUCCESSFUL => AuthorizeOrderActionNotice::SUCCESS,
AuthorizedPaymentsProcessor::ALREADY_CAPTURED => AuthorizeOrderActionNotice::ALREADY_CAPTURED,
AuthorizedPaymentsProcessor::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
AuthorizedPaymentsProcessor::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
);
2020-08-28 08:13:45 +03:00
$display_message = ( isset( $message_mapping[ $status ] ) ) ?
$message_mapping[ $status ]
2020-08-27 11:08:36 +03:00
: AuthorizeOrderActionNotice::FAILED;
2020-08-28 08:13:45 +03:00
$this->notice->display_message( $display_message );
2020-08-27 11:08:36 +03:00
}
2020-08-28 08:13:45 +03:00
/**
* Renders the settings.
*
* @return string
*/
2020-08-27 11:08:36 +03:00
public function generate_ppcp_html(): string {
ob_start();
2020-08-28 08:13:45 +03:00
$this->settings_renderer->render( false );
2020-08-27 11:08:36 +03:00
$content = ob_get_contents();
ob_end_clean();
return $content;
}
/**
* Defines the method title. If we are on the credit card tab in the settings, we want to change this.
*
* @return string
*/
private function define_method_title(): string {
if ( $this->is_credit_card_tab() ) {
return __( 'PayPal Card Processing', 'woocommerce-paypal-payments' );
}
if ( $this->is_paypal_tab() ) {
return __( 'PayPal Checkout', 'woocommerce-paypal-payments' );
}
return __( 'PayPal', 'woocommerce-paypal-payments' );
}
/**
* Defines the method description. If we are on the credit card tab in the settings, we want to change this.
*
* @return string
*/
private function define_method_description(): string {
if ( $this->is_credit_card_tab() ) {
return __(
'Accept debit and credit cards, and local payment methods.',
'woocommerce-paypal-payments'
);
}
return __(
'Accept PayPal, Pay Later and alternative payment types.',
'woocommerce-paypal-payments'
);
}
// phpcs:disable WordPress.Security.NonceVerification.Recommended
2020-09-02 14:53:30 +03:00
/**
* Determines, whether the current session is on the credit card tab in the admin settings.
*
* @return bool
*/
private function is_credit_card_tab() : bool {
return is_admin()
&& isset( $_GET[ SectionsRenderer::KEY ] )
&& CreditCardGateway::ID === sanitize_text_field( wp_unslash( $_GET[ SectionsRenderer::KEY ] ) );
}
/**
* Whether we are on the PayPal settings tab.
*
* @return bool
*/
private function is_paypal_tab() : bool {
return ! $this->is_credit_card_tab()
&& is_admin()
&& isset( $_GET['section'] )
&& self::ID === sanitize_text_field( wp_unslash( $_GET['section'] ) );
}
2020-09-02 12:41:10 +03:00
// phpcs:enable WordPress.Security.NonceVerification.Recommended
2020-09-28 11:47:24 +03:00
/**
* Process refund.
*
* If the gateway declares 'refunds' support, this will allow it to refund.
* a passed in amount.
*
* @param int $order_id Order ID.
* @param float $amount Refund amount.
* @param string $reason Refund reason.
* @return boolean True or false based on success, or a WP_Error object.
*/
public function process_refund( $order_id, $amount = null, $reason = '' ) {
$order = wc_get_order( $order_id );
if ( ! is_a( $order, \WC_Order::class ) ) {
return false;
}
return $this->refund_processor->process( $order, (float) $amount, (string) $reason );
}
2021-02-22 13:47:32 +02:00
/**
* Return transaction url for this gateway and given order.
*
* @param \WC_Order $order WC order to get transaction url by.
*
* @return string
*/
public function get_transaction_url( $order ): string {
$this->view_transaction_url = $this->transaction_url_provider->get_transaction_url_base( $order );
2021-02-22 13:47:32 +02:00
return parent::get_transaction_url( $order );
}
2020-04-06 11:16:18 +03:00
}