mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 18:16:38 +08:00
code styles for the wc gateway module
This commit is contained in:
parent
7fcda592f7
commit
cf0b5b0e25
33 changed files with 3453 additions and 2620 deletions
|
@ -108,6 +108,6 @@ class EarlyOrderHandler {
|
||||||
/**
|
/**
|
||||||
* Patch Order so we have the \WC_Order id added.
|
* Patch Order so we have the \WC_Order id added.
|
||||||
*/
|
*/
|
||||||
return $this->orderProcessor->patchOrder( $wcOrder, $order );
|
return $this->orderProcessor->patch_order( $wcOrder, $order );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* The extensions of the gateway module.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
@ -12,72 +17,76 @@ use Inpsyde\Woocommerce\Logging\Logger\WooCommerceLogger;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
return [
|
return array(
|
||||||
|
|
||||||
'api.merchant_email' => static function (ContainerInterface $container): string {
|
'api.merchant_email' => static function ( ContainerInterface $container ): string {
|
||||||
$settings = $container->get('wcgateway.settings');
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
return $settings->has('merchant_email') ? (string) $settings->get('merchant_email') : '';
|
return $settings->has( 'merchant_email' ) ? (string) $settings->get( 'merchant_email' ) : '';
|
||||||
},
|
},
|
||||||
'api.merchant_id' => static function (ContainerInterface $container): string {
|
'api.merchant_id' => static function ( ContainerInterface $container ): string {
|
||||||
$settings = $container->get('wcgateway.settings');
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
return $settings->has('merchant_id') ? (string) $settings->get('merchant_id') : '';
|
return $settings->has( 'merchant_id' ) ? (string) $settings->get( 'merchant_id' ) : '';
|
||||||
},
|
},
|
||||||
'api.partner_merchant_id' => static function (): string {
|
'api.partner_merchant_id' => static function (): string {
|
||||||
// ToDo: Replace with the real merchant id of platform
|
// @ToDo: Replace with the real merchant id of platform
|
||||||
return 'KQ8FCM66JFGDL';
|
return 'KQ8FCM66JFGDL';
|
||||||
},
|
},
|
||||||
'api.key' => static function (ContainerInterface $container): string {
|
'api.key' => static function ( ContainerInterface $container ): string {
|
||||||
$settings = $container->get('wcgateway.settings');
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
$key = $settings->has('client_id') ? (string) $settings->get('client_id') : '';
|
$key = $settings->has( 'client_id' ) ? (string) $settings->get( 'client_id' ) : '';
|
||||||
return $key;
|
return $key;
|
||||||
},
|
},
|
||||||
'api.secret' => static function (ContainerInterface $container): string {
|
'api.secret' => static function ( ContainerInterface $container ): string {
|
||||||
$settings = $container->get('wcgateway.settings');
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
return $settings->has('client_secret') ? (string) $settings->get('client_secret') : '';
|
return $settings->has( 'client_secret' ) ? (string) $settings->get( 'client_secret' ) : '';
|
||||||
},
|
},
|
||||||
'api.prefix' => static function (ContainerInterface $container): string {
|
'api.prefix' => static function ( ContainerInterface $container ): string {
|
||||||
$settings = $container->get('wcgateway.settings');
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
return $settings->has('prefix') ? (string) $settings->get('prefix') : 'WC-';
|
return $settings->has( 'prefix' ) ? (string) $settings->get( 'prefix' ) : 'WC-';
|
||||||
},
|
},
|
||||||
'api.endpoint.order' => static function (ContainerInterface $container): OrderEndpoint {
|
'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint {
|
||||||
$orderFactory = $container->get('api.factory.order');
|
$order_factory = $container->get( 'api.factory.order' );
|
||||||
$patchCollectionFactory = $container->get('api.factory.patch-collection-factory');
|
$patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
|
||||||
$logger = $container->get('woocommerce.logger.woocommerce');
|
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||||
/**
|
/**
|
||||||
* @var SessionHandler $sessionHandler
|
* The session handler.
|
||||||
|
*
|
||||||
|
* @var SessionHandler $session_handler
|
||||||
*/
|
*/
|
||||||
$sessionHandler = $container->get('session.handler');
|
$session_handler = $container->get( 'session.handler' );
|
||||||
$bnCode = $sessionHandler->bnCode();
|
$bn_code = $session_handler->bnCode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
* @var Settings $settings
|
* @var Settings $settings
|
||||||
*/
|
*/
|
||||||
$settings = $container->get('wcgateway.settings');
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
$intent = $settings->has('intent') && strtoupper((string) $settings->get('intent')) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
|
$intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
|
||||||
$applicationContextRepository = $container->get('api.repository.application-context');
|
$application_context_repository = $container->get( 'api.repository.application-context' );
|
||||||
$paypalRequestId = $container->get('api.repository.paypal-request-id');
|
$pay_pal_request_id_repository = $container->get( 'api.repository.paypal-request-id' );
|
||||||
return new OrderEndpoint(
|
return new OrderEndpoint(
|
||||||
$container->get('api.host'),
|
$container->get( 'api.host' ),
|
||||||
$container->get('api.bearer'),
|
$container->get( 'api.bearer' ),
|
||||||
$orderFactory,
|
$order_factory,
|
||||||
$patchCollectionFactory,
|
$patch_collection_factory,
|
||||||
$intent,
|
$intent,
|
||||||
$logger,
|
$logger,
|
||||||
$applicationContextRepository,
|
$application_context_repository,
|
||||||
$paypalRequestId,
|
$pay_pal_request_id_repository,
|
||||||
$bnCode
|
$bn_code
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'woocommerce.logger.woocommerce' => function (ContainerInterface $container): LoggerInterface {
|
'woocommerce.logger.woocommerce' => function ( ContainerInterface $container ): LoggerInterface {
|
||||||
$settings = $container->get('wcgateway.settings');
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
if (! function_exists('wc_get_logger') || ! $settings->has('logging_enabled') || ! $settings->get('logging_enabled')) {
|
if ( ! function_exists( 'wc_get_logger' ) || ! $settings->has( 'logging_enabled' ) || ! $settings->get( 'logging_enabled' ) ) {
|
||||||
return new NullLogger();
|
return new NullLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
$source = $container->get('woocommerce.logger.source');
|
$source = $container->get( 'woocommerce.logger.source' );
|
||||||
return new WooCommerceLogger(
|
return new WooCommerceLogger(
|
||||||
wc_get_logger(),
|
wc_get_logger(),
|
||||||
$source
|
$source
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
];
|
);
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* The module.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,87 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Admin;
|
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
|
||||||
|
|
||||||
class OrderTablePaymentStatusColumn {
|
|
||||||
|
|
||||||
private const COLUMN_KEY = 'ppcp_payment_status';
|
|
||||||
private const INTENT = 'authorize';
|
|
||||||
private const AFTER_COLUMN_KEY = 'order_status';
|
|
||||||
private $settings;
|
|
||||||
|
|
||||||
public function __construct( Settings $settings ) {
|
|
||||||
$this->settings = $settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function register( array $columns ): array {
|
|
||||||
if ( ! $this->settings->has( 'intent' ) || $this->settings->get( 'intent' ) !== self::INTENT ) {
|
|
||||||
return $columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
$statusColumnPosition = array_search( self::AFTER_COLUMN_KEY, array_keys( $columns ), true );
|
|
||||||
$toInsertPosition = false === $statusColumnPosition ? count( $columns ) : $statusColumnPosition + 1;
|
|
||||||
|
|
||||||
$columns = array_merge(
|
|
||||||
array_slice( $columns, 0, $toInsertPosition ),
|
|
||||||
array(
|
|
||||||
self::COLUMN_KEY => __( 'Payment Captured', 'woocommerce-paypal-commerce-gateway' ),
|
|
||||||
),
|
|
||||||
array_slice( $columns, $toInsertPosition )
|
|
||||||
);
|
|
||||||
|
|
||||||
return $columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render( string $column, int $wcOrderId ) {
|
|
||||||
if ( ! $this->settings->has( 'intent' ) || $this->settings->get( 'intent' ) !== self::INTENT ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( self::COLUMN_KEY !== $column ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$wcOrder = wc_get_order( $wcOrderId );
|
|
||||||
|
|
||||||
if ( ! is_a( $wcOrder, \WC_Order::class ) || ! $this->renderForOrder( $wcOrder ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $this->isCaptured( $wcOrder ) ) {
|
|
||||||
$this->renderCompletedStatus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->renderIncompletedStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function renderForOrder( \WC_Order $order ): bool {
|
|
||||||
return ! empty( $order->get_meta( PayPalGateway::CAPTURED_META_KEY ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private function isCaptured( \WC_Order $wcOrder ): bool {
|
|
||||||
$captured = $wcOrder->get_meta( PayPalGateway::CAPTURED_META_KEY );
|
|
||||||
return wc_string_to_bool( $captured );
|
|
||||||
}
|
|
||||||
|
|
||||||
private function renderCompletedStatus() {
|
|
||||||
printf(
|
|
||||||
'<span class="dashicons dashicons-yes">
|
|
||||||
<span class="screen-reader-text">%s</span>
|
|
||||||
</span>',
|
|
||||||
esc_html__( 'Payment captured', 'woocommerce-paypal-commerce-gateway' )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function renderIncompletedStatus() {
|
|
||||||
printf(
|
|
||||||
'<mark class="onbackorder">%s</mark>',
|
|
||||||
esc_html__( 'Not captured', 'woocommerce-paypal-commerce-gateway' )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Renders the columns to display to the merchant, which orders have been authorized and
|
||||||
|
* which have not been authorized yet.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Admin
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Inpsyde\PayPalCommerce\WcGateway\Admin;
|
||||||
|
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class OrderTablePaymentStatusColumn
|
||||||
|
*/
|
||||||
|
class OrderTablePaymentStatusColumn {
|
||||||
|
|
||||||
|
private const COLUMN_KEY = 'ppcp_payment_status';
|
||||||
|
private const INTENT = 'authorize';
|
||||||
|
private const AFTER_COLUMN_KEY = 'order_status';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
|
* @var Settings
|
||||||
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OrderTablePaymentStatusColumn constructor.
|
||||||
|
*
|
||||||
|
* @param Settings $settings The Settings.
|
||||||
|
*/
|
||||||
|
public function __construct( Settings $settings ) {
|
||||||
|
$this->settings = $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the columns.
|
||||||
|
*
|
||||||
|
* @param array $columns The existing columns.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function register( array $columns ): array {
|
||||||
|
if ( ! $this->settings->has( 'intent' ) || $this->settings->get( 'intent' ) !== self::INTENT ) {
|
||||||
|
return $columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
$status_column_position = array_search( self::AFTER_COLUMN_KEY, array_keys( $columns ), true );
|
||||||
|
$to_insert_position = false === $status_column_position ? count( $columns ) : $status_column_position + 1;
|
||||||
|
|
||||||
|
$columns = array_merge(
|
||||||
|
array_slice( $columns, 0, $to_insert_position ),
|
||||||
|
array(
|
||||||
|
self::COLUMN_KEY => __( 'Payment Captured', 'woocommerce-paypal-commerce-gateway' ),
|
||||||
|
),
|
||||||
|
array_slice( $columns, $to_insert_position )
|
||||||
|
);
|
||||||
|
|
||||||
|
return $columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the column.
|
||||||
|
*
|
||||||
|
* @param string $column The column.
|
||||||
|
* @param int $wc_order_id The id or the Woocommerce order.
|
||||||
|
*/
|
||||||
|
public function render( string $column, int $wc_order_id ) {
|
||||||
|
if ( ! $this->settings->has( 'intent' ) || $this->settings->get( 'intent' ) !== self::INTENT ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( self::COLUMN_KEY !== $column ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wc_order = wc_get_order( $wc_order_id );
|
||||||
|
|
||||||
|
if ( ! is_a( $wc_order, \WC_Order::class ) || ! $this->render_for_order( $wc_order ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->is_captured( $wc_order ) ) {
|
||||||
|
$this->render_completed_status();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->render_incomplete_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to render the authorization status of an order or not.
|
||||||
|
*
|
||||||
|
* @param \WC_Order $order The Woocommerce order.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function render_for_order( \WC_Order $order ): bool {
|
||||||
|
return ! empty( $order->get_meta( PayPalGateway::CAPTURED_META_KEY ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the order has been captured or not.
|
||||||
|
*
|
||||||
|
* @param \WC_Order $wc_order The Woocommerce order.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function is_captured( \WC_Order $wc_order ): bool {
|
||||||
|
$captured = $wc_order->get_meta( PayPalGateway::CAPTURED_META_KEY );
|
||||||
|
return wc_string_to_bool( $captured );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the captured status.
|
||||||
|
*/
|
||||||
|
private function render_completed_status() {
|
||||||
|
printf(
|
||||||
|
'<span class="dashicons dashicons-yes">
|
||||||
|
<span class="screen-reader-text">%s</span>
|
||||||
|
</span>',
|
||||||
|
esc_html__( 'Payment captured', 'woocommerce-paypal-commerce-gateway' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the "not captured" status.
|
||||||
|
*/
|
||||||
|
private function render_incomplete_status() {
|
||||||
|
printf(
|
||||||
|
'<mark class="onbackorder">%s</mark>',
|
||||||
|
esc_html__( 'Not captured', 'woocommerce-paypal-commerce-gateway' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Renders the not captured information.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Admin
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
@ -6,12 +11,20 @@ namespace Inpsyde\PayPalCommerce\WcGateway\Admin;
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PaymentStatusOrderDetail
|
||||||
|
*/
|
||||||
class PaymentStatusOrderDetail {
|
class PaymentStatusOrderDetail {
|
||||||
|
|
||||||
public function render( int $wcOrderId ) {
|
/**
|
||||||
$wcOrder = new \WC_Order( $wcOrderId );
|
* Renders the not captured information.
|
||||||
$intent = $wcOrder->get_meta( PayPalGateway::INTENT_META_KEY );
|
*
|
||||||
$captured = $wcOrder->get_meta( PayPalGateway::CAPTURED_META_KEY );
|
* @param int $wc_order_id The Woocommerce order id.
|
||||||
|
*/
|
||||||
|
public function render( int $wc_order_id ) {
|
||||||
|
$wc_order = new \WC_Order( $wc_order_id );
|
||||||
|
$intent = $wc_order->get_meta( PayPalGateway::INTENT_META_KEY );
|
||||||
|
$captured = $wc_order->get_meta( PayPalGateway::CAPTURED_META_KEY );
|
||||||
|
|
||||||
if ( strcasecmp( $intent, 'AUTHORIZE' ) !== 0 ) {
|
if ( strcasecmp( $intent, 'AUTHORIZE' ) !== 0 ) {
|
||||||
return;
|
return;
|
||||||
|
@ -31,7 +44,7 @@ class PaymentStatusOrderDetail {
|
||||||
esc_html__(
|
esc_html__(
|
||||||
'To capture the payment select capture action from the list below.',
|
'To capture the payment select capture action from the list below.',
|
||||||
'woocommerce-paypal-commerce-gateway'
|
'woocommerce-paypal-commerce-gateway'
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,124 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Checkout;
|
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Shipping;
|
|
||||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service that fills checkout address fields
|
|
||||||
* with address selected via PayPal
|
|
||||||
*/
|
|
||||||
class CheckoutPayPalAddressPreset {
|
|
||||||
|
|
||||||
|
|
||||||
private $shippingCache = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var SessionHandler
|
|
||||||
*/
|
|
||||||
private $sessionHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param SessionHandler $sessionHandler
|
|
||||||
*/
|
|
||||||
public function __construct( SessionHandler $sessionHandler ) {
|
|
||||||
$this->sessionHandler = $sessionHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @wp-hook woocommerce_checkout_get_value
|
|
||||||
* @param string|null
|
|
||||||
* @param string $fieldId
|
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function filterCheckoutFiled( $defaultValue, $fieldId ): ?string {
|
|
||||||
if ( ! is_string( $defaultValue ) ) {
|
|
||||||
$defaultValue = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! is_string( $fieldId ) ) {
|
|
||||||
return $defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->readPresetForField( $fieldId ) ?? $defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function readPresetForField( string $fieldId ): ?string {
|
|
||||||
$order = $this->sessionHandler->order();
|
|
||||||
if ( ! $order ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$shipping = $this->readShippingFromOrder();
|
|
||||||
$payer = $order->payer();
|
|
||||||
|
|
||||||
$addressMap = array(
|
|
||||||
'billing_address_1' => 'addressLine1',
|
|
||||||
'billing_address_2' => 'addressLine2',
|
|
||||||
'billing_postcode' => 'postalCode',
|
|
||||||
'billing_country' => 'countryCode',
|
|
||||||
'billing_city' => 'adminArea2',
|
|
||||||
'billing_state' => 'adminArea1',
|
|
||||||
);
|
|
||||||
$payerNameMap = array(
|
|
||||||
'billing_last_name' => 'surname',
|
|
||||||
'billing_first_name' => 'givenName',
|
|
||||||
);
|
|
||||||
$payerMap = array(
|
|
||||||
'billing_email' => 'emailAddress',
|
|
||||||
);
|
|
||||||
$payerPhoneMap = array(
|
|
||||||
'billing_phone' => 'nationalNumber',
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( array_key_exists( $fieldId, $addressMap ) && $shipping ) {
|
|
||||||
return $shipping->address()->{$addressMap[ $fieldId ]}() ?: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( array_key_exists( $fieldId, $payerNameMap ) && $payer ) {
|
|
||||||
return $payer->name()->{$payerNameMap[ $fieldId ]}() ?: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( array_key_exists( $fieldId, $payerMap ) && $payer ) {
|
|
||||||
return $payer->{$payerMap[ $fieldId ]}() ?: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
array_key_exists( $fieldId, $payerPhoneMap )
|
|
||||||
&& $payer
|
|
||||||
&& $payer->phone()
|
|
||||||
&& $payer->phone()->phone()
|
|
||||||
) {
|
|
||||||
return $payer->phone()->phone()->{$payerPhoneMap[ $fieldId ]}() ?: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function readShippingFromOrder(): ?Shipping {
|
|
||||||
$order = $this->sessionHandler->order();
|
|
||||||
if ( ! $order ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( array_key_exists( $order->id(), $this->shippingCache ) ) {
|
|
||||||
return $this->shippingCache[ $order->id() ];
|
|
||||||
}
|
|
||||||
|
|
||||||
$shipping = null;
|
|
||||||
foreach ( $this->sessionHandler->order()->purchaseUnits() as $unit ) {
|
|
||||||
$shipping = $unit->shipping();
|
|
||||||
if ( $shipping ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->shippingCache[ $order->id() ] = $shipping;
|
|
||||||
|
|
||||||
return $shipping;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Checkout;
|
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
||||||
use Psr\Container\ContainerInterface;
|
|
||||||
|
|
||||||
class DisableGateways {
|
|
||||||
|
|
||||||
|
|
||||||
private $sessionHandler;
|
|
||||||
private $settings;
|
|
||||||
public function __construct(
|
|
||||||
SessionHandler $sessionHandler,
|
|
||||||
ContainerInterface $settings
|
|
||||||
) {
|
|
||||||
|
|
||||||
$this->sessionHandler = $sessionHandler;
|
|
||||||
$this->settings = $settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handler( array $methods ): array {
|
|
||||||
if ( ! isset( $methods[ PayPalGateway::ID ] ) && ! isset( $methods[ CreditCardGateway::ID ] ) ) {
|
|
||||||
return $methods;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
! $this->settings->has( 'merchant_email' )
|
|
||||||
|| ! is_email( $this->settings->get( 'merchant_email' ) )
|
|
||||||
) {
|
|
||||||
unset( $methods[ PayPalGateway::ID ] );
|
|
||||||
unset( $methods[ CreditCardGateway::ID ] );
|
|
||||||
return $methods;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! $this->settings->has( 'client_id' ) || empty( $this->settings->get( 'client_id' ) ) ) {
|
|
||||||
unset( $methods[ CreditCardGateway::ID ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! $this->needsToDisableGateways() ) {
|
|
||||||
return $methods;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $this->isCreditCard() ) {
|
|
||||||
return array( CreditCardGateway::ID => $methods[ CreditCardGateway::ID ] );
|
|
||||||
}
|
|
||||||
return array( PayPalGateway::ID => $methods[ PayPalGateway::ID ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
private function needsToDisableGateways(): bool {
|
|
||||||
return $this->sessionHandler->order() !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function isCreditCard(): bool {
|
|
||||||
$order = $this->sessionHandler->order();
|
|
||||||
if ( ! $order ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( ! $order->paymentSource() || ! $order->paymentSource()->card() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Service that fills checkout address fields
|
||||||
|
* with address selected via PayPal
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Checkout
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Inpsyde\PayPalCommerce\WcGateway\Checkout;
|
||||||
|
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Entity\Shipping;
|
||||||
|
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CheckoutPayPalAddressPreset
|
||||||
|
*/
|
||||||
|
class CheckoutPayPalAddressPreset {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches Shipping objects for orders.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $shipping_cache = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Session Handler.
|
||||||
|
*
|
||||||
|
* @var SessionHandler
|
||||||
|
*/
|
||||||
|
private $session_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CheckoutPayPalAddressPreset constructor.
|
||||||
|
*
|
||||||
|
* @param SessionHandler $session_handler The session handler.
|
||||||
|
*/
|
||||||
|
public function __construct( SessionHandler $session_handler ) {
|
||||||
|
$this->session_handler = $session_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the checkout fields to replace values if necessary.
|
||||||
|
*
|
||||||
|
* @wp-hook woocommerce_checkout_get_value
|
||||||
|
*
|
||||||
|
* @param string|null $default_value The default value.
|
||||||
|
* @param string $field_id The field ID.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function filter_checkout_field( $default_value, $field_id ): ?string {
|
||||||
|
if ( ! is_string( $default_value ) ) {
|
||||||
|
$default_value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! is_string( $field_id ) ) {
|
||||||
|
return $default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->read_preset_for_field( $field_id ) ?? $default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value for a checkout field from an PayPal order if given.
|
||||||
|
*
|
||||||
|
* @param string $field_id The ID of the field.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
private function read_preset_for_field( string $field_id ): ?string {
|
||||||
|
$order = $this->session_handler->order();
|
||||||
|
if ( ! $order ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$shipping = $this->read_shipping_from_order();
|
||||||
|
$payer = $order->payer();
|
||||||
|
|
||||||
|
$address_map = array(
|
||||||
|
'billing_address_1' => 'addressLine1',
|
||||||
|
'billing_address_2' => 'addressLine2',
|
||||||
|
'billing_postcode' => 'postalCode',
|
||||||
|
'billing_country' => 'countryCode',
|
||||||
|
'billing_city' => 'adminArea2',
|
||||||
|
'billing_state' => 'adminArea1',
|
||||||
|
);
|
||||||
|
$payer_name_map = array(
|
||||||
|
'billing_last_name' => 'surname',
|
||||||
|
'billing_first_name' => 'givenName',
|
||||||
|
);
|
||||||
|
$payer_map = array(
|
||||||
|
'billing_email' => 'emailAddress',
|
||||||
|
);
|
||||||
|
$payer_phone_map = array(
|
||||||
|
'billing_phone' => 'nationalNumber',
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( array_key_exists( $field_id, $address_map ) && $shipping ) {
|
||||||
|
return $shipping->address()->{$address_map[ $field_id ]}() ? $shipping->address()->{$address_map[ $field_id ]}() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( array_key_exists( $field_id, $payer_name_map ) && $payer ) {
|
||||||
|
return $payer->name()->{$payer_name_map[ $field_id ]}() ? $payer->name()->{$payer_name_map[ $field_id ]}() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( array_key_exists( $field_id, $payer_map ) && $payer ) {
|
||||||
|
return $payer->{$payer_map[ $field_id ]}() ? $payer->{$payer_map[ $field_id ]}() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
array_key_exists( $field_id, $payer_phone_map )
|
||||||
|
&& $payer
|
||||||
|
&& $payer->phone()
|
||||||
|
&& $payer->phone()->phone()
|
||||||
|
) {
|
||||||
|
return $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() ? $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Shipping object for an order, if given.
|
||||||
|
*
|
||||||
|
* @return Shipping|null
|
||||||
|
*/
|
||||||
|
private function read_shipping_from_order(): ?Shipping {
|
||||||
|
$order = $this->session_handler->order();
|
||||||
|
if ( ! $order ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( array_key_exists( $order->id(), $this->shipping_cache ) ) {
|
||||||
|
return $this->shipping_cache[ $order->id() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
$shipping = null;
|
||||||
|
foreach ( $this->session_handler->order()->purchaseUnits() as $unit ) {
|
||||||
|
$shipping = $unit->shipping();
|
||||||
|
if ( $shipping ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->shipping_cache[ $order->id() ] = $shipping;
|
||||||
|
|
||||||
|
return $shipping;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Determines whether specific gateways need to be disabled.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Checkout
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Inpsyde\PayPalCommerce\WcGateway\Checkout;
|
||||||
|
|
||||||
|
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class DisableGateways
|
||||||
|
*/
|
||||||
|
class DisableGateways {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Session Handler.
|
||||||
|
*
|
||||||
|
* @var SessionHandler
|
||||||
|
*/
|
||||||
|
private $session_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Settings.
|
||||||
|
*
|
||||||
|
* @var ContainerInterface
|
||||||
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisableGateways constructor.
|
||||||
|
*
|
||||||
|
* @param SessionHandler $session_handler The Session Handler.
|
||||||
|
* @param ContainerInterface $settings The Settings.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
SessionHandler $session_handler,
|
||||||
|
ContainerInterface $settings
|
||||||
|
) {
|
||||||
|
|
||||||
|
$this->session_handler = $session_handler;
|
||||||
|
$this->settings = $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the logic for enabling/disabling gateways.
|
||||||
|
*
|
||||||
|
* @param array $methods The Gateways.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function handler( array $methods ): array {
|
||||||
|
if ( ! isset( $methods[ PayPalGateway::ID ] ) && ! isset( $methods[ CreditCardGateway::ID ] ) ) {
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
! $this->settings->has( 'merchant_email' )
|
||||||
|
|| ! is_email( $this->settings->get( 'merchant_email' ) )
|
||||||
|
) {
|
||||||
|
unset( $methods[ PayPalGateway::ID ] );
|
||||||
|
unset( $methods[ CreditCardGateway::ID ] );
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $this->settings->has( 'client_id' ) || empty( $this->settings->get( 'client_id' ) ) ) {
|
||||||
|
unset( $methods[ CreditCardGateway::ID ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $this->needs_to_disable_gateways() ) {
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->is_credit_card() ) {
|
||||||
|
return array( CreditCardGateway::ID => $methods[ CreditCardGateway::ID ] );
|
||||||
|
}
|
||||||
|
return array( PayPalGateway::ID => $methods[ PayPalGateway::ID ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the Gateways need to be disabled. When we come to the checkout with a running PayPal
|
||||||
|
* session, we need to disable the other Gateways, so the customer can smoothly sail through the
|
||||||
|
* process.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function needs_to_disable_gateways(): bool {
|
||||||
|
return $this->session_handler->order() !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the current PayPal session is done via DCC payment.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function is_credit_card(): bool {
|
||||||
|
$order = $this->session_handler->order();
|
||||||
|
if ( ! $order ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( ! $order->paymentSource() || ! $order->paymentSource()->card() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,52 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Endpoint;
|
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
||||||
use Inpsyde\PayPalCommerce\Webhooks\Handler\PrefixTrait;
|
|
||||||
|
|
||||||
class ReturnUrlEndpoint {
|
|
||||||
|
|
||||||
use PrefixTrait;
|
|
||||||
public const ENDPOINT = 'ppc-return-url';
|
|
||||||
|
|
||||||
private $gateway;
|
|
||||||
private $orderEndpoint;
|
|
||||||
public function __construct( PayPalGateway $gateway, OrderEndpoint $orderEndpoint, string $prefix ) {
|
|
||||||
$this->gateway = $gateway;
|
|
||||||
$this->orderEndpoint = $orderEndpoint;
|
|
||||||
$this->prefix = $prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handleRequest() {
|
|
||||||
|
|
||||||
if ( ! isset( $_GET['token'] ) ) {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
|
|
||||||
$order = $this->orderEndpoint->order( $token );
|
|
||||||
if ( ! $order ) {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$wcOrderId = $this->sanitize_custom_id( $order->purchaseUnits()[0]->customId() );
|
|
||||||
if ( ! $wcOrderId ) {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$wcOrder = wc_get_order( $wcOrderId );
|
|
||||||
if ( ! $wcOrder ) {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$success = $this->gateway->process_payment( $wcOrderId );
|
|
||||||
if ( isset( $success['result'] ) && $success['result'] === 'success' ) {
|
|
||||||
wp_redirect( $success['redirect'] );
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
wp_redirect( wc_get_checkout_url() );
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Controls the endpoint for customers returning from PayPal.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Endpoint
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Inpsyde\PayPalCommerce\WcGateway\Endpoint;
|
||||||
|
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
use Inpsyde\PayPalCommerce\Webhooks\Handler\PrefixTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ReturnUrlEndpoint
|
||||||
|
*/
|
||||||
|
class ReturnUrlEndpoint {
|
||||||
|
|
||||||
|
use PrefixTrait;
|
||||||
|
public const ENDPOINT = 'ppc-return-url';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PayPal Gateway.
|
||||||
|
*
|
||||||
|
* @var PayPalGateway
|
||||||
|
*/
|
||||||
|
private $gateway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Order Endpoint.
|
||||||
|
*
|
||||||
|
* @var OrderEndpoint
|
||||||
|
*/
|
||||||
|
private $order_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ReturnUrlEndpoint constructor.
|
||||||
|
*
|
||||||
|
* @param PayPalGateway $gateway The PayPal Gateway.
|
||||||
|
* @param OrderEndpoint $order_endpoint The Order Endpoint.
|
||||||
|
* @param string $prefix The prefix.
|
||||||
|
*/
|
||||||
|
public function __construct( PayPalGateway $gateway, OrderEndpoint $order_endpoint, string $prefix ) {
|
||||||
|
$this->gateway = $gateway;
|
||||||
|
$this->order_endpoint = $order_endpoint;
|
||||||
|
$this->prefix = $prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the incoming request.
|
||||||
|
*/
|
||||||
|
public function handle_request() {
|
||||||
|
|
||||||
|
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
|
if ( ! isset( $_GET['token'] ) ) {
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
|
||||||
|
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||||
|
$order = $this->order_endpoint->order( $token );
|
||||||
|
if ( ! $order ) {
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$wc_order_id = $this->sanitize_custom_id( $order->purchaseUnits()[0]->customId() );
|
||||||
|
if ( ! $wc_order_id ) {
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$wc_order = wc_get_order( $wc_order_id );
|
||||||
|
if ( ! $wc_order ) {
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$success = $this->gateway->process_payment( $wc_order_id );
|
||||||
|
if ( isset( $success['result'] ) && 'success' === $success['result'] ) {
|
||||||
|
wp_safe_redirect( $success['redirect'] );
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
wp_safe_redirect( wc_get_checkout_url() );
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* The Not Found Exception for the Settings Container.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Exception
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
@ -7,6 +12,9 @@ namespace Inpsyde\PayPalCommerce\WcGateway\Exception;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Psr\Container\NotFoundExceptionInterface;
|
use Psr\Container\NotFoundExceptionInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class NotFoundException
|
||||||
|
*/
|
||||||
class NotFoundException extends Exception implements NotFoundExceptionInterface {
|
class NotFoundException extends Exception implements NotFoundExceptionInterface {
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Gateway;
|
|
||||||
|
|
||||||
interface WcGatewayInterface {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* The Credit card gateway.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Gateway
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
@ -11,32 +16,48 @@ use Inpsyde\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
//phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
|
/**
|
||||||
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
* Class CreditCardGateway
|
||||||
//phpcs:disable Inpsyde.CodeQuality.NoAccessors.NoGetter
|
*/
|
||||||
//phpcs:disable Inpsyde.CodeQuality.ReturnTypeDeclaration.NoReturnType
|
|
||||||
class CreditCardGateway extends PayPalGateway {
|
class CreditCardGateway extends PayPalGateway {
|
||||||
|
|
||||||
public const ID = 'ppcp-credit-card-gateway';
|
public const ID = 'ppcp-credit-card-gateway';
|
||||||
|
|
||||||
private $moduleUrl;
|
/**
|
||||||
|
* The URL to the module.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $module_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreditCardGateway 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 Notices.
|
||||||
|
* @param ContainerInterface $config The settings.
|
||||||
|
* @param string $module_url The URL to the module.
|
||||||
|
* @param SessionHandler $session_handler The Session Handler.
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SettingsRenderer $settingsRenderer,
|
SettingsRenderer $settings_renderer,
|
||||||
OrderProcessor $orderProcessor,
|
OrderProcessor $order_processor,
|
||||||
AuthorizedPaymentsProcessor $authorizedPayments,
|
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
||||||
AuthorizeOrderActionNotice $notice,
|
AuthorizeOrderActionNotice $notice,
|
||||||
ContainerInterface $config,
|
ContainerInterface $config,
|
||||||
string $moduleUrl,
|
string $module_url,
|
||||||
SessionHandler $sessionHandler
|
SessionHandler $session_handler
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$this->id = self::ID;
|
$this->id = self::ID;
|
||||||
$this->orderProcessor = $orderProcessor;
|
$this->order_processor = $order_processor;
|
||||||
$this->authorizedPayments = $authorizedPayments;
|
$this->authorized_payments = $authorized_payments_processor;
|
||||||
$this->notice = $notice;
|
$this->notice = $notice;
|
||||||
$this->settingsRenderer = $settingsRenderer;
|
$this->settings_renderer = $settings_renderer;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->sessionHandler = $sessionHandler;
|
$this->session_handler = $session_handler;
|
||||||
if (
|
if (
|
||||||
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
||||||
&& PPCP_FLAG_SUBSCRIPTION
|
&& PPCP_FLAG_SUBSCRIPTION
|
||||||
|
@ -82,9 +103,12 @@ class CreditCardGateway extends PayPalGateway {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->moduleUrl = $moduleUrl;
|
$this->module_url = $module_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the form fields.
|
||||||
|
*/
|
||||||
public function init_form_fields() {
|
public function init_form_fields() {
|
||||||
$this->form_fields = array(
|
$this->form_fields = array(
|
||||||
'enabled' => array(
|
'enabled' => array(
|
||||||
|
@ -99,15 +123,25 @@ class CreditCardGateway extends PayPalGateway {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the settings.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function generate_ppcp_html(): string {
|
public function generate_ppcp_html(): string {
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
$this->settingsRenderer->render( true );
|
$this->settings_renderer->render( true );
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the title of the gateway.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function get_title() {
|
public function get_title() {
|
||||||
|
|
||||||
if ( is_admin() ) {
|
if ( is_admin() ) {
|
||||||
|
@ -119,12 +153,12 @@ class CreditCardGateway extends PayPalGateway {
|
||||||
return $title;
|
return $title;
|
||||||
}
|
}
|
||||||
|
|
||||||
$titleOptions = $this->cardLabels();
|
$title_options = $this->card_labels();
|
||||||
$images = array_map(
|
$images = array_map(
|
||||||
function ( string $type ) use ( $titleOptions ): string {
|
function ( string $type ) use ( $title_options ): string {
|
||||||
return '<img
|
return '<img
|
||||||
title="' . esc_attr( $titleOptions[ $type ] ) . '"
|
title="' . esc_attr( $title_options[ $type ] ) . '"
|
||||||
src="' . esc_url( $this->moduleUrl ) . '/assets/images/' . esc_attr( $type ) . '.svg"
|
src="' . esc_url( $this->module_url ) . '/assets/images/' . esc_attr( $type ) . '.svg"
|
||||||
class="ppcp-card-icon"
|
class="ppcp-card-icon"
|
||||||
> ';
|
> ';
|
||||||
},
|
},
|
||||||
|
@ -133,7 +167,12 @@ class CreditCardGateway extends PayPalGateway {
|
||||||
return $title . implode( '', $images );
|
return $title . implode( '', $images );
|
||||||
}
|
}
|
||||||
|
|
||||||
private function cardLabels(): array {
|
/**
|
||||||
|
* Returns an array of credit card names.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function card_labels(): array {
|
||||||
return array(
|
return array(
|
||||||
'visa' => _x(
|
'visa' => _x(
|
||||||
'Visa',
|
'Visa',
|
|
@ -1,59 +1,100 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* The PayPal Payment Gateway
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Gateway
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Gateway;
|
namespace Inpsyde\PayPalCommerce\WcGateway\Gateway;
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\CartRepository;
|
|
||||||
use Inpsyde\PayPalCommerce\Button\Assets\SmartButton;
|
|
||||||
use Inpsyde\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
|
|
||||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
use Inpsyde\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
use Inpsyde\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
use Inpsyde\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsFields;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
//phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
|
/**
|
||||||
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
* Class PayPalGateway
|
||||||
|
*/
|
||||||
class PayPalGateway extends \WC_Payment_Gateway {
|
class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
|
|
||||||
|
|
||||||
public const ID = 'ppcp-gateway';
|
public const ID = 'ppcp-gateway';
|
||||||
public const CAPTURED_META_KEY = '_ppcp_paypal_captured';
|
public const CAPTURED_META_KEY = '_ppcp_paypal_captured';
|
||||||
public const INTENT_META_KEY = '_ppcp_paypal_intent';
|
public const INTENT_META_KEY = '_ppcp_paypal_intent';
|
||||||
public const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
|
public const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
|
||||||
|
|
||||||
protected $settingsRenderer;
|
/**
|
||||||
protected $authorizedPayments;
|
* The Settings Renderer.
|
||||||
protected $notice;
|
*
|
||||||
protected $orderProcessor;
|
* @var SettingsRenderer
|
||||||
protected $config;
|
*/
|
||||||
protected $sessionHandler;
|
protected $settings_renderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The processor for authorized payments.
|
||||||
|
*
|
||||||
|
* @var AuthorizedPaymentsProcessor
|
||||||
|
*/
|
||||||
|
protected $authorized_payments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Authorized Order Action Notice.
|
||||||
|
*
|
||||||
|
* @var AuthorizeOrderActionNotice
|
||||||
|
*/
|
||||||
|
protected $notice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The processor for orders.
|
||||||
|
*
|
||||||
|
* @var OrderProcessor
|
||||||
|
*/
|
||||||
|
protected $order_processor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
|
* @var ContainerInterface
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Session Handler.
|
||||||
|
*
|
||||||
|
* @var SessionHandler
|
||||||
|
*/
|
||||||
|
protected $session_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SettingsRenderer $settingsRenderer,
|
SettingsRenderer $settings_renderer,
|
||||||
OrderProcessor $orderProcessor,
|
OrderProcessor $order_processor,
|
||||||
AuthorizedPaymentsProcessor $authorizedPayments,
|
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
||||||
AuthorizeOrderActionNotice $notice,
|
AuthorizeOrderActionNotice $notice,
|
||||||
ContainerInterface $config,
|
ContainerInterface $config,
|
||||||
SessionHandler $sessionHandler
|
SessionHandler $session_handler
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$this->id = self::ID;
|
$this->id = self::ID;
|
||||||
$this->orderProcessor = $orderProcessor;
|
$this->order_processor = $order_processor;
|
||||||
$this->authorizedPayments = $authorizedPayments;
|
$this->authorized_payments = $authorized_payments_processor;
|
||||||
$this->notice = $notice;
|
$this->notice = $notice;
|
||||||
$this->settingsRenderer = $settingsRenderer;
|
$this->settings_renderer = $settings_renderer;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->sessionHandler = $sessionHandler;
|
$this->session_handler = $session_handler;
|
||||||
if (
|
if (
|
||||||
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
||||||
&& PPCP_FLAG_SUBSCRIPTION
|
&& PPCP_FLAG_SUBSCRIPTION
|
||||||
|
@ -97,11 +138,19 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the Gateway needs to be setup.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function needs_setup(): bool {
|
public function needs_setup(): bool {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the form fields.
|
||||||
|
*/
|
||||||
public function init_form_fields() {
|
public function init_form_fields() {
|
||||||
$this->form_fields = array(
|
$this->form_fields = array(
|
||||||
'enabled' => array(
|
'enabled' => array(
|
||||||
|
@ -116,10 +165,17 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function process_payment( $orderId ): ?array {
|
/**
|
||||||
|
* Process a payment for an Woocommerce order.
|
||||||
|
*
|
||||||
|
* @param int $order_id The Woocommerce order id.
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
public function process_payment( $order_id ): ?array {
|
||||||
global $woocommerce;
|
global $woocommerce;
|
||||||
$wcOrder = wc_get_order( $orderId );
|
$wc_order = wc_get_order( $order_id );
|
||||||
if ( ! is_a( $wcOrder, \WC_Order::class ) ) {
|
if ( ! is_a( $wc_order, \WC_Order::class ) ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,26 +183,26 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
* If the WC_Order is payed through the approved webhook.
|
* If the WC_Order is payed through the approved webhook.
|
||||||
*/
|
*/
|
||||||
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wcOrder->has_status( 'processing' ) ) {
|
if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wc_order->has_status( 'processing' ) ) {
|
||||||
return array(
|
return array(
|
||||||
'result' => 'success',
|
'result' => 'success',
|
||||||
'redirect' => $this->get_return_url( $wcOrder ),
|
'redirect' => $this->get_return_url( $wc_order ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( $this->orderProcessor->process( $wcOrder, $woocommerce ) ) {
|
if ( $this->order_processor->process( $wc_order, $woocommerce ) ) {
|
||||||
return array(
|
return array(
|
||||||
'result' => 'success',
|
'result' => 'success',
|
||||||
'redirect' => $this->get_return_url( $wcOrder ),
|
'redirect' => $this->get_return_url( $wc_order ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch ( PayPalApiException $error ) {
|
} catch ( PayPalApiException $error ) {
|
||||||
if ( $error->hasDetail( 'INSTRUMENT_DECLINED' ) ) {
|
if ( $error->hasDetail( 'INSTRUMENT_DECLINED' ) ) {
|
||||||
$host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ?
|
$host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ?
|
||||||
'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/';
|
'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/';
|
||||||
$url = $host . 'checkoutnow?token=' . $this->sessionHandler->order()->id();
|
$url = $host . 'checkoutnow?token=' . $this->session_handler->order()->id();
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'result' => 'success',
|
'result' => 'success',
|
||||||
|
@ -154,7 +210,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sessionHandler->destroySessionData();
|
$this->session_handler->destroySessionData();
|
||||||
wc_add_notice(
|
wc_add_notice(
|
||||||
__(
|
__(
|
||||||
'Something went wrong. Please try again.',
|
'Something went wrong. Please try again.',
|
||||||
|
@ -167,54 +223,71 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function captureAuthorizedPayment( \WC_Order $wcOrder ): bool {
|
/**
|
||||||
$isProcessed = $this->authorizedPayments->process( $wcOrder );
|
* Captures an authorized payment for an Woocommerce order.
|
||||||
$this->renderAuthorizationMessageForStatus( $this->authorizedPayments->lastStatus() );
|
*
|
||||||
|
* @param \WC_Order $wc_order The Woocommerce order.
|
||||||
|
*
|
||||||
|
* @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() );
|
||||||
|
|
||||||
if ( $isProcessed ) {
|
if ( $is_processed ) {
|
||||||
$wcOrder->add_order_note(
|
$wc_order->add_order_note(
|
||||||
__( 'Payment successfully captured.', 'woocommerce-paypal-commerce-gateway' )
|
__( 'Payment successfully captured.', 'woocommerce-paypal-commerce-gateway' )
|
||||||
);
|
);
|
||||||
|
|
||||||
$wcOrder->set_status( 'processing' );
|
$wc_order->set_status( 'processing' );
|
||||||
$wcOrder->update_meta_data( self::CAPTURED_META_KEY, 'true' );
|
$wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
|
||||||
$wcOrder->save();
|
$wc_order->save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->authorizedPayments->lastStatus() === AuthorizedPaymentsProcessor::ALREADY_CAPTURED ) {
|
if ( $this->authorized_payments->last_status() === AuthorizedPaymentsProcessor::ALREADY_CAPTURED ) {
|
||||||
if ( $wcOrder->get_status() === 'on-hold' ) {
|
if ( $wc_order->get_status() === 'on-hold' ) {
|
||||||
$wcOrder->add_order_note(
|
$wc_order->add_order_note(
|
||||||
__( 'Payment successfully captured.', 'woocommerce-paypal-commerce-gateway' )
|
__( 'Payment successfully captured.', 'woocommerce-paypal-commerce-gateway' )
|
||||||
);
|
);
|
||||||
$wcOrder->set_status( 'processing' );
|
$wc_order->set_status( 'processing' );
|
||||||
}
|
}
|
||||||
|
|
||||||
$wcOrder->update_meta_data( self::CAPTURED_META_KEY, 'true' );
|
$wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
|
||||||
$wcOrder->save();
|
$wc_order->save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderAuthorizationMessageForStatus( string $status ) {
|
/**
|
||||||
|
* Displays the notice for a status.
|
||||||
|
*
|
||||||
|
* @param string $status The status.
|
||||||
|
*/
|
||||||
|
private function render_authorization_message_for_status( string $status ) {
|
||||||
|
|
||||||
$messageMapping = array(
|
$message_mapping = array(
|
||||||
AuthorizedPaymentsProcessor::SUCCESSFUL => AuthorizeOrderActionNotice::SUCCESS,
|
AuthorizedPaymentsProcessor::SUCCESSFUL => AuthorizeOrderActionNotice::SUCCESS,
|
||||||
AuthorizedPaymentsProcessor::ALREADY_CAPTURED => AuthorizeOrderActionNotice::ALREADY_CAPTURED,
|
AuthorizedPaymentsProcessor::ALREADY_CAPTURED => AuthorizeOrderActionNotice::ALREADY_CAPTURED,
|
||||||
AuthorizedPaymentsProcessor::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
|
AuthorizedPaymentsProcessor::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
|
||||||
AuthorizedPaymentsProcessor::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
|
AuthorizedPaymentsProcessor::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
|
||||||
);
|
);
|
||||||
$displayMessage = ( isset( $messageMapping[ $status ] ) ) ?
|
$display_message = ( isset( $message_mapping[ $status ] ) ) ?
|
||||||
$messageMapping[ $status ]
|
$message_mapping[ $status ]
|
||||||
: AuthorizeOrderActionNotice::FAILED;
|
: AuthorizeOrderActionNotice::FAILED;
|
||||||
$this->notice->displayMessage( $displayMessage );
|
$this->notice->display_message( $display_message );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the settings.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function generate_ppcp_html(): string {
|
public function generate_ppcp_html(): string {
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
$this->settingsRenderer->render( false );
|
$this->settings_renderer->render( false );
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
return $content;
|
return $content;
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The WcGateway interface.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Gateway
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Inpsyde\PayPalCommerce\WcGateway\Gateway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface WcGatewayInterface
|
||||||
|
*/
|
||||||
|
interface WcGatewayInterface {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Contains the messages to display, when capturing an authorization manually.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Notice
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
@ -6,6 +11,9 @@ namespace Inpsyde\PayPalCommerce\WcGateway\Notice;
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\AdminNotices\Entity\Message;
|
use Inpsyde\PayPalCommerce\AdminNotices\Entity\Message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AuthorizeOrderActionNotice
|
||||||
|
*/
|
||||||
class AuthorizeOrderActionNotice {
|
class AuthorizeOrderActionNotice {
|
||||||
|
|
||||||
public const QUERY_PARAM = 'ppcp-authorized-message';
|
public const QUERY_PARAM = 'ppcp-authorized-message';
|
||||||
|
@ -16,9 +24,14 @@ class AuthorizeOrderActionNotice {
|
||||||
public const SUCCESS = 84;
|
public const SUCCESS = 84;
|
||||||
public const NOT_FOUND = 85;
|
public const NOT_FOUND = 85;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current message if there is one.
|
||||||
|
*
|
||||||
|
* @return Message|null
|
||||||
|
*/
|
||||||
public function message(): ?Message {
|
public function message(): ?Message {
|
||||||
|
|
||||||
$message = $this->currentMessage();
|
$message = $this->current_message();
|
||||||
if ( ! $message ) {
|
if ( ! $message ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +39,12 @@ class AuthorizeOrderActionNotice {
|
||||||
return new Message( $message['message'], $message['type'] );
|
return new Message( $message['message'], $message['type'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
private function currentMessage(): array {
|
/**
|
||||||
|
* Returns the current message.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function current_message(): array {
|
||||||
$messages[ self::NO_INFO ] = array(
|
$messages[ self::NO_INFO ] = array(
|
||||||
'message' => __(
|
'message' => __(
|
||||||
'Could not retrieve information. Try again later.',
|
'Could not retrieve information. Try again later.',
|
||||||
|
@ -67,18 +85,23 @@ class AuthorizeOrderActionNotice {
|
||||||
if ( ! isset( $_GET[ self::QUERY_PARAM ] ) ) { // Input ok.
|
if ( ! isset( $_GET[ self::QUERY_PARAM ] ) ) { // Input ok.
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
$messageId = absint( $_GET[ self::QUERY_PARAM ] ); // Input ok.
|
$message_id = absint( $_GET[ self::QUERY_PARAM ] ); // Input ok.
|
||||||
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||||
return ( isset( $messages[ $messageId ] ) ) ? $messages[ $messageId ] : array();
|
return ( isset( $messages[ $message_id ] ) ) ? $messages[ $message_id ] : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function displayMessage( int $messageCode ): void {
|
/**
|
||||||
|
* Adds the query parameter for the message to 'redirect_post_location'.
|
||||||
|
*
|
||||||
|
* @param int $message_code The message code.
|
||||||
|
*/
|
||||||
|
public function display_message( int $message_code ): void {
|
||||||
add_filter(
|
add_filter(
|
||||||
'redirect_post_location',
|
'redirect_post_location',
|
||||||
static function ( $location ) use ( $messageCode ) {
|
static function ( $location ) use ( $message_code ) {
|
||||||
return add_query_arg(
|
return add_query_arg(
|
||||||
self::QUERY_PARAM,
|
self::QUERY_PARAM,
|
||||||
$messageCode,
|
$message_code,
|
||||||
$location
|
$location
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -1,4 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Registers the admin message to "connect your account" if necessary.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Notice
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
@ -9,35 +14,63 @@ use Inpsyde\PayPalCommerce\Onboarding\State;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ConnectAdminNotice
|
||||||
|
*/
|
||||||
class ConnectAdminNotice {
|
class ConnectAdminNotice {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state.
|
||||||
|
*
|
||||||
|
* @var State
|
||||||
|
*/
|
||||||
private $state;
|
private $state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
|
* @var ContainerInterface
|
||||||
|
*/
|
||||||
private $settings;
|
private $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConnectAdminNotice constructor.
|
||||||
|
*
|
||||||
|
* @param State $state The state.
|
||||||
|
* @param ContainerInterface $settings The settings.
|
||||||
|
*/
|
||||||
public function __construct( State $state, ContainerInterface $settings ) {
|
public function __construct( State $state, ContainerInterface $settings ) {
|
||||||
$this->state = $state;
|
$this->state = $state;
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function connectMessage(): ?Message {
|
/**
|
||||||
if ( ! $this->shouldDisplay() ) {
|
* Returns the message.
|
||||||
|
*
|
||||||
|
* @return Message|null
|
||||||
|
*/
|
||||||
|
public function connect_message(): ?Message {
|
||||||
|
if ( ! $this->should_display() ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = sprintf(
|
$message = sprintf(
|
||||||
/* translators: %1$s the gateway name */
|
/* translators: %1$s the gateway name. */
|
||||||
__(
|
__(
|
||||||
'PayPal Payments is almost ready. To get started, <a href="%1$s">connect your account</a>.',
|
'PayPal Payments is almost ready. To get started, <a href="%1$s">connect your account</a>.',
|
||||||
'woocommerce-paypal-commerce-gateway'
|
'woocommerce-paypal-commerce-gateway'
|
||||||
),
|
),
|
||||||
// TODO: find a better way to get the url
|
|
||||||
admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' )
|
admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' )
|
||||||
);
|
);
|
||||||
return new Message( $message, 'warning' );
|
return new Message( $message, 'warning' );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function shouldDisplay(): bool {
|
/**
|
||||||
// TODO: decide on what condition to display
|
* Whether the message should display.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function should_display(): bool {
|
||||||
return $this->state->currentState() < State::STATE_PROGRESSIVE;
|
return $this->state->currentState() < State::STATE_PROGRESSIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,110 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Processor;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Authorization;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
||||||
|
|
||||||
class AuthorizedPaymentsProcessor {
|
|
||||||
|
|
||||||
public const SUCCESSFUL = 'SUCCESSFUL';
|
|
||||||
public const ALREADY_CAPTURED = 'ALREADY_CAPTURED';
|
|
||||||
public const FAILED = 'FAILED';
|
|
||||||
public const INACCESSIBLE = 'INACCESSIBLE';
|
|
||||||
public const NOT_FOUND = 'NOT_FOUND';
|
|
||||||
private $orderEndpoint;
|
|
||||||
private $paymentsEndpoint;
|
|
||||||
private $lastStatus = '';
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
OrderEndpoint $orderEndpoint,
|
|
||||||
PaymentsEndpoint $paymentsEndpoint
|
|
||||||
) {
|
|
||||||
|
|
||||||
$this->orderEndpoint = $orderEndpoint;
|
|
||||||
$this->paymentsEndpoint = $paymentsEndpoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function process( \WC_Order $wcOrder ): bool {
|
|
||||||
try {
|
|
||||||
$order = $this->payPalOrderFromWcOrder( $wcOrder );
|
|
||||||
} catch ( Exception $exception ) {
|
|
||||||
if ( $exception->getCode() === 404 ) {
|
|
||||||
$this->lastStatus = self::NOT_FOUND;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$this->lastStatus = self::INACCESSIBLE;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$authorizations = $this->allAuthorizations( $order );
|
|
||||||
|
|
||||||
if ( ! $this->areAuthorizationToCapture( ...$authorizations ) ) {
|
|
||||||
$this->lastStatus = self::ALREADY_CAPTURED;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->captureAuthorizations( ...$authorizations );
|
|
||||||
} catch ( Exception $exception ) {
|
|
||||||
$this->lastStatus = self::FAILED;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->lastStatus = self::SUCCESSFUL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lastStatus(): string {
|
|
||||||
|
|
||||||
return $this->lastStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function payPalOrderFromWcOrder( \WC_Order $wcOrder ): Order {
|
|
||||||
$orderId = $wcOrder->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
|
||||||
return $this->orderEndpoint->order( $orderId );
|
|
||||||
}
|
|
||||||
|
|
||||||
private function allAuthorizations( Order $order ): array {
|
|
||||||
$authorizations = array();
|
|
||||||
foreach ( $order->purchaseUnits() as $purchaseUnit ) {
|
|
||||||
foreach ( $purchaseUnit->payments()->authorizations() as $authorization ) {
|
|
||||||
$authorizations[] = $authorization;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $authorizations;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function areAuthorizationToCapture( Authorization ...$authorizations ): bool {
|
|
||||||
return (bool) count( $this->authorizationsToCapture( ...$authorizations ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private function captureAuthorizations( Authorization ...$authorizations ) {
|
|
||||||
$uncapturedAuthorizations = $this->authorizationsToCapture( ...$authorizations );
|
|
||||||
foreach ( $uncapturedAuthorizations as $authorization ) {
|
|
||||||
$this->paymentsEndpoint->capture( $authorization->id() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Authorization ...$authorizations
|
|
||||||
* @return Authorization[]
|
|
||||||
*/
|
|
||||||
private function authorizationsToCapture( Authorization ...$authorizations ): array {
|
|
||||||
return array_filter(
|
|
||||||
$authorizations,
|
|
||||||
static function ( Authorization $authorization ): bool {
|
|
||||||
return $authorization->status()->is( AuthorizationStatus::CREATED )
|
|
||||||
|| $authorization->status()->is( AuthorizationStatus::PENDING );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,165 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Processor;
|
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\CartRepository;
|
|
||||||
use Inpsyde\PayPalCommerce\Button\Helper\ThreeDSecure;
|
|
||||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
|
||||||
|
|
||||||
class OrderProcessor {
|
|
||||||
|
|
||||||
private $sessionHandler;
|
|
||||||
private $cartRepository;
|
|
||||||
private $orderEndpoint;
|
|
||||||
private $paymentsEndpoint;
|
|
||||||
private $orderFactory;
|
|
||||||
private $threedSecure;
|
|
||||||
private $authorizedPaymentsProcessor;
|
|
||||||
private $settings;
|
|
||||||
|
|
||||||
private $lastError = '';
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
SessionHandler $sessionHandler,
|
|
||||||
CartRepository $cartRepository,
|
|
||||||
OrderEndpoint $orderEndpoint,
|
|
||||||
PaymentsEndpoint $paymentsEndpoint,
|
|
||||||
OrderFactory $orderFactory,
|
|
||||||
ThreeDSecure $threedSecure,
|
|
||||||
AuthorizedPaymentsProcessor $authorizedPaymentsProcessor,
|
|
||||||
Settings $settings
|
|
||||||
) {
|
|
||||||
|
|
||||||
$this->sessionHandler = $sessionHandler;
|
|
||||||
$this->cartRepository = $cartRepository;
|
|
||||||
$this->orderEndpoint = $orderEndpoint;
|
|
||||||
$this->paymentsEndpoint = $paymentsEndpoint;
|
|
||||||
$this->orderFactory = $orderFactory;
|
|
||||||
$this->threedSecure = $threedSecure;
|
|
||||||
$this->authorizedPaymentsProcessor = $authorizedPaymentsProcessor;
|
|
||||||
$this->settings = $settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function process( \WC_Order $wcOrder, \WooCommerce $woocommerce ): bool {
|
|
||||||
$order = $this->sessionHandler->order();
|
|
||||||
$wcOrder->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
|
||||||
$wcOrder->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
|
||||||
|
|
||||||
$errorMessage = null;
|
|
||||||
if ( ! $order || ! $this->orderIsApproved( $order ) ) {
|
|
||||||
$errorMessage = __(
|
|
||||||
'The payment has not been approved yet.',
|
|
||||||
'woocommerce-paypal-commerce-gateway'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if ( $errorMessage ) {
|
|
||||||
$this->lastError = sprintf(
|
|
||||||
// translators: %s is the message of the error.
|
|
||||||
__( 'Payment error: %s', 'woocommerce-paypal-commerce-gateway' ),
|
|
||||||
$errorMessage
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$order = $this->patchOrder( $wcOrder, $order );
|
|
||||||
if ( $order->intent() === 'CAPTURE' ) {
|
|
||||||
$order = $this->orderEndpoint->capture( $order );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $order->intent() === 'AUTHORIZE' ) {
|
|
||||||
$order = $this->orderEndpoint->authorize( $order );
|
|
||||||
$wcOrder->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
|
|
||||||
}
|
|
||||||
|
|
||||||
$wcOrder->update_status(
|
|
||||||
'on-hold',
|
|
||||||
__( 'Awaiting payment.', 'woocommerce-paypal-commerce-gateway' )
|
|
||||||
);
|
|
||||||
if ( $order->status()->is( OrderStatus::COMPLETED ) && $order->intent() === 'CAPTURE' ) {
|
|
||||||
$wcOrder->update_status(
|
|
||||||
'processing',
|
|
||||||
__( 'Payment received.', 'woocommerce-paypal-commerce-gateway' )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $this->captureAuthorizedDownloads( $order ) && $this->authorizedPaymentsProcessor->process( $wcOrder ) ) {
|
|
||||||
$wcOrder->add_order_note(
|
|
||||||
__( 'Payment successfully captured.', 'woocommerce-paypal-commerce-gateway' )
|
|
||||||
);
|
|
||||||
$wcOrder->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
|
|
||||||
$wcOrder->update_status( 'processing' );
|
|
||||||
}
|
|
||||||
$woocommerce->cart->empty_cart();
|
|
||||||
$this->sessionHandler->destroySessionData();
|
|
||||||
$this->lastError = '';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function captureAuthorizedDownloads( Order $order ): bool {
|
|
||||||
if (
|
|
||||||
! $this->settings->has( 'capture_for_virtual_only' )
|
|
||||||
|| ! $this->settings->get( 'capture_for_virtual_only' )
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $order->intent() === 'CAPTURE' ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We fetch the order again as the authorize endpoint (from which the Order derives)
|
|
||||||
* drops the item's category, making it impossible to check, if purchase units contain
|
|
||||||
* physical goods.
|
|
||||||
*/
|
|
||||||
$order = $this->orderEndpoint->order( $order->id() );
|
|
||||||
|
|
||||||
foreach ( $order->purchaseUnits() as $unit ) {
|
|
||||||
if ( $unit->containsPhysicalGoodsItems() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lastError(): string {
|
|
||||||
|
|
||||||
return $this->lastError;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function patchOrder( \WC_Order $wcOrder, Order $order ): Order {
|
|
||||||
$updatedOrder = $this->orderFactory->fromWcOrder( $wcOrder, $order );
|
|
||||||
$order = $this->orderEndpoint->patchOrderWith( $order, $updatedOrder );
|
|
||||||
return $order;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function orderIsApproved( Order $order ): bool {
|
|
||||||
|
|
||||||
if ( $order->status()->is( OrderStatus::APPROVED ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! $order->paymentSource() || ! $order->paymentSource()->card() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$isApproved = in_array(
|
|
||||||
$this->threedSecure->proceedWithOrder( $order ),
|
|
||||||
array(
|
|
||||||
ThreeDSecure::NO_DECISION,
|
|
||||||
ThreeDSecure::PROCCEED,
|
|
||||||
),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
return $isApproved;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Authorizes payments for a given Woocommerce order.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Processor
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Inpsyde\PayPalCommerce\WcGateway\Processor;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AuthorizedPaymentsProcessor
|
||||||
|
*/
|
||||||
|
class AuthorizedPaymentsProcessor {
|
||||||
|
|
||||||
|
public const SUCCESSFUL = 'SUCCESSFUL';
|
||||||
|
public const ALREADY_CAPTURED = 'ALREADY_CAPTURED';
|
||||||
|
public const FAILED = 'FAILED';
|
||||||
|
public const INACCESSIBLE = 'INACCESSIBLE';
|
||||||
|
public const NOT_FOUND = 'NOT_FOUND';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Order endpoint.
|
||||||
|
*
|
||||||
|
* @var OrderEndpoint
|
||||||
|
*/
|
||||||
|
private $order_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Payments endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentsEndpoint
|
||||||
|
*/
|
||||||
|
private $payments_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last status.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $last_status = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AuthorizedPaymentsProcessor constructor.
|
||||||
|
*
|
||||||
|
* @param OrderEndpoint $order_endpoint The Order endpoint.
|
||||||
|
* @param PaymentsEndpoint $payments_endpoint The Payments endpoint.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
OrderEndpoint $order_endpoint,
|
||||||
|
PaymentsEndpoint $payments_endpoint
|
||||||
|
) {
|
||||||
|
|
||||||
|
$this->order_endpoint = $order_endpoint;
|
||||||
|
$this->payments_endpoint = $payments_endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a Woocommerce order.
|
||||||
|
*
|
||||||
|
* @param \WC_Order $wc_order The Woocommerce order.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function process( \WC_Order $wc_order ): bool {
|
||||||
|
try {
|
||||||
|
$order = $this->paypal_order_from_wc_order( $wc_order );
|
||||||
|
} catch ( Exception $exception ) {
|
||||||
|
if ( $exception->getCode() === 404 ) {
|
||||||
|
$this->last_status = self::NOT_FOUND;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this->last_status = self::INACCESSIBLE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$authorizations = $this->all_authorizations( $order );
|
||||||
|
|
||||||
|
if ( ! $this->are_authorzations_to_capture( ...$authorizations ) ) {
|
||||||
|
$this->last_status = self::ALREADY_CAPTURED;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->capture_authorizations( ...$authorizations );
|
||||||
|
} catch ( Exception $exception ) {
|
||||||
|
$this->last_status = self::FAILED;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->last_status = self::SUCCESSFUL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last status.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function last_status(): string {
|
||||||
|
|
||||||
|
return $this->last_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the PayPal order from a given Woocommerce order.
|
||||||
|
*
|
||||||
|
* @param \WC_Order $wc_order The Woocommerce order.
|
||||||
|
*
|
||||||
|
* @return Order
|
||||||
|
*/
|
||||||
|
private function paypal_order_from_wc_order( \WC_Order $wc_order ): Order {
|
||||||
|
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||||
|
return $this->order_endpoint->order( $order_id );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all Authorizations from an order.
|
||||||
|
*
|
||||||
|
* @param Order $order The order.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function all_authorizations( Order $order ): array {
|
||||||
|
$authorizations = array();
|
||||||
|
foreach ( $order->purchaseUnits() as $purchase_unit ) {
|
||||||
|
foreach ( $purchase_unit->payments()->authorizations() as $authorization ) {
|
||||||
|
$authorizations[] = $authorization;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $authorizations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Authorizations need to be captured.
|
||||||
|
*
|
||||||
|
* @param Authorization ...$authorizations All Authorizations.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function are_authorzations_to_capture( Authorization ...$authorizations ): bool {
|
||||||
|
return (bool) count( $this->authorizations_to_capture( ...$authorizations ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captures the authorizations.
|
||||||
|
*
|
||||||
|
* @param Authorization ...$authorizations All authorizations.
|
||||||
|
*/
|
||||||
|
private function capture_authorizations( Authorization ...$authorizations ) {
|
||||||
|
$uncaptured_authorizations = $this->authorizations_to_capture( ...$authorizations );
|
||||||
|
foreach ( $uncaptured_authorizations as $authorization ) {
|
||||||
|
$this->payments_endpoint->capture( $authorization->id() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The authorizations which need to be captured.
|
||||||
|
*
|
||||||
|
* @param Authorization ...$authorizations All Authorizations.
|
||||||
|
* @return Authorization[]
|
||||||
|
*/
|
||||||
|
private function authorizations_to_capture( Authorization ...$authorizations ): array {
|
||||||
|
return array_filter(
|
||||||
|
$authorizations,
|
||||||
|
static function ( Authorization $authorization ): bool {
|
||||||
|
return $authorization->status()->is( AuthorizationStatus::CREATED )
|
||||||
|
|| $authorization->status()->is( AuthorizationStatus::PENDING );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,272 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Processes orders for the gateways.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Processor
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Inpsyde\PayPalCommerce\WcGateway\Processor;
|
||||||
|
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Repository\CartRepository;
|
||||||
|
use Inpsyde\PayPalCommerce\Button\Helper\ThreeDSecure;
|
||||||
|
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class OrderProcessor
|
||||||
|
*/
|
||||||
|
class OrderProcessor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Session Handler.
|
||||||
|
*
|
||||||
|
* @var SessionHandler
|
||||||
|
*/
|
||||||
|
private $session_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Cart Repository.
|
||||||
|
*
|
||||||
|
* @var CartRepository
|
||||||
|
*/
|
||||||
|
private $cart_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Order Endpoint.
|
||||||
|
*
|
||||||
|
* @var OrderEndpoint
|
||||||
|
*/
|
||||||
|
private $order_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Payments Endpoint.
|
||||||
|
*
|
||||||
|
* @var PaymentsEndpoint
|
||||||
|
*/
|
||||||
|
private $payments_endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Order Factory.
|
||||||
|
*
|
||||||
|
* @var OrderFactory
|
||||||
|
*/
|
||||||
|
private $order_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The helper for 3d secure.
|
||||||
|
*
|
||||||
|
* @var ThreeDSecure
|
||||||
|
*/
|
||||||
|
private $threed_secure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The processor for authorized payments.
|
||||||
|
*
|
||||||
|
* @var AuthorizedPaymentsProcessor
|
||||||
|
*/
|
||||||
|
private $authorized_payments_processor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
|
* @var Settings
|
||||||
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last error.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $last_error = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OrderProcessor constructor.
|
||||||
|
*
|
||||||
|
* @param SessionHandler $session_handler The Session Handler.
|
||||||
|
* @param CartRepository $cart_repository The Cart Repository.
|
||||||
|
* @param OrderEndpoint $order_endpoint The Order Endpoint.
|
||||||
|
* @param PaymentsEndpoint $payments_endpoint The Payments Endpoint.
|
||||||
|
* @param OrderFactory $order_factory The Order Factory.
|
||||||
|
* @param ThreeDSecure $three_d_secure The ThreeDSecure Helper.
|
||||||
|
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
|
||||||
|
* @param Settings $settings The Settings.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
SessionHandler $session_handler,
|
||||||
|
CartRepository $cart_repository,
|
||||||
|
OrderEndpoint $order_endpoint,
|
||||||
|
PaymentsEndpoint $payments_endpoint,
|
||||||
|
OrderFactory $order_factory,
|
||||||
|
ThreeDSecure $three_d_secure,
|
||||||
|
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
||||||
|
Settings $settings
|
||||||
|
) {
|
||||||
|
|
||||||
|
$this->session_handler = $session_handler;
|
||||||
|
$this->cart_repository = $cart_repository;
|
||||||
|
$this->order_endpoint = $order_endpoint;
|
||||||
|
$this->payments_endpoint = $payments_endpoint;
|
||||||
|
$this->order_factory = $order_factory;
|
||||||
|
$this->threed_secure = $three_d_secure;
|
||||||
|
$this->authorized_payments_processor = $authorized_payments_processor;
|
||||||
|
$this->settings = $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a given Woocommerce order and captured/authorizes the connected PayPal orders.
|
||||||
|
*
|
||||||
|
* @param \WC_Order $wc_order The Woocommerce order.
|
||||||
|
* @param \WooCommerce $woocommerce The Woocommerce object.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function process( \WC_Order $wc_order, \WooCommerce $woocommerce ): bool {
|
||||||
|
$order = $this->session_handler->order();
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||||
|
|
||||||
|
$error_message = null;
|
||||||
|
if ( ! $order || ! $this->order_is_approved( $order ) ) {
|
||||||
|
$error_message = __(
|
||||||
|
'The payment has not been approved yet.',
|
||||||
|
'woocommerce-paypal-commerce-gateway'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ( $error_message ) {
|
||||||
|
$this->last_error = sprintf(
|
||||||
|
// translators: %s is the message of the error.
|
||||||
|
__( 'Payment error: %s', 'woocommerce-paypal-commerce-gateway' ),
|
||||||
|
$error_message
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = $this->patch_order( $wc_order, $order );
|
||||||
|
if ( $order->intent() === 'CAPTURE' ) {
|
||||||
|
$order = $this->order_endpoint->capture( $order );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $order->intent() === 'AUTHORIZE' ) {
|
||||||
|
$order = $this->order_endpoint->authorize( $order );
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$wc_order->update_status(
|
||||||
|
'on-hold',
|
||||||
|
__( 'Awaiting payment.', 'woocommerce-paypal-commerce-gateway' )
|
||||||
|
);
|
||||||
|
if ( $order->status()->is( OrderStatus::COMPLETED ) && $order->intent() === 'CAPTURE' ) {
|
||||||
|
$wc_order->update_status(
|
||||||
|
'processing',
|
||||||
|
__( 'Payment received.', 'woocommerce-paypal-commerce-gateway' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->capture_authorized_downloads( $order ) && $this->authorized_payments_processor->process( $wc_order ) ) {
|
||||||
|
$wc_order->add_order_note(
|
||||||
|
__( 'Payment successfully captured.', 'woocommerce-paypal-commerce-gateway' )
|
||||||
|
);
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
|
||||||
|
$wc_order->update_status( 'processing' );
|
||||||
|
}
|
||||||
|
$woocommerce->cart->empty_cart();
|
||||||
|
$this->session_handler->destroySessionData();
|
||||||
|
$this->last_error = '';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if an order should be captured immediately.
|
||||||
|
*
|
||||||
|
* @param Order $order The PayPal order.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function capture_authorized_downloads( Order $order ): bool {
|
||||||
|
if (
|
||||||
|
! $this->settings->has( 'capture_for_virtual_only' )
|
||||||
|
|| ! $this->settings->get( 'capture_for_virtual_only' )
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $order->intent() === 'CAPTURE' ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We fetch the order again as the authorize endpoint (from which the Order derives)
|
||||||
|
* drops the item's category, making it impossible to check, if purchase units contain
|
||||||
|
* physical goods.
|
||||||
|
*/
|
||||||
|
$order = $this->order_endpoint->order( $order->id() );
|
||||||
|
|
||||||
|
foreach ( $order->purchaseUnits() as $unit ) {
|
||||||
|
if ( $unit->containsPhysicalGoodsItems() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last error.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function last_error(): string {
|
||||||
|
|
||||||
|
return $this->last_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patches a given PayPal order with a Woocommerce order.
|
||||||
|
*
|
||||||
|
* @param \WC_Order $wc_order The Woocommerce order.
|
||||||
|
* @param Order $order The PayPal order.
|
||||||
|
*
|
||||||
|
* @return Order
|
||||||
|
*/
|
||||||
|
public function patch_order( \WC_Order $wc_order, Order $order ): Order {
|
||||||
|
$updated_order = $this->order_factory->fromWcOrder( $wc_order, $order );
|
||||||
|
$order = $this->order_endpoint->patchOrderWith( $order, $updated_order );
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether a given order is approved.
|
||||||
|
*
|
||||||
|
* @param Order $order The order.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function order_is_approved( Order $order ): bool {
|
||||||
|
|
||||||
|
if ( $order->status()->is( OrderStatus::APPROVED ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $order->paymentSource() || ! $order->paymentSource()->card() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_approved = in_array(
|
||||||
|
$this->threed_secure->proceedWithOrder( $order ),
|
||||||
|
array(
|
||||||
|
ThreeDSecure::NO_DECISION,
|
||||||
|
ThreeDSecure::PROCCEED,
|
||||||
|
),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
return $is_approved;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,201 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
|
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
|
||||||
use Inpsyde\PayPalCommerce\Onboarding\State;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
||||||
use Inpsyde\PayPalCommerce\Webhooks\WebhookRegistrar;
|
|
||||||
use Psr\SimpleCache\CacheInterface;
|
|
||||||
|
|
||||||
class SettingsListener {
|
|
||||||
|
|
||||||
|
|
||||||
public const NONCE = 'ppcp-settings';
|
|
||||||
private $settings;
|
|
||||||
private $settingFields;
|
|
||||||
private $webhookRegistrar;
|
|
||||||
private $cache;
|
|
||||||
private $state;
|
|
||||||
public function __construct(
|
|
||||||
Settings $settings,
|
|
||||||
array $settingFields,
|
|
||||||
WebhookRegistrar $webhookRegistrar,
|
|
||||||
CacheInterface $cache,
|
|
||||||
State $state
|
|
||||||
) {
|
|
||||||
|
|
||||||
$this->settings = $settings;
|
|
||||||
$this->settingFields = $settingFields;
|
|
||||||
$this->webhookRegistrar = $webhookRegistrar;
|
|
||||||
$this->cache = $cache;
|
|
||||||
$this->state = $state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function listen() {
|
|
||||||
|
|
||||||
if ( ! $this->isValidUpdateRequest() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Nonce verification is done in self::isValidUpdateRequest
|
|
||||||
*/
|
|
||||||
//phpcs:disable WordPress.Security.NonceVerification.Missing
|
|
||||||
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
|
||||||
if ( isset( $_POST['save'] ) && sanitize_text_field( wp_unslash( $_POST['save'] ) ) === 'reset' ) {
|
|
||||||
$this->settings->reset();
|
|
||||||
$this->settings->persist();
|
|
||||||
$this->webhookRegistrar->unregister();
|
|
||||||
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
|
||||||
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
|
||||||
//phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotValidated
|
|
||||||
/**
|
|
||||||
* Sanitization is done at a later stage.
|
|
||||||
*/
|
|
||||||
$rawData = ( isset( $_POST['ppcp'] ) ) ? (array) wp_unslash( $_POST['ppcp'] ) : array();
|
|
||||||
$settings = $this->retrieveSettingsFromRawData( $rawData );
|
|
||||||
if ( $_GET['section'] === PayPalGateway::ID ) {
|
|
||||||
$settings['enabled'] = isset( $_POST['woocommerce_ppcp-gateway_enabled'] )
|
|
||||||
&& absint( $_POST['woocommerce_ppcp-gateway_enabled'] ) === 1;
|
|
||||||
}
|
|
||||||
if ( $_GET['section'] === CreditCardGateway::ID ) {
|
|
||||||
$dccEnabledPostKey = 'woocommerce_ppcp-credit-card-gateway_enabled';
|
|
||||||
$settings['dcc_gateway_enabled'] = isset( $_POST[ $dccEnabledPostKey ] )
|
|
||||||
&& absint( $_POST[ $dccEnabledPostKey ] ) === 1;
|
|
||||||
}
|
|
||||||
$this->maybeRegisterWebhooks( $settings );
|
|
||||||
|
|
||||||
foreach ( $settings as $id => $value ) {
|
|
||||||
$this->settings->set( $id, $value );
|
|
||||||
}
|
|
||||||
$this->settings->persist();
|
|
||||||
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
|
||||||
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
|
||||||
}
|
|
||||||
//phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotValidated
|
|
||||||
//phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
|
||||||
//phpcs:enable WordPress.Security.NonceVerification.Missing
|
|
||||||
}
|
|
||||||
|
|
||||||
private function maybeRegisterWebhooks( array $settings ) {
|
|
||||||
|
|
||||||
if ( ! $this->settings->has( 'client_id' ) && $settings['client_id'] ) {
|
|
||||||
$this->webhookRegistrar->register();
|
|
||||||
}
|
|
||||||
if ( $this->settings->has( 'client_id' ) && $this->settings->get( 'client_id' ) ) {
|
|
||||||
$currentSecret = $this->settings->has( 'client_secret' ) ?
|
|
||||||
$this->settings->get( 'client_secret' ) : '';
|
|
||||||
if (
|
|
||||||
$settings['client_id'] !== $this->settings->get( 'client_id' )
|
|
||||||
|| $settings['client_secret'] !== $currentSecret
|
|
||||||
) {
|
|
||||||
$this->webhookRegistrar->unregister();
|
|
||||||
$this->webhookRegistrar->register();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//phpcs:disable Inpsyde.CodeQuality.NestingLevel.MaxExceeded
|
|
||||||
//phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
|
||||||
//phpcs:disable Inpsyde.CodeQuality.FunctionLength.TooLong
|
|
||||||
private function retrieveSettingsFromRawData( array $rawData ): array {
|
|
||||||
if ( ! isset( $_GET['section'] ) ) {
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
$settings = array();
|
|
||||||
foreach ( $this->settingFields as $key => $config ) {
|
|
||||||
if ( ! in_array( $this->state->currentState(), $config['screens'], true ) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
$config['gateway'] === 'dcc'
|
|
||||||
&& sanitize_text_field( wp_unslash( $_GET['section'] ) ) !== 'ppcp-credit-card-gateway'
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
$config['gateway'] === 'paypal'
|
|
||||||
&& sanitize_text_field( wp_unslash( $_GET['section'] ) ) !== 'ppcp-gateway'
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch ( $config['type'] ) {
|
|
||||||
case 'checkbox':
|
|
||||||
$settings[ $key ] = isset( $rawData[ $key ] );
|
|
||||||
break;
|
|
||||||
case 'text':
|
|
||||||
case 'ppcp-text-input':
|
|
||||||
case 'ppcp-password':
|
|
||||||
$settings[ $key ] = isset( $rawData[ $key ] ) ? sanitize_text_field( $rawData[ $key ] ) : '';
|
|
||||||
break;
|
|
||||||
case 'password':
|
|
||||||
if ( empty( $rawData[ $key ] ) ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$settings[ $key ] = sanitize_text_field( $rawData[ $key ] );
|
|
||||||
break;
|
|
||||||
case 'ppcp-multiselect':
|
|
||||||
$values = isset( $rawData[ $key ] ) ? (array) $rawData[ $key ] : array();
|
|
||||||
$valuesToSave = array();
|
|
||||||
foreach ( $values as $index => $rawValue ) {
|
|
||||||
$value = sanitize_text_field( $rawValue );
|
|
||||||
if ( ! in_array( $value, array_keys( $config['options'] ), true ) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$valuesToSave[] = $value;
|
|
||||||
}
|
|
||||||
$settings[ $key ] = $valuesToSave;
|
|
||||||
break;
|
|
||||||
case 'select':
|
|
||||||
$options = array_keys( $config['options'] );
|
|
||||||
$settings[ $key ] = isset( $rawData[ $key ] ) && in_array(
|
|
||||||
sanitize_text_field( $rawData[ $key ] ),
|
|
||||||
$options,
|
|
||||||
true
|
|
||||||
) ? sanitize_text_field( $rawData[ $key ] ) : null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $settings;
|
|
||||||
}
|
|
||||||
//phpcs:enable Inpsyde.CodeQuality.NestingLevel.MaxExceeded
|
|
||||||
//phpcs:enable Generic.Metrics.CyclomaticComplexity.TooHigh
|
|
||||||
|
|
||||||
private function isValidUpdateRequest(): bool {
|
|
||||||
|
|
||||||
if (
|
|
||||||
! isset( $_REQUEST['section'] )
|
|
||||||
|| ! in_array(
|
|
||||||
sanitize_text_field( wp_unslash( $_REQUEST['section'] ) ),
|
|
||||||
array( 'ppcp-gateway', 'ppcp-credit-card-gateway' ),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! current_user_can( 'manage_options' ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
! isset( $_POST['ppcp-nonce'] )
|
|
||||||
|| ! wp_verify_nonce(
|
|
||||||
sanitize_text_field( wp_unslash( $_POST['ppcp-nonce'] ) ),
|
|
||||||
self::NONCE
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +1,39 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* The settings object.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Settings
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
|
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
|
||||||
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
use Inpsyde\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\WcGatewayInterface;
|
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Settings
|
||||||
|
*/
|
||||||
class Settings implements ContainerInterface {
|
class Settings implements ContainerInterface {
|
||||||
|
|
||||||
public const KEY = 'woocommerce-ppcp-settings';
|
public const KEY = 'woocommerce-ppcp-settings';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
private $settings = array();
|
private $settings = array();
|
||||||
|
|
||||||
public function __construct() {
|
/**
|
||||||
}
|
* Returns the value for an id.
|
||||||
|
*
|
||||||
// phpcs:disable Inpsyde.CodeQuality.ReturnTypeDeclaration.NoReturnType
|
* @param string $id The value identificator.
|
||||||
// phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @throws NotFoundException When nothing was found.
|
||||||
|
*/
|
||||||
public function get( $id ) {
|
public function get( $id ) {
|
||||||
if ( ! $this->has( $id ) ) {
|
if ( ! $this->has( $id ) ) {
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
|
@ -25,24 +41,45 @@ class Settings implements ContainerInterface {
|
||||||
return $this->settings[ $id ];
|
return $this->settings[ $id ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether a value exists.
|
||||||
|
*
|
||||||
|
* @param string $id The value identificator.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function has( $id ) {
|
public function has( $id ) {
|
||||||
$this->load();
|
$this->load();
|
||||||
return array_key_exists( $id, $this->settings );
|
return array_key_exists( $id, $this->settings );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a value.
|
||||||
|
*
|
||||||
|
* @param string $id The value identificator.
|
||||||
|
* @param mixed $value The value.
|
||||||
|
*/
|
||||||
public function set( $id, $value ) {
|
public function set( $id, $value ) {
|
||||||
$this->load();
|
$this->load();
|
||||||
$this->settings[ $id ] = $value;
|
$this->settings[ $id ] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the settings to the database.
|
||||||
|
*/
|
||||||
public function persist() {
|
public function persist() {
|
||||||
|
|
||||||
update_option( self::KEY, $this->settings );
|
update_option( self::KEY, $this->settings );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the onboarding.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function reset(): bool {
|
public function reset(): bool {
|
||||||
$this->load();
|
$this->load();
|
||||||
$fieldsToReset = array(
|
$fields_to_reset = array(
|
||||||
'enabled',
|
'enabled',
|
||||||
'dcc_gateway_enabled',
|
'dcc_gateway_enabled',
|
||||||
'intent',
|
'intent',
|
||||||
|
@ -50,13 +87,18 @@ class Settings implements ContainerInterface {
|
||||||
'client_secret',
|
'client_secret',
|
||||||
'merchant_email',
|
'merchant_email',
|
||||||
);
|
);
|
||||||
foreach ( $fieldsToReset as $id ) {
|
foreach ( $fields_to_reset as $id ) {
|
||||||
$this->settings[ $id ] = null;
|
$this->settings[ $id ] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the settings.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
private function load(): bool {
|
private function load(): bool {
|
||||||
|
|
||||||
if ( $this->settings ) {
|
if ( $this->settings ) {
|
|
@ -0,0 +1,277 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Listens to requests and updates the settings if necessary.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Settings
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
|
||||||
|
|
||||||
|
use Inpsyde\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
||||||
|
use Inpsyde\PayPalCommerce\Onboarding\State;
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||||
|
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
use Inpsyde\PayPalCommerce\Webhooks\WebhookRegistrar;
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SettingsListener
|
||||||
|
*/
|
||||||
|
class SettingsListener {
|
||||||
|
|
||||||
|
|
||||||
|
public const NONCE = 'ppcp-settings';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Settings.
|
||||||
|
*
|
||||||
|
* @var Settings
|
||||||
|
*/
|
||||||
|
private $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array contains the setting fields.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $setting_fields;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Webhook Registrar.
|
||||||
|
*
|
||||||
|
* @var WebhookRegistrar
|
||||||
|
*/
|
||||||
|
private $webhook_registrar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Cache.
|
||||||
|
*
|
||||||
|
* @var CacheInterface
|
||||||
|
*/
|
||||||
|
private $cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The State.
|
||||||
|
*
|
||||||
|
* @var State
|
||||||
|
*/
|
||||||
|
private $state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SettingsListener constructor.
|
||||||
|
*
|
||||||
|
* @param Settings $settings The settings.
|
||||||
|
* @param array $setting_fields The setting fields.
|
||||||
|
* @param WebhookRegistrar $webhook_registrar The Webhook Registrar.
|
||||||
|
* @param CacheInterface $cache The Cache.
|
||||||
|
* @param State $state The state.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
Settings $settings,
|
||||||
|
array $setting_fields,
|
||||||
|
WebhookRegistrar $webhook_registrar,
|
||||||
|
CacheInterface $cache,
|
||||||
|
State $state
|
||||||
|
) {
|
||||||
|
|
||||||
|
$this->settings = $settings;
|
||||||
|
$this->setting_fields = $setting_fields;
|
||||||
|
$this->webhook_registrar = $webhook_registrar;
|
||||||
|
$this->cache = $cache;
|
||||||
|
$this->state = $state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens to the request.
|
||||||
|
*
|
||||||
|
* @throws \Inpsyde\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
|
||||||
|
* @throws \Psr\SimpleCache\InvalidArgumentException When the argument was invalid.
|
||||||
|
*/
|
||||||
|
public function listen() {
|
||||||
|
|
||||||
|
if ( ! $this->is_valid_update_request() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nonce verification has been done in is_valid_update_request().
|
||||||
|
*
|
||||||
|
* phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||||
|
* phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
|
*/
|
||||||
|
if ( isset( $_POST['save'] ) && sanitize_text_field( wp_unslash( $_POST['save'] ) ) === 'reset' ) {
|
||||||
|
$this->settings->reset();
|
||||||
|
$this->settings->persist();
|
||||||
|
$this->webhook_registrar->unregister();
|
||||||
|
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
||||||
|
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitization is done in retrieve_settings_from_raw_data().
|
||||||
|
*
|
||||||
|
* phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||||
|
*/
|
||||||
|
$raw_data = ( isset( $_POST['ppcp'] ) ) ? (array) wp_unslash( $_POST['ppcp'] ) : array();
|
||||||
|
// phpcs:enable phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||||
|
$settings = $this->retrieve_settings_from_raw_data( $raw_data );
|
||||||
|
if ( isset( $_GET['section'] ) && PayPalGateway::ID === $_GET['section'] ) {
|
||||||
|
$settings['enabled'] = isset( $_POST['woocommerce_ppcp-gateway_enabled'] )
|
||||||
|
&& 1 === absint( $_POST['woocommerce_ppcp-gateway_enabled'] );
|
||||||
|
}
|
||||||
|
if ( isset( $_GET['section'] ) && CreditCardGateway::ID === $_GET['section'] ) {
|
||||||
|
$dcc_enabled_post_key = 'woocommerce_ppcp-credit-card-gateway_enabled';
|
||||||
|
$settings['dcc_gateway_enabled'] = isset( $_POST[ $dcc_enabled_post_key ] )
|
||||||
|
&& 1 === absint( $_POST[ $dcc_enabled_post_key ] );
|
||||||
|
}
|
||||||
|
$this->maybe_register_webhooks( $settings );
|
||||||
|
|
||||||
|
foreach ( $settings as $id => $value ) {
|
||||||
|
$this->settings->set( $id, $value );
|
||||||
|
}
|
||||||
|
$this->settings->persist();
|
||||||
|
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
||||||
|
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
||||||
|
}
|
||||||
|
|
||||||
|
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||||
|
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Depending on the settings change, we might need to register or unregister the Webhooks at PayPal.
|
||||||
|
*
|
||||||
|
* @param array $settings The settings.
|
||||||
|
*
|
||||||
|
* @throws \Inpsyde\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting hasn't been found.
|
||||||
|
*/
|
||||||
|
private function maybe_register_webhooks( array $settings ) {
|
||||||
|
|
||||||
|
if ( ! $this->settings->has( 'client_id' ) && $settings['client_id'] ) {
|
||||||
|
$this->webhook_registrar->register();
|
||||||
|
}
|
||||||
|
if ( $this->settings->has( 'client_id' ) && $this->settings->get( 'client_id' ) ) {
|
||||||
|
$current_secret = $this->settings->has( 'client_secret' ) ?
|
||||||
|
$this->settings->get( 'client_secret' ) : '';
|
||||||
|
if (
|
||||||
|
$settings['client_id'] !== $this->settings->get( 'client_id' )
|
||||||
|
|| $settings['client_secret'] !== $current_secret
|
||||||
|
) {
|
||||||
|
$this->webhook_registrar->unregister();
|
||||||
|
$this->webhook_registrar->register();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitizes the settings input data and returns a valid settings array.
|
||||||
|
*
|
||||||
|
* @param array $raw_data The Raw data.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function retrieve_settings_from_raw_data( array $raw_data ): array {
|
||||||
|
/**
|
||||||
|
* Nonce verification has already been done.
|
||||||
|
* phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
|
*/
|
||||||
|
if ( ! isset( $_GET['section'] ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$settings = array();
|
||||||
|
foreach ( $this->setting_fields as $key => $config ) {
|
||||||
|
if ( ! in_array( $this->state->currentState(), $config['screens'], true ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
'dcc' === $config['gateway']
|
||||||
|
&& sanitize_text_field( wp_unslash( $_GET['section'] ) ) !== 'ppcp-credit-card-gateway'
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
'paypal' === $config['gateway']
|
||||||
|
&& sanitize_text_field( wp_unslash( $_GET['section'] ) ) !== 'ppcp-gateway'
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch ( $config['type'] ) {
|
||||||
|
case 'checkbox':
|
||||||
|
$settings[ $key ] = isset( $raw_data[ $key ] );
|
||||||
|
break;
|
||||||
|
case 'text':
|
||||||
|
case 'ppcp-text-input':
|
||||||
|
case 'ppcp-password':
|
||||||
|
$settings[ $key ] = isset( $raw_data[ $key ] ) ? sanitize_text_field( $raw_data[ $key ] ) : '';
|
||||||
|
break;
|
||||||
|
case 'password':
|
||||||
|
if ( empty( $raw_data[ $key ] ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$settings[ $key ] = sanitize_text_field( $raw_data[ $key ] );
|
||||||
|
break;
|
||||||
|
case 'ppcp-multiselect':
|
||||||
|
$values = isset( $raw_data[ $key ] ) ? (array) $raw_data[ $key ] : array();
|
||||||
|
$values_to_save = array();
|
||||||
|
foreach ( $values as $index => $raw_value ) {
|
||||||
|
$value = sanitize_text_field( $raw_value );
|
||||||
|
if ( ! in_array( $value, array_keys( $config['options'] ), true ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$values_to_save[] = $value;
|
||||||
|
}
|
||||||
|
$settings[ $key ] = $values_to_save;
|
||||||
|
break;
|
||||||
|
case 'select':
|
||||||
|
$options = array_keys( $config['options'] );
|
||||||
|
$settings[ $key ] = isset( $raw_data[ $key ] ) && in_array(
|
||||||
|
sanitize_text_field( $raw_data[ $key ] ),
|
||||||
|
$options,
|
||||||
|
true
|
||||||
|
) ? sanitize_text_field( $raw_data[ $key ] ) : null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||||
|
return $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates whether the current request is supposed to update the settings.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function is_valid_update_request(): bool {
|
||||||
|
|
||||||
|
if (
|
||||||
|
! isset( $_REQUEST['section'] )
|
||||||
|
|| ! in_array(
|
||||||
|
sanitize_text_field( wp_unslash( $_REQUEST['section'] ) ),
|
||||||
|
array( 'ppcp-gateway', 'ppcp-credit-card-gateway' ),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
! isset( $_POST['ppcp-nonce'] )
|
||||||
|
|| ! wp_verify_nonce(
|
||||||
|
sanitize_text_field( wp_unslash( $_POST['ppcp-nonce'] ) ),
|
||||||
|
self::NONCE
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Renders the settings of the Gateways.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway\Settings
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
@ -9,42 +14,92 @@ use Inpsyde\PayPalCommerce\Button\Helper\MessagesApply;
|
||||||
use Inpsyde\PayPalCommerce\Onboarding\State;
|
use Inpsyde\PayPalCommerce\Onboarding\State;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SettingsRenderer
|
||||||
|
*/
|
||||||
class SettingsRenderer {
|
class SettingsRenderer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
|
* @var ContainerInterface
|
||||||
|
*/
|
||||||
private $settings;
|
private $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current onboarding state.
|
||||||
|
*
|
||||||
|
* @var State
|
||||||
|
*/
|
||||||
private $state;
|
private $state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The setting fields.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
private $fields;
|
private $fields;
|
||||||
private $dccApplies;
|
|
||||||
private $messagesApply;
|
/**
|
||||||
|
* Helper to see if DCC gateway can be shown.
|
||||||
|
*
|
||||||
|
* @var DccApplies
|
||||||
|
*/
|
||||||
|
private $dcc_applies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to see if messages are supposed to show up.
|
||||||
|
*
|
||||||
|
* @var MessagesApply
|
||||||
|
*/
|
||||||
|
private $messages_apply;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SettingsRenderer constructor.
|
||||||
|
*
|
||||||
|
* @param ContainerInterface $settings The Settings.
|
||||||
|
* @param State $state The current state.
|
||||||
|
* @param array $fields The setting fields.
|
||||||
|
* @param DccApplies $dcc_applies Whether DCC gateway can be shown.
|
||||||
|
* @param MessagesApply $messages_apply Whether messages can be shown.
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ContainerInterface $settings,
|
ContainerInterface $settings,
|
||||||
State $state,
|
State $state,
|
||||||
array $fields,
|
array $fields,
|
||||||
DccApplies $dccApplies,
|
DccApplies $dcc_applies,
|
||||||
MessagesApply $messagesApply
|
MessagesApply $messages_apply
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->state = $state;
|
$this->state = $state;
|
||||||
$this->fields = $fields;
|
$this->fields = $fields;
|
||||||
$this->dccApplies = $dccApplies;
|
$this->dcc_applies = $dcc_applies;
|
||||||
$this->messagesApply = $messagesApply;
|
$this->messages_apply = $messages_apply;
|
||||||
}
|
}
|
||||||
|
|
||||||
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
/**
|
||||||
public function renderMultiSelect( $field, $key, $config, $value ): string {
|
* Renders the multiselect field.
|
||||||
|
*
|
||||||
|
* @param string $field The current field HTML.
|
||||||
|
* @param string $key The current key.
|
||||||
|
* @param array $config The configuration array.
|
||||||
|
* @param string $value The current value.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render_multiselect( $field, $key, $config, $value ): string {
|
||||||
|
|
||||||
if ( $config['type'] !== 'ppcp-multiselect' ) {
|
if ( 'ppcp-multiselect' !== $config['type'] ) {
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
$options = array();
|
$options = array();
|
||||||
foreach ( $config['options'] as $optionKey => $optionValue ) {
|
foreach ( $config['options'] as $option_key => $option_value ) {
|
||||||
$selected = ( in_array( $optionKey, $value, true ) ) ? 'selected="selected"' : '';
|
$selected = ( in_array( $option_key, $value, true ) ) ? 'selected="selected"' : '';
|
||||||
|
|
||||||
$options[] = '<option value="' . esc_attr( $optionKey ) . '" ' . $selected . '>' .
|
$options[] = '<option value="' . esc_attr( $option_key ) . '" ' . $selected . '>' .
|
||||||
esc_html( $optionValue ) .
|
esc_html( $option_value ) .
|
||||||
'</option>';
|
'</option>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +117,19 @@ class SettingsRenderer {
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderPassword( $field, $key, $config, $value ): string {
|
/**
|
||||||
|
* Renders the password input field.
|
||||||
|
*
|
||||||
|
* @param string $field The current field HTML.
|
||||||
|
* @param string $key The current key.
|
||||||
|
* @param array $config The configuration array.
|
||||||
|
* @param string $value The current value.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render_password( $field, $key, $config, $value ): string {
|
||||||
|
|
||||||
if ( $config['type'] !== 'ppcp-password' ) {
|
if ( 'ppcp-password' !== $config['type'] ) {
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,9 +149,20 @@ class SettingsRenderer {
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderTextInput( $field, $key, $config, $value ): string {
|
|
||||||
|
|
||||||
if ( $config['type'] !== 'ppcp-text-input' ) {
|
/**
|
||||||
|
* Renders the text input field.
|
||||||
|
*
|
||||||
|
* @param string $field The current field HTML.
|
||||||
|
* @param string $key The current key.
|
||||||
|
* @param array $config The configuration array.
|
||||||
|
* @param string $value The current value.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render_text_input( $field, $key, $config, $value ): string {
|
||||||
|
|
||||||
|
if ( 'ppcp-text-input' !== $config['type'] ) {
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,9 +182,19 @@ class SettingsRenderer {
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderHeading( $field, $key, $config, $value ): string {
|
/**
|
||||||
|
* Renders the heading field.
|
||||||
|
*
|
||||||
|
* @param string $field The current field HTML.
|
||||||
|
* @param string $key The current key.
|
||||||
|
* @param array $config The configuration array.
|
||||||
|
* @param string $value The current value.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function render_heading( $field, $key, $config, $value ): string {
|
||||||
|
|
||||||
if ( $config['type'] !== 'ppcp-heading' ) {
|
if ( 'ppcp-heading' !== $config['type'] ) {
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,11 +206,13 @@ class SettingsRenderer {
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
//phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
|
||||||
|
|
||||||
//phpcs:disable Inpsyde.CodeQuality.NestingLevel.High
|
/**
|
||||||
//phpcs:disable Inpsyde.CodeQuality.FunctionLength.TooLong
|
* Renders the settings.
|
||||||
public function render( bool $isDcc ) {
|
*
|
||||||
|
* @param bool $is_dcc Whether it is the DCC gateway or not.
|
||||||
|
*/
|
||||||
|
public function render( bool $is_dcc ) {
|
||||||
|
|
||||||
$nonce = wp_create_nonce( SettingsListener::NONCE );
|
$nonce = wp_create_nonce( SettingsListener::NONCE );
|
||||||
?>
|
?>
|
||||||
|
@ -134,21 +222,21 @@ class SettingsRenderer {
|
||||||
if ( ! in_array( $this->state->currentState(), $config['screens'], true ) ) {
|
if ( ! in_array( $this->state->currentState(), $config['screens'], true ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( $isDcc && ! in_array( $config['gateway'], array( 'all', 'dcc' ), true ) ) {
|
if ( $is_dcc && ! in_array( $config['gateway'], array( 'all', 'dcc' ), true ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! $isDcc && ! in_array( $config['gateway'], array( 'all', 'paypal' ), true ) ) {
|
if ( ! $is_dcc && ! in_array( $config['gateway'], array( 'all', 'paypal' ), true ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
in_array( 'dcc', $config['requirements'], true )
|
in_array( 'dcc', $config['requirements'], true )
|
||||||
&& ! $this->dccApplies->forCountryCurrency()
|
&& ! $this->dcc_applies->forCountryCurrency()
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
in_array( 'messages', $config['requirements'], true )
|
in_array( 'messages', $config['requirements'], true )
|
||||||
&& ! $this->messagesApply->forCountry()
|
&& ! $this->messages_apply->forCountry()
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -156,12 +244,12 @@ class SettingsRenderer {
|
||||||
$key = 'ppcp[' . $field . ']';
|
$key = 'ppcp[' . $field . ']';
|
||||||
$id = 'ppcp-' . $field;
|
$id = 'ppcp-' . $field;
|
||||||
$config['id'] = $id;
|
$config['id'] = $id;
|
||||||
$thTd = $config['type'] !== 'ppcp-heading' ? 'td' : 'th';
|
$th_td = 'ppcp-heading' !== $config['type'] ? 'td' : 'th';
|
||||||
$colspan = $config['type'] !== 'ppcp-heading' ? 1 : 2;
|
$colspan = 'ppcp-heading' !== $config['type'] ? 1 : 2;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<tr valign="top" id="<?php echo esc_attr( 'field-' . $field ); ?>">
|
<tr valign="top" id="<?php echo esc_attr( 'field-' . $field ); ?>">
|
||||||
<?php if ( $config['type'] !== 'ppcp-heading' ) : ?>
|
<?php if ( 'ppcp-heading' !== $config['type'] ) : ?>
|
||||||
<th>
|
<th>
|
||||||
<label
|
<label
|
||||||
for="<?php echo esc_attr( $id ); ?>"
|
for="<?php echo esc_attr( $id ); ?>"
|
||||||
|
@ -177,18 +265,18 @@ class SettingsRenderer {
|
||||||
?>
|
?>
|
||||||
</th>
|
</th>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<<?php echo esc_attr( $thTd ); ?> colspan="<?php echo (int) $colspan; ?>">
|
<<?php echo esc_attr( $th_td ); ?> colspan="<?php echo (int) $colspan; ?>">
|
||||||
<?php
|
<?php
|
||||||
$config['type'] === 'ppcp-text' ?
|
'ppcp-text' === $config['type'] ?
|
||||||
$this->renderText( $config )
|
$this->render_text( $config )
|
||||||
: woocommerce_form_field( $key, $config, $value );
|
: woocommerce_form_field( $key, $config, $value );
|
||||||
?>
|
?>
|
||||||
</<?php echo esc_attr( $thTd ); ?>>
|
</<?php echo esc_attr( $th_td ); ?>>
|
||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
endforeach;
|
endforeach;
|
||||||
|
|
||||||
if ( $isDcc ) :
|
if ( $is_dcc ) :
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<th><?php esc_html_e( '3D Secure', 'woocommerce-paypal-commerce-gateway' ); ?></th>
|
<th><?php esc_html_e( '3D Secure', 'woocommerce-paypal-commerce-gateway' ); ?></th>
|
||||||
|
@ -196,6 +284,8 @@ class SettingsRenderer {
|
||||||
<p>
|
<p>
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
|
* We still need to provide a docs link.
|
||||||
|
*
|
||||||
* @todo: Provide link to documentation.
|
* @todo: Provide link to documentation.
|
||||||
*/
|
*/
|
||||||
echo wp_kses_post(
|
echo wp_kses_post(
|
||||||
|
@ -206,7 +296,7 @@ class SettingsRenderer {
|
||||||
an additional layer of verification using Verified by Visa,
|
an additional layer of verification using Verified by Visa,
|
||||||
MasterCard SecureCode and American Express SafeKey.
|
MasterCard SecureCode and American Express SafeKey.
|
||||||
%1$sLearn more about 3D Secure.%2$s',
|
%1$sLearn more about 3D Secure.%2$s',
|
||||||
'woocommerce - paypal - commerce - gateway'
|
'woocommerce-paypal-commerce-gateway'
|
||||||
),
|
),
|
||||||
'<a href = "#">',
|
'<a href = "#">',
|
||||||
'</a>'
|
'</a>'
|
||||||
|
@ -219,9 +309,13 @@ class SettingsRenderer {
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
}
|
}
|
||||||
//phpcs:enable Inpsyde.CodeQuality.NestingLevel.High
|
|
||||||
|
|
||||||
private function renderText( array $config ) {
|
/**
|
||||||
|
* Renders the ppcp-text field given a configuration.
|
||||||
|
*
|
||||||
|
* @param array $config The configuration array.
|
||||||
|
*/
|
||||||
|
private function render_text( array $config ) {
|
||||||
echo wp_kses_post( $config['text'] );
|
echo wp_kses_post( $config['text'] );
|
||||||
if ( isset( $config['hidden'] ) ) {
|
if ( isset( $config['hidden'] ) ) {
|
||||||
$value = $this->settings->has( $config['hidden'] ) ?
|
$value = $this->settings->has( $config['hidden'] ) ?
|
|
@ -1,4 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* The Gateway module.
|
||||||
|
*
|
||||||
|
* @package Inpsyde\PayPalCommerce\WcGateway
|
||||||
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
@ -9,7 +14,6 @@ use Dhii\Modular\Module\ModuleInterface;
|
||||||
use Inpsyde\PayPalCommerce\AdminNotices\Repository\Repository;
|
use Inpsyde\PayPalCommerce\AdminNotices\Repository\Repository;
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Helper\DccApplies;
|
use Inpsyde\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
|
use Inpsyde\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Admin\OrderDetail;
|
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
|
use Inpsyde\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail;
|
use Inpsyde\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail;
|
||||||
use Inpsyde\PayPalCommerce\WcGateway\Checkout\CheckoutPayPalAddressPreset;
|
use Inpsyde\PayPalCommerce\WcGateway\Checkout\CheckoutPayPalAddressPreset;
|
||||||
|
@ -23,8 +27,16 @@ use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||||
use Interop\Container\ServiceProviderInterface;
|
use Interop\Container\ServiceProviderInterface;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class WcGatewayModule
|
||||||
|
*/
|
||||||
class WcGatewayModule implements ModuleInterface {
|
class WcGatewayModule implements ModuleInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the module.
|
||||||
|
*
|
||||||
|
* @return ServiceProviderInterface
|
||||||
|
*/
|
||||||
public function setup(): ServiceProviderInterface {
|
public function setup(): ServiceProviderInterface {
|
||||||
return new ServiceProvider(
|
return new ServiceProvider(
|
||||||
require __DIR__ . '/../services.php',
|
require __DIR__ . '/../services.php',
|
||||||
|
@ -32,28 +44,35 @@ class WcGatewayModule implements ModuleInterface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the module.
|
||||||
|
*
|
||||||
|
* @param ContainerInterface $container The container.
|
||||||
|
*/
|
||||||
public function run( ContainerInterface $container ) {
|
public function run( ContainerInterface $container ) {
|
||||||
$this->registerPaymentGateway( $container );
|
$this->register_payment_gateways( $container );
|
||||||
$this->registerOrderFunctionality( $container );
|
$this->register_order_functionality( $container );
|
||||||
$this->registerColumns( $container );
|
$this->register_columns( $container );
|
||||||
$this->registerCheckoutAddressPreset( $container );
|
$this->register_checkout_paypal_address_preset( $container );
|
||||||
$this->ajaxGatewayEnabler( $container );
|
$this->ajax_gateway_enabler( $container );
|
||||||
|
|
||||||
add_filter(
|
add_filter(
|
||||||
Repository::NOTICES_FILTER,
|
Repository::NOTICES_FILTER,
|
||||||
static function ( $notices ) use ( $container ): array {
|
static function ( $notices ) use ( $container ): array {
|
||||||
$notice = $container->get( 'wcgateway.notice.connect' );
|
$notice = $container->get( 'wcgateway.notice.connect' );
|
||||||
/**
|
/**
|
||||||
|
* The Connect Admin Notice object.
|
||||||
|
*
|
||||||
* @var ConnectAdminNotice $notice
|
* @var ConnectAdminNotice $notice
|
||||||
*/
|
*/
|
||||||
$connectMessage = $notice->connectMessage();
|
$connect_message = $notice->connect_message();
|
||||||
if ( $connectMessage ) {
|
if ( $connect_message ) {
|
||||||
$notices[] = $connectMessage;
|
$notices[] = $connect_message;
|
||||||
}
|
}
|
||||||
$authorizeOrderAction = $container->get( 'wcgateway.notice.authorize-order-action' );
|
$authorize_order_action = $container->get( 'wcgateway.notice.authorize-order-action' );
|
||||||
$authorizedMessage = $authorizeOrderAction->message();
|
$authorized_message = $authorize_order_action->message();
|
||||||
if ( $authorizedMessage ) {
|
if ( $authorized_message ) {
|
||||||
$notices[] = $authorizedMessage;
|
$notices[] = $authorized_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $notices;
|
return $notices;
|
||||||
|
@ -74,14 +93,21 @@ class WcGatewayModule implements ModuleInterface {
|
||||||
static function () use ( $container ) {
|
static function () use ( $container ) {
|
||||||
$endpoint = $container->get( 'wcgateway.endpoint.return-url' );
|
$endpoint = $container->get( 'wcgateway.endpoint.return-url' );
|
||||||
/**
|
/**
|
||||||
|
* The Endpoint.
|
||||||
|
*
|
||||||
* @var ReturnUrlEndpoint $endpoint
|
* @var ReturnUrlEndpoint $endpoint
|
||||||
*/
|
*/
|
||||||
$endpoint->handleRequest();
|
$endpoint->handle_request();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ajaxGatewayEnabler( ContainerInterface $container ) {
|
/**
|
||||||
|
* Adds the functionality to listen to the ajax enable gateway switch.
|
||||||
|
*
|
||||||
|
* @param ContainerInterface $container The container.
|
||||||
|
*/
|
||||||
|
private function ajax_gateway_enabler( ContainerInterface $container ) {
|
||||||
add_action(
|
add_action(
|
||||||
'wp_ajax_woocommerce_toggle_gateway_enabled',
|
'wp_ajax_woocommerce_toggle_gateway_enabled',
|
||||||
static function () use ( $container ) {
|
static function () use ( $container ) {
|
||||||
|
@ -97,11 +123,13 @@ class WcGatewayModule implements ModuleInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The settings.
|
||||||
|
*
|
||||||
* @var Settings $settings
|
* @var Settings $settings
|
||||||
*/
|
*/
|
||||||
$settings = $container->get( 'wcgateway.settings' );
|
$settings = $container->get( 'wcgateway.settings' );
|
||||||
$key = $_POST['gateway_id'] === PayPalGateway::ID ? 'enabled' : '';
|
$key = PayPalGateway::ID === $_POST['gateway_id'] ? 'enabled' : '';
|
||||||
if ( $_POST['gateway_id'] === CreditCardGateway::ID ) {
|
if ( CreditCardGateway::ID === $_POST['gateway_id'] ) {
|
||||||
$key = 'dcc_gateway_enabled';
|
$key = 'dcc_gateway_enabled';
|
||||||
}
|
}
|
||||||
if ( ! $key ) {
|
if ( ! $key ) {
|
||||||
|
@ -118,17 +146,24 @@ class WcGatewayModule implements ModuleInterface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function registerPaymentGateWay( ContainerInterface $container ) {
|
/**
|
||||||
|
* Registers the payment gateways.
|
||||||
|
*
|
||||||
|
* @param ContainerInterface $container The container.
|
||||||
|
*/
|
||||||
|
private function register_payment_gateways( ContainerInterface $container ) {
|
||||||
|
|
||||||
add_filter(
|
add_filter(
|
||||||
'woocommerce_payment_gateways',
|
'woocommerce_payment_gateways',
|
||||||
static function ( $methods ) use ( $container ): array {
|
static function ( $methods ) use ( $container ): array {
|
||||||
$methods[] = $container->get( 'wcgateway.paypal-gateway' );
|
$methods[] = $container->get( 'wcgateway.paypal-gateway' );
|
||||||
$dccApplies = $container->get( 'api.helpers.dccapplies' );
|
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||||
/**
|
/**
|
||||||
* @var DccApplies $dccApplies
|
* The DCC Applies object.
|
||||||
|
*
|
||||||
|
* @var DccApplies $dcc_applies
|
||||||
*/
|
*/
|
||||||
if ( $dccApplies->forCountryCurrency() ) {
|
if ( $dcc_applies->forCountryCurrency() ) {
|
||||||
$methods[] = $container->get( 'wcgateway.credit-card-gateway' );
|
$methods[] = $container->get( 'wcgateway.credit-card-gateway' );
|
||||||
}
|
}
|
||||||
return (array) $methods;
|
return (array) $methods;
|
||||||
|
@ -148,12 +183,14 @@ class WcGatewayModule implements ModuleInterface {
|
||||||
static function ( $field, $key, $args, $value ) use ( $container ) {
|
static function ( $field, $key, $args, $value ) use ( $container ) {
|
||||||
$renderer = $container->get( 'wcgateway.settings.render' );
|
$renderer = $container->get( 'wcgateway.settings.render' );
|
||||||
/**
|
/**
|
||||||
|
* The Settings Renderer object.
|
||||||
|
*
|
||||||
* @var SettingsRenderer $renderer
|
* @var SettingsRenderer $renderer
|
||||||
*/
|
*/
|
||||||
$field = $renderer->renderMultiSelect( $field, $key, $args, $value );
|
$field = $renderer->render_multiselect( $field, $key, $args, $value );
|
||||||
$field = $renderer->renderPassword( $field, $key, $args, $value );
|
$field = $renderer->render_password( $field, $key, $args, $value );
|
||||||
$field = $renderer->renderTextInput( $field, $key, $args, $value );
|
$field = $renderer->render_text_input( $field, $key, $args, $value );
|
||||||
$field = $renderer->renderHeading( $field, $key, $args, $value );
|
$field = $renderer->render_heading( $field, $key, $args, $value );
|
||||||
return $field;
|
return $field;
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
|
@ -165,6 +202,8 @@ class WcGatewayModule implements ModuleInterface {
|
||||||
static function ( $methods ) use ( $container ): array {
|
static function ( $methods ) use ( $container ): array {
|
||||||
$disabler = $container->get( 'wcgateway.disabler' );
|
$disabler = $container->get( 'wcgateway.disabler' );
|
||||||
/**
|
/**
|
||||||
|
* The Gateay disabler.
|
||||||
|
*
|
||||||
* @var DisableGateways $disabler
|
* @var DisableGateways $disabler
|
||||||
*/
|
*/
|
||||||
return $disabler->handler( (array) $methods );
|
return $disabler->handler( (array) $methods );
|
||||||
|
@ -172,39 +211,53 @@ class WcGatewayModule implements ModuleInterface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function registerOrderFunctionality( ContainerInterface $container ) {
|
/**
|
||||||
|
* Registers the authorize order functionality.
|
||||||
|
*
|
||||||
|
* @param ContainerInterface $container The container.
|
||||||
|
*/
|
||||||
|
private function register_order_functionality( ContainerInterface $container ) {
|
||||||
add_filter(
|
add_filter(
|
||||||
'woocommerce_order_actions',
|
'woocommerce_order_actions',
|
||||||
static function ( $orderActions ): array {
|
static function ( $order_actions ): array {
|
||||||
$orderActions['ppcp_authorize_order'] = __(
|
$order_actions['ppcp_authorize_order'] = __(
|
||||||
'Capture authorized PayPal payment',
|
'Capture authorized PayPal payment',
|
||||||
'woocommerce-paypal-commerce-gateway'
|
'woocommerce-paypal-commerce-gateway'
|
||||||
);
|
);
|
||||||
return $orderActions;
|
return $order_actions;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
add_action(
|
add_action(
|
||||||
'woocommerce_order_action_ppcp_authorize_order',
|
'woocommerce_order_action_ppcp_authorize_order',
|
||||||
static function ( \WC_Order $wcOrder ) use ( $container ) {
|
static function ( \WC_Order $wc_order ) use ( $container ) {
|
||||||
/**
|
/**
|
||||||
|
* The PayPal Gateway.
|
||||||
|
*
|
||||||
* @var PayPalGateway $gateway
|
* @var PayPalGateway $gateway
|
||||||
*/
|
*/
|
||||||
$gateway = $container->get( 'wcgateway.paypal-gateway' );
|
$gateway = $container->get( 'wcgateway.paypal-gateway' );
|
||||||
$gateway->captureAuthorizedPayment( $wcOrder );
|
$gateway->capture_authorized_payment( $wc_order );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function registerColumns( ContainerInterface $container ) {
|
/**
|
||||||
|
* Registers the additional columns on the order list page.
|
||||||
|
*
|
||||||
|
* @param ContainerInterface $container The container.
|
||||||
|
*/
|
||||||
|
private function register_columns( ContainerInterface $container ) {
|
||||||
add_action(
|
add_action(
|
||||||
'woocommerce_order_actions_start',
|
'woocommerce_order_actions_start',
|
||||||
static function ( $wcOrderId ) use ( $container ) {
|
static function ( $wc_order_id ) use ( $container ) {
|
||||||
/**
|
/**
|
||||||
|
* The Payment Status Order Detail.
|
||||||
|
*
|
||||||
* @var PaymentStatusOrderDetail $class
|
* @var PaymentStatusOrderDetail $class
|
||||||
*/
|
*/
|
||||||
$class = $container->get( 'wcgateway.admin.order-payment-status' );
|
$class = $container->get( 'wcgateway.admin.order-payment-status' );
|
||||||
$class->render( intval( $wcOrderId ) );
|
$class->render( intval( $wc_order_id ) );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -212,41 +265,54 @@ class WcGatewayModule implements ModuleInterface {
|
||||||
'manage_edit-shop_order_columns',
|
'manage_edit-shop_order_columns',
|
||||||
static function ( $columns ) use ( $container ) {
|
static function ( $columns ) use ( $container ) {
|
||||||
/**
|
/**
|
||||||
* @var OrderTablePaymentStatusColumn $paymentStatusColumn
|
* The Order Table Payment Status object.
|
||||||
|
*
|
||||||
|
* @var OrderTablePaymentStatusColumn $payment_status_column
|
||||||
*/
|
*/
|
||||||
$paymentStatusColumn = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
$payment_status_column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
||||||
return $paymentStatusColumn->register( $columns );
|
return $payment_status_column->register( $columns );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
add_action(
|
add_action(
|
||||||
'manage_shop_order_posts_custom_column',
|
'manage_shop_order_posts_custom_column',
|
||||||
static function ( $column, $wcOrderId ) use ( $container ) {
|
static function ( $column, $wc_order_id ) use ( $container ) {
|
||||||
/**
|
/**
|
||||||
* @var OrderTablePaymentStatusColumn $paymentStatusColumn
|
* The column object.
|
||||||
|
*
|
||||||
|
* @var OrderTablePaymentStatusColumn $payment_status_column
|
||||||
*/
|
*/
|
||||||
$paymentStatusColumn = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
$payment_status_column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
||||||
$paymentStatusColumn->render( $column, intval( $wcOrderId ) );
|
$payment_status_column->render( $column, intval( $wc_order_id ) );
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function registerCheckoutAddressPreset( ContainerInterface $container ): void {
|
/**
|
||||||
|
* Registers the PayPal Address preset to overwrite Shipping in checkout.
|
||||||
|
*
|
||||||
|
* @param ContainerInterface $container The container.
|
||||||
|
*/
|
||||||
|
private function register_checkout_paypal_address_preset( ContainerInterface $container ): void {
|
||||||
add_filter(
|
add_filter(
|
||||||
'woocommerce_checkout_get_value',
|
'woocommerce_checkout_get_value',
|
||||||
static function ( ...$args ) use ( $container ) {
|
static function ( ...$args ) use ( $container ) {
|
||||||
|
|
||||||
// Its important to not instantiate the service too early as it
|
/**
|
||||||
// depends on SessionHandler and WooCommerce Session
|
* Its important to not instantiate the service too early as it
|
||||||
|
* depends on SessionHandler and WooCommerce Session.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The CheckoutPayPalAddressPreset object.
|
||||||
|
*
|
||||||
* @var CheckoutPayPalAddressPreset $service
|
* @var CheckoutPayPalAddressPreset $service
|
||||||
*/
|
*/
|
||||||
$service = $container->get( 'wcgateway.checkout.address-preset' );
|
$service = $container->get( 'wcgateway.checkout.address-preset' );
|
||||||
|
|
||||||
return $service->filterCheckoutFiled( ...$args );
|
return $service->filter_checkout_field( ...$args );
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
2
|
2
|
|
@ -40,7 +40,7 @@ class CheckoutPayPalAddressPresetTest extends TestCase
|
||||||
|
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
$expected,
|
$expected,
|
||||||
$testee->filterCheckoutFiled(null, $fieldId)
|
$testee->filter_checkout_field(null, $fieldId)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,7 @@ class WcGatewayTest extends TestCase
|
||||||
$sessionHandler
|
$sessionHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertTrue($testee->captureAuthorizedPayment($wcOrder));
|
$this->assertTrue($testee->capture_authorized_payment($wcOrder));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCaptureAuthorizedPaymentHasAlreadyBeenCaptured() {
|
public function testCaptureAuthorizedPaymentHasAlreadyBeenCaptured() {
|
||||||
|
@ -220,7 +220,7 @@ class WcGatewayTest extends TestCase
|
||||||
$sessionHandler
|
$sessionHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertTrue($testee->captureAuthorizedPayment($wcOrder));
|
$this->assertTrue($testee->capture_authorized_payment($wcOrder));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -259,7 +259,7 @@ class WcGatewayTest extends TestCase
|
||||||
$sessionHandler
|
$sessionHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertFalse($testee->captureAuthorizedPayment($wcOrder));
|
$this->assertFalse($testee->capture_authorized_payment($wcOrder));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function dataForTestCaptureAuthorizedPaymentNoActionableFailures() : array
|
public function dataForTestCaptureAuthorizedPaymentNoActionableFailures() : array
|
||||||
|
|
|
@ -63,7 +63,7 @@ class AuthorizedPaymentsProcessorTest extends TestCase
|
||||||
->with(PayPalGateway::ORDER_ID_META_KEY)
|
->with(PayPalGateway::ORDER_ID_META_KEY)
|
||||||
->andReturn($orderId);
|
->andReturn($orderId);
|
||||||
$this->assertTrue($testee->process($wcOrder));
|
$this->assertTrue($testee->process($wcOrder));
|
||||||
$this->assertEquals(AuthorizedPaymentsProcessor::SUCCESSFUL, $testee->lastStatus());
|
$this->assertEquals(AuthorizedPaymentsProcessor::SUCCESSFUL, $testee->last_status());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInaccessible() {
|
public function testInaccessible() {
|
||||||
|
@ -82,7 +82,7 @@ class AuthorizedPaymentsProcessorTest extends TestCase
|
||||||
->with(PayPalGateway::ORDER_ID_META_KEY)
|
->with(PayPalGateway::ORDER_ID_META_KEY)
|
||||||
->andReturn($orderId);
|
->andReturn($orderId);
|
||||||
$this->assertFalse($testee->process($wcOrder));
|
$this->assertFalse($testee->process($wcOrder));
|
||||||
$this->assertEquals(AuthorizedPaymentsProcessor::INACCESSIBLE, $testee->lastStatus());
|
$this->assertEquals(AuthorizedPaymentsProcessor::INACCESSIBLE, $testee->last_status());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNotFound() {
|
public function testNotFound() {
|
||||||
|
@ -101,7 +101,7 @@ class AuthorizedPaymentsProcessorTest extends TestCase
|
||||||
->with(PayPalGateway::ORDER_ID_META_KEY)
|
->with(PayPalGateway::ORDER_ID_META_KEY)
|
||||||
->andReturn($orderId);
|
->andReturn($orderId);
|
||||||
$this->assertFalse($testee->process($wcOrder));
|
$this->assertFalse($testee->process($wcOrder));
|
||||||
$this->assertEquals(AuthorizedPaymentsProcessor::NOT_FOUND, $testee->lastStatus());
|
$this->assertEquals(AuthorizedPaymentsProcessor::NOT_FOUND, $testee->last_status());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCaptureFails() {
|
public function testCaptureFails() {
|
||||||
|
@ -149,7 +149,7 @@ class AuthorizedPaymentsProcessorTest extends TestCase
|
||||||
->with(PayPalGateway::ORDER_ID_META_KEY)
|
->with(PayPalGateway::ORDER_ID_META_KEY)
|
||||||
->andReturn($orderId);
|
->andReturn($orderId);
|
||||||
$this->assertFalse($testee->process($wcOrder));
|
$this->assertFalse($testee->process($wcOrder));
|
||||||
$this->assertEquals(AuthorizedPaymentsProcessor::FAILED, $testee->lastStatus());
|
$this->assertEquals(AuthorizedPaymentsProcessor::FAILED, $testee->last_status());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAllAreCaptured() {
|
public function testAllAreCaptured() {
|
||||||
|
@ -197,6 +197,6 @@ class AuthorizedPaymentsProcessorTest extends TestCase
|
||||||
->with(PayPalGateway::ORDER_ID_META_KEY)
|
->with(PayPalGateway::ORDER_ID_META_KEY)
|
||||||
->andReturn($orderId);
|
->andReturn($orderId);
|
||||||
$this->assertFalse($testee->process($wcOrder));
|
$this->assertFalse($testee->process($wcOrder));
|
||||||
$this->assertEquals(AuthorizedPaymentsProcessor::ALREADY_CAPTURED, $testee->lastStatus());
|
$this->assertEquals(AuthorizedPaymentsProcessor::ALREADY_CAPTURED, $testee->last_status());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -266,7 +266,7 @@ class OrderProcessorTest extends TestCase
|
||||||
$orderIntent
|
$orderIntent
|
||||||
);
|
);
|
||||||
$this->assertFalse($testee->process($wcOrder, $woocommerce));
|
$this->assertFalse($testee->process($wcOrder, $woocommerce));
|
||||||
$this->assertNotEmpty($testee->lastError());
|
$this->assertNotEmpty($testee->last_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue