Fix merge conflict

This commit is contained in:
dinamiko 2021-03-17 09:34:09 +01:00
commit e0f45fac4f
18 changed files with 483 additions and 79 deletions

View file

@ -1,6 +1,6 @@
# WooCommerce PayPal Payments
PayPal's latest complete payments processing solution. Accept PayPal, PayPal Credit, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
## Requirements

View file

@ -36,7 +36,18 @@ class CheckoutActionHandler {
}).then(function (data) {
if (!data.success) {
spinner.unblock();
errorHandler.message(data.data.message, true);
//handle both messages sent from Woocommerce (data.messages) and this plugin (data.data.message)
if (typeof(data.messages) !== 'undefined' )
{
const domParser = new DOMParser();
errorHandler.appendPreparedErrorMessageElement(
domParser.parseFromString(data.messages, 'text/html')
.querySelector('ul')
);
} else {
errorHandler.message(data.data.message, true);
}
return;
}
const input = document.createElement('input');

View file

@ -4,6 +4,7 @@ class ErrorHandler {
{
this.genericErrorText = genericErrorText;
this.wrapper = document.querySelector('.woocommerce-notices-wrapper');
this.messagesList = document.querySelector('ul.woocommerce-error');
}
genericError() {
@ -14,18 +15,55 @@ class ErrorHandler {
this.message(this.genericErrorText)
}
appendPreparedErrorMessageElement(errorMessageElement)
{
if(this.messagesList === null) {
this.prepareMessagesList();
}
this.messagesList.replaceWith(errorMessageElement);
}
message(text, persist = false)
{
this.wrapper.classList.add('woocommerce-error');
if(! typeof String || text.length === 0){
throw new Error('A new message text must be a non-empty string.');
}
if(this.messagesList === null){
this.prepareMessagesList();
}
if (persist) {
this.wrapper.classList.add('ppcp-persist');
} else {
this.wrapper.classList.remove('ppcp-persist');
}
this.wrapper.innerHTML = this.sanitize(text);
let messageNode = this.prepareMessagesListItem(text);
this.messagesList.appendChild(messageNode);
jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'))
}
prepareMessagesList()
{
if(this.messagesList === null){
this.messagesList = document.createElement('ul');
this.messagesList.setAttribute('class', 'woocommerce-error');
this.messagesList.setAttribute('role', 'alert');
this.wrapper.appendChild(this.messagesList);
}
}
prepareMessagesListItem(message)
{
const li = document.createElement('li');
li.innerHTML = message;
return li;
}
sanitize(text)
{
const textarea = document.createElement('textarea');

View file

@ -116,8 +116,8 @@ class CreditCardRenderer {
this.spinner.unblock();
return contextConfig.onApprove(payload);
}).catch(() => {
this.errorHandler.genericError();
this.spinner.unblock();
this.errorHandler.genericError()
});
} else {
this.spinner.unblock();

View file

@ -730,18 +730,9 @@ class SmartButton implements SmartButtonInterface {
$disable_funding[] = 'card';
}
/**
* Disable card for UK.
*/
$region = wc_get_base_location();
$country = $region['country'];
if ( 'GB' === $country ) {
$disable_funding[] = 'credit';
}
if ( count( $disable_funding ) > 0 ) {
$params['disable-funding'] = implode( ',', array_unique( $disable_funding ) );
}
if ( count( $disable_funding ) > 0 ) {
$params['disable-funding'] = implode( ',', array_unique( $disable_funding ) );
}
$smart_button_url = add_query_arg( $params, 'https://www.paypal.com/sdk/js' );
return $smart_button_url;

View file

@ -163,7 +163,7 @@ class CreateOrderEndpoint implements EndpointInterface {
$this->set_bn_code( $data );
$needs_shipping = WC()->cart && WC()->cart->needs_shipping();
$shipping_address_is_fix = $needs_shipping && 'checkout' === $data['context'] ? true : false;
$shipping_address_is_fix = $needs_shipping && 'checkout' === $data['context'];
$order = $this->api_endpoint->create(
$purchase_units,
$this->payer( $data, $wc_order ),
@ -173,7 +173,7 @@ class CreateOrderEndpoint implements EndpointInterface {
$shipping_address_is_fix
);
if ( 'checkout' === $data['context'] ) {
$this->validate_checkout_form( $data['form'], $order );
$this->process_checkout_form( $data['form'], $order );
}
if ( 'pay-now' === $data['context'] && get_option( 'woocommerce_terms_page_id', '' ) !== '' ) {
$this->validate_paynow_form( $data['form'] );
@ -263,7 +263,7 @@ class CreateOrderEndpoint implements EndpointInterface {
*
* @throws \Exception On Error.
*/
private function validate_checkout_form( string $form_values, Order $order ) {
private function process_checkout_form( string $form_values, Order $order ) {
$this->order = $order;
$form_values = explode( '&', $form_values );

View file

@ -24,6 +24,7 @@ class MessagesApply {
'US',
'DE',
'GB',
'FR',
);
/**

View file

@ -9,10 +9,10 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway;
use Dhii\Data\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
use WooCommerce\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail;
@ -22,6 +22,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Checkout\DisableGateways;
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\TransactionUrlProvider;
use Woocommerce\PayPalCommerce\WcGateway\Helper\DccProductStatus;
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
@ -32,7 +33,6 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener;
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
use WpOop\TransientCache\CachePoolFactory;
return array(
'wcgateway.paypal-gateway' => static function ( $container ): PayPalGateway {
@ -44,6 +44,7 @@ return array(
$session_handler = $container->get( 'session.handler' );
$refund_processor = $container->get( 'wcgateway.processor.refunds' );
$state = $container->get( 'onboarding.state' );
$transaction_url_provider = $container->get( 'wcgateway.transaction-url-provider' );
return new PayPalGateway(
$settings_renderer,
@ -53,7 +54,8 @@ return array(
$settings,
$session_handler,
$refund_processor,
$state
$state,
$transaction_url_provider
);
},
'wcgateway.credit-card-gateway' => static function ( $container ): CreditCardGateway {
@ -66,6 +68,8 @@ return array(
$session_handler = $container->get( 'session.handler' );
$refund_processor = $container->get( 'wcgateway.processor.refunds' );
$state = $container->get( 'onboarding.state' );
$transaction_url_provider = $container->get( 'wcgateway.transaction-url-provider' );
return new CreditCardGateway(
$settings_renderer,
$order_processor,
@ -75,7 +79,8 @@ return array(
$module_url,
$session_handler,
$refund_processor,
$state
$state,
$transaction_url_provider
);
},
'wcgateway.disabler' => static function ( $container ): DisableGateways {
@ -131,7 +136,10 @@ return array(
$order_factory = $container->get( 'api.factory.order' );
$threed_secure = $container->get( 'button.helper.three-d-secure' );
$authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' );
$settings = $container->get( 'wcgateway.settings' );
$settings = $container->get( 'wcgateway.settings' );
$environment = $container->get( 'onboarding.environment' );
$logger = $container->get( 'woocommerce.logger.woocommerce' );
return new OrderProcessor(
$session_handler,
$cart_repository,
@ -140,7 +148,9 @@ return array(
$order_factory,
$threed_secure,
$authorized_payments_processor,
$settings
$settings,
$logger,
$environment->current_environment_is( Environment::SANDBOX )
);
},
'wcgateway.processor.refunds' => static function ( $container ): RefundProcessor {
@ -1800,6 +1810,28 @@ return array(
$fields['message_cart_heading']['description'] = __( 'Display pay later messaging on your site for offers like Pay in 3, which lets customers pay with 3 interest-free monthly payments. Well show messages on your site to promote this feature for you. You may not promote pay later offers with any other content, marketing, or materials.', 'woocommerce-paypal-payments' );
}
if ( 'FR' === $country ) {
// todo: replace this with the text in English and use this text for French translation when it will be created.
$french_pay_later_description = 'Affichez le Paiement en 4X PayPal sur votre site.' .
'Le Paiement en 4X PayPal permet aux consommateurs français de payer en 4 versements égaux.' .
'Vous pouvez promouvoir le Paiement en 4X PayPal uniquement si vous êtes un commerçant basé en France, ' .
'avec un site internet en français et uneintégration PayPal standard. ' .
'Les marchands ayantloutil Vaulting(coffre-fort numérique) ou une intégration de paiements récurrents/abonnement, ' .
'ainsi que ceux présentant certaines activités (vente de biens numériques / de biens non physiques) ' .
'ne sont pas éligibles pour promouvoir le Paiement en 4X PayPal.' .
'Nous afficherons des messages sur votre site pour promouvoir le Paiement en 4X PayPal. ' .
'Vous ne pouvez pas promouvoir le Paiement en 4X PayPal avec un autre contenu, quel quil soit.';
$fields['message_heading']['heading'] = __( 'Pay Later Messaging on Checkout', 'woocommerce-paypal-payments' );
$fields['message_heading']['description'] = $french_pay_later_description;
$fields['message_product_heading']['heading'] = __( 'Pay Later Messaging on Single Product Page', 'woocommerce-paypal-payments' );
$fields['message_product_heading']['description'] = $french_pay_later_description;
$fields['message_cart_heading']['heading'] = __( 'Pay Later Messaging on Cart', 'woocommerce-paypal-payments' );
$fields['message_cart_heading']['description'] = $french_pay_later_description;
}
/**
* Set Pay Later link for DE
*/
@ -1852,6 +1884,22 @@ return array(
$prefix
);
},
'wcgateway.transaction-url-sandbox' => static function ( $container ): string {
return 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
},
'wcgateway.transaction-url-live' => static function ( $container ): string {
return 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
},
'wcgateway.transaction-url-provider' => static function ( $container ): TransactionUrlProvider {
$sandbox_url_base = $container->get( 'wcgateway.transaction-url-sandbox' );
$live_url_base = $container->get( 'wcgateway.transaction-url-live' );
return new TransactionUrlProvider( $sandbox_url_base, $live_url_base );
},
'wcgateway.helper.dcc-product-status' => static function ( $container ) : DccProductStatus {
$settings = $container->get( 'wcgateway.settings' );

View file

@ -27,6 +27,13 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
const ID = 'ppcp-credit-card-gateway';
/**
* Service to get transaction url for an order.
*
* @var TransactionUrlProvider
*/
protected $transaction_url_provider;
/**
* The URL to the module.
*
@ -53,6 +60,7 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
* @param SessionHandler $session_handler The Session Handler.
* @param RefundProcessor $refund_processor The refund processor.
* @param State $state The state.
* @param TransactionUrlProvider $transaction_url_provider Service able to provide view transaction url base.
*/
public function __construct(
SettingsRenderer $settings_renderer,
@ -63,7 +71,8 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
string $module_url,
SessionHandler $session_handler,
RefundProcessor $refund_processor,
State $state
State $state,
TransactionUrlProvider $transaction_url_provider
) {
$this->id = self::ID;
@ -125,7 +134,8 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
)
);
$this->module_url = $module_url;
$this->module_url = $module_url;
$this->transaction_url_provider = $transaction_url_provider;
}
/**
@ -250,4 +260,17 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
}
return $this->refund_processor->process( $order, (float) $amount, (string) $reason );
}
/**
* Set the class property then call parent function.
*
* @param \WC_Order $order WC Order to get transaction url for.
*
* @inheritDoc
*/
public function get_transaction_url( $order ): string {
$this->view_transaction_url = $this->transaction_url_provider->get_transaction_url_base( $order );
return parent::get_transaction_url( $order );
}
}

View file

@ -9,7 +9,6 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
@ -27,10 +26,11 @@ class PayPalGateway extends \WC_Payment_Gateway {
use ProcessPaymentTrait;
const ID = 'ppcp-gateway';
const CAPTURED_META_KEY = '_ppcp_paypal_captured';
const INTENT_META_KEY = '_ppcp_paypal_intent';
const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
const ID = 'ppcp-gateway';
const CAPTURED_META_KEY = '_ppcp_paypal_captured';
const INTENT_META_KEY = '_ppcp_paypal_intent';
const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
/**
* The Settings Renderer.
@ -74,6 +74,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
*/
protected $session_handler;
/**
* Service able to provide transaction url for an order.
*
* @var TransactionUrlProvider
*/
protected $transaction_url_provider;
/**
* The Refund Processor.
*
@ -92,6 +99,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
* @param SessionHandler $session_handler The Session Handler.
* @param RefundProcessor $refund_processor The Refund Processor.
* @param State $state The state.
* @param TransactionUrlProvider $transaction_url_provider Service providing transaction view URL based on order.
*/
public function __construct(
SettingsRenderer $settings_renderer,
@ -101,17 +109,19 @@ class PayPalGateway extends \WC_Payment_Gateway {
ContainerInterface $config,
SessionHandler $session_handler,
RefundProcessor $refund_processor,
State $state
State $state,
TransactionUrlProvider $transaction_url_provider
) {
$this->id = self::ID;
$this->order_processor = $order_processor;
$this->authorized_payments = $authorized_payments_processor;
$this->notice = $notice;
$this->settings_renderer = $settings_renderer;
$this->config = $config;
$this->session_handler = $session_handler;
$this->refund_processor = $refund_processor;
$this->id = self::ID;
$this->order_processor = $order_processor;
$this->authorized_payments = $authorized_payments_processor;
$this->notice = $notice;
$this->settings_renderer = $settings_renderer;
$this->config = $config;
$this->session_handler = $session_handler;
$this->refund_processor = $refund_processor;
$this->transaction_url_provider = $transaction_url_provider;
if ( $state->current_state() === State::STATE_ONBOARDED ) {
$this->supports = array( 'refunds' );
@ -340,4 +350,17 @@ class PayPalGateway extends \WC_Payment_Gateway {
}
return $this->refund_processor->process( $order, (float) $amount, (string) $reason );
}
/**
* Return transaction url for this gateway and given order.
*
* @param \WC_Order $order WC order to get transaction url by.
*
* @return string
*/
public function get_transaction_url( $order ): string {
$this->view_transaction_url = $this->transaction_url_provider->get_transaction_url_base( $order );
return parent::get_transaction_url( $order );
}
}

View file

@ -0,0 +1,59 @@
<?php
/**
* Service able to provide transaction url base (URL with the placeholder instead of an actual transaction id)
* based on the given WC Order.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
/**
* Class TransactionUrlProvider
*/
class TransactionUrlProvider {
/**
* Transaction URL base used for sandbox payments.
*
* @var string
*/
protected $transaction_url_base_sandbox;
/**
* Transaction URL base used for live payments.
*
* @var string
*/
protected $transaction_url_base_live;
/**
* TransactionUrlProvider constructor.
*
* @param string $transaction_url_base_sandbox URL for sandbox orders.
* @param string $transaction_url_base_live URL for live orders.
*/
public function __construct(
string $transaction_url_base_sandbox,
string $transaction_url_base_live
) {
$this->transaction_url_base_sandbox = $transaction_url_base_sandbox;
$this->transaction_url_base_live = $transaction_url_base_live;
}
/**
* Return transaction url base
*
* @param \WC_Order $order WC order to get payment type from.
*
* @return string
*/
public function get_transaction_url_base( \WC_Order $order ): string {
$order_payment_mode = $order->get_meta( PayPalGateway::ORDER_PAYMENT_MODE_META_KEY, true );
return 'sandbox' === $order_payment_mode ? $this->transaction_url_base_sandbox : $this->transaction_url_base_live;
}
}

View file

@ -1,18 +0,0 @@
<?php
/**
* The WcGateway interface.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
/**
* Interface WcGatewayInterface
*/
interface WcGatewayInterface {
}

View file

@ -9,6 +9,7 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
@ -25,6 +26,13 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
*/
class OrderProcessor {
/**
* Whether current payment mode is sandbox.
*
* @var bool
*/
protected $sandbox_mode;
/**
* The Session Handler.
*
@ -88,6 +96,13 @@ class OrderProcessor {
*/
private $last_error = '';
/**
* A logger.
*
* @var LoggerInterface
*/
private $logger;
/**
* OrderProcessor constructor.
*
@ -99,6 +114,8 @@ class OrderProcessor {
* @param ThreeDSecure $three_d_secure The ThreeDSecure Helper.
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
* @param Settings $settings The Settings.
* @param LoggerInterface $logger A logger service.
* @param bool $sandbox_mode Whether sandbox mode enabled.
*/
public function __construct(
SessionHandler $session_handler,
@ -108,7 +125,9 @@ class OrderProcessor {
OrderFactory $order_factory,
ThreeDSecure $three_d_secure,
AuthorizedPaymentsProcessor $authorized_payments_processor,
Settings $settings
Settings $settings,
LoggerInterface $logger,
bool $sandbox_mode
) {
$this->session_handler = $session_handler;
@ -119,6 +138,8 @@ class OrderProcessor {
$this->threed_secure = $three_d_secure;
$this->authorized_payments_processor = $authorized_payments_processor;
$this->settings = $settings;
$this->sandbox_mode = $sandbox_mode;
$this->logger = $logger;
}
/**
@ -136,9 +157,13 @@ class OrderProcessor {
}
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
$wc_order->update_meta_data(
PayPalGateway::ORDER_PAYMENT_MODE_META_KEY,
$this->sandbox_mode ? 'sandbox' : 'live'
);
$error_message = null;
if ( ! $order || ! $this->order_is_approved( $order ) ) {
if ( ! $this->order_is_approved( $order ) ) {
$error_message = __(
'The payment has not been approved yet.',
'woocommerce-paypal-payments'
@ -163,6 +188,12 @@ class OrderProcessor {
$wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
}
$transaction_id = $this->get_paypal_order_transaction_id( $order );
if ( '' !== $transaction_id ) {
$this->set_order_transaction_id( $transaction_id, $wc_order );
}
$wc_order->update_status(
'on-hold',
__( 'Awaiting payment.', 'woocommerce-paypal-payments' )
@ -187,6 +218,55 @@ class OrderProcessor {
return true;
}
/**
* Set transaction id to WC order meta data.
*
* @param string $transaction_id Transaction id to set.
* @param \WC_Order $wc_order Order to set transaction ID to.
*/
public function set_order_transaction_id( string $transaction_id, \WC_Order $wc_order ) {
try {
$wc_order->set_transaction_id( $transaction_id );
} catch ( \WC_Data_Exception $exception ) {
$this->logger->log(
'warning',
sprintf(
'Failed to set transaction ID. Exception caught when tried: %1$s',
$exception->getMessage()
)
);
}
}
/**
* Retrieve transaction id from PayPal order.
*
* @param Order $order Order to get transaction id from.
*
* @return string
*/
private function get_paypal_order_transaction_id( Order $order ): string {
$purchase_units = $order->purchase_units();
if ( ! isset( $purchase_units[0] ) ) {
return '';
}
$payments = $purchase_units[0]->payments();
if ( null === $payments ) {
return '';
}
$captures = $payments->captures();
if ( isset( $captures[0] ) ) {
return $captures[0]->id();
}
return '';
}
/**
* Returns if an order should be captured immediately.
*

View file

@ -8,7 +8,7 @@ Stable tag: 1.2.1
License: GPLv2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
PayPal's latest payments processing solution. Accept PayPal, PayPal Credit, credit/debit cards, alternative digital wallets and bank accounts.
PayPal's latest payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets and bank accounts.
== Description ==

View file

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
use WooCommerce\PayPalCommerce\TestCase;
class TransactionUrlProviderTest extends TestCase
{
/**
* @dataProvider getTransactionUrlDataProvider
*/
public function testGetTransactionUrlBase(
string $sandboxUrl,
string $liveUrl,
string $orderPaymentMode,
$expectedResult
) {
$testee = new TransactionUrlProvider($sandboxUrl, $liveUrl);
$wcOrder = \Mockery::mock(\WC_Order::class);
$wcOrder->expects('get_meta')
->with(PayPalGateway::ORDER_PAYMENT_MODE_META_KEY, true)
->andReturn($orderPaymentMode);
$this->assertSame($expectedResult, $testee->get_transaction_url_base($wcOrder));
}
function getTransactionUrlDataProvider(): array
{
$sandboxUrl = 'sandbox.example.com';
$liveUrl = 'example.com';
return [
[
$sandboxUrl, $liveUrl, 'sandbox', $sandboxUrl
],
[
$sandboxUrl, $liveUrl, 'live', $liveUrl
],
[
$sandboxUrl, $liveUrl, '', $liveUrl
]
];
}
}

View file

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\TestCase;
@ -45,6 +44,7 @@ class WcGatewayTest extends TestCase
$settings
->shouldReceive('has')->andReturnFalse();
$refundProcessor = Mockery::mock(RefundProcessor::class);
$transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$state = Mockery::mock(State::class);
$state
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
@ -56,7 +56,8 @@ class WcGatewayTest extends TestCase
$settings,
$sessionHandler,
$refundProcessor,
$state
$state,
$transactionUrlProvider
);
expect('wc_get_order')
@ -86,6 +87,7 @@ class WcGatewayTest extends TestCase
$sessionHandler = Mockery::mock(SessionHandler::class);
$refundProcessor = Mockery::mock(RefundProcessor::class);
$state = Mockery::mock(State::class);
$transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$state
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
$testee = new PayPalGateway(
@ -96,7 +98,8 @@ class WcGatewayTest extends TestCase
$settings,
$sessionHandler,
$refundProcessor,
$state
$state,
$transactionUrlProvider
);
expect('wc_get_order')
@ -132,6 +135,7 @@ class WcGatewayTest extends TestCase
$sessionHandler = Mockery::mock(SessionHandler::class);
$refundProcessor = Mockery::mock(RefundProcessor::class);
$state = Mockery::mock(State::class);
$transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$state
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
$testee = new PayPalGateway(
@ -142,7 +146,8 @@ class WcGatewayTest extends TestCase
$settings,
$sessionHandler,
$refundProcessor,
$state
$state,
$transactionUrlProvider
);
expect('wc_get_order')
@ -193,6 +198,7 @@ class WcGatewayTest extends TestCase
$sessionHandler = Mockery::mock(SessionHandler::class);
$refundProcessor = Mockery::mock(RefundProcessor::class);
$state = Mockery::mock(State::class);
$transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$state
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
$testee = new PayPalGateway(
@ -203,7 +209,8 @@ class WcGatewayTest extends TestCase
$settings,
$sessionHandler,
$refundProcessor,
$state
$state,
$transactionUrlProvider
);
$this->assertTrue($testee->capture_authorized_payment($wcOrder));
@ -246,6 +253,7 @@ class WcGatewayTest extends TestCase
$sessionHandler = Mockery::mock(SessionHandler::class);
$refundProcessor = Mockery::mock(RefundProcessor::class);
$state = Mockery::mock(State::class);
$transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$state
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
$testee = new PayPalGateway(
@ -256,7 +264,8 @@ class WcGatewayTest extends TestCase
$settings,
$sessionHandler,
$refundProcessor,
$state
$state,
$transactionUrlProvider
);
$this->assertTrue($testee->capture_authorized_payment($wcOrder));
@ -292,6 +301,7 @@ class WcGatewayTest extends TestCase
$sessionHandler = Mockery::mock(SessionHandler::class);
$refundProcessor = Mockery::mock(RefundProcessor::class);
$state = Mockery::mock(State::class);
$transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$state
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
$testee = new PayPalGateway(
@ -302,7 +312,8 @@ class WcGatewayTest extends TestCase
$settings,
$sessionHandler,
$refundProcessor,
$state
$state,
$transactionUrlProvider
);
$this->assertFalse($testee->capture_authorized_payment($wcOrder));
@ -325,4 +336,4 @@ class WcGatewayTest extends TestCase
],
];
}
}
}

View file

@ -4,10 +4,14 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
@ -15,14 +19,32 @@ use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\TestCase;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use WooCommerce\WooCommerce\Logging\WooCommerceLoggingModule;
use Mockery;
class OrderProcessorTest extends TestCase
{
public function testAuthorize() {
$transactionId = 'ABC123';
$capture = Mockery::mock(Capture::class);
$capture->expects('id')
->andReturn($transactionId);
$payments = Mockery::mock(Payments::class);
$payments->expects('captures')
->andReturn([$capture]);
$purchaseUnit = Mockery::mock(PurchaseUnit::class);
$purchaseUnit->expects('payments')
->andReturn($payments);
$wcOrder = Mockery::mock(\WC_Order::class);
$wcOrder->expects('update_meta_data')
->with(PayPalGateway::ORDER_PAYMENT_MODE_META_KEY, 'live');
$wcOrder->expects('set_transaction_id')
->with($transactionId);
$orderStatus = Mockery::mock(OrderStatus::class);
$orderStatus
->expects('is')
@ -32,8 +54,10 @@ class OrderProcessorTest extends TestCase
->expects('is')
->with(OrderStatus::COMPLETED)
->andReturn(true);
$orderId = 'abc';
$orderIntent = 'AUTHORIZE';
$currentOrder = Mockery::mock(Order::class);
$currentOrder
->expects('id')
@ -44,13 +68,18 @@ class OrderProcessorTest extends TestCase
$currentOrder
->shouldReceive('status')
->andReturn($orderStatus);
$currentOrder->expects('purchase_units')
->andReturn([$purchaseUnit]);
$sessionHandler = Mockery::mock(SessionHandler::class);
$sessionHandler
->expects('order')
->andReturn($currentOrder);
$sessionHandler
->expects('destroy_session_data');
$cartRepository = Mockery::mock(CartRepository::class);
$orderEndpoint = Mockery::mock(OrderEndpoint::class);
$orderEndpoint
->expects('patch_order_with')
@ -60,19 +89,26 @@ class OrderProcessorTest extends TestCase
->expects('authorize')
->with($currentOrder)
->andReturn($currentOrder);
$paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$orderFactory = Mockery::mock(OrderFactory::class);
$orderFactory
->expects('from_wc_order')
->with($wcOrder, $currentOrder)
->andReturn($currentOrder);
$threeDSecure = Mockery::mock(ThreeDSecure::class);
$authorizedPaymentProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$settings = Mockery::mock(Settings::class);
$settings
->shouldReceive('has')
->andReturnFalse();
$logger = Mockery::mock(LoggerInterface::class);
$testee = new OrderProcessor(
$sessionHandler,
$cartRepository,
@ -81,7 +117,9 @@ class OrderProcessorTest extends TestCase
$orderFactory,
$threeDSecure,
$authorizedPaymentProcessor,
$settings
$settings,
$logger,
false
);
$cart = Mockery::mock(\WC_Cart::class);
@ -115,6 +153,20 @@ class OrderProcessorTest extends TestCase
}
public function testCapture() {
$transactionId = 'ABC123';
$capture = Mockery::mock(Capture::class);
$capture->expects('id')
->andReturn($transactionId);
$payments = Mockery::mock(Payments::class);
$payments->expects('captures')
->andReturn([$capture]);
$purchaseUnit = Mockery::mock(PurchaseUnit::class);
$purchaseUnit->expects('payments')
->andReturn($payments);
$wcOrder = Mockery::mock(\WC_Order::class);
$orderStatus = Mockery::mock(OrderStatus::class);
$orderStatus
@ -137,6 +189,9 @@ class OrderProcessorTest extends TestCase
$currentOrder
->shouldReceive('status')
->andReturn($orderStatus);
$currentOrder
->expects('purchase_units')
->andReturn([$purchaseUnit]);
$sessionHandler = Mockery::mock(SessionHandler::class);
$sessionHandler
->expects('order')
@ -166,7 +221,10 @@ class OrderProcessorTest extends TestCase
->shouldReceive('has')
->andReturnFalse();
$testee = new OrderProcessor(
$logger = Mockery::mock(LoggerInterface::class);
$testee = new OrderProcessor(
$sessionHandler,
$cartRepository,
$orderEndpoint,
@ -174,7 +232,9 @@ class OrderProcessorTest extends TestCase
$orderFactory,
$threeDSecure,
$authorizedPaymentProcessor,
$settings
$settings,
$logger,
false
);
$cart = Mockery::mock(\WC_Cart::class);
@ -198,6 +258,10 @@ class OrderProcessorTest extends TestCase
$wcOrder
->expects('update_status')
->with('on-hold', 'Awaiting payment.');
$wcOrder->expects('update_meta_data')
->with(PayPalGateway::ORDER_PAYMENT_MODE_META_KEY, 'live');
$wcOrder->expects('set_transaction_id')
->with($transactionId);
$wcOrder
->expects('update_status')
->with('processing', 'Payment received.');
@ -205,7 +269,26 @@ class OrderProcessorTest extends TestCase
}
public function testError() {
$transactionId = 'ABC123';
$capture = Mockery::mock(Capture::class);
$capture->shouldReceive('id')
->andReturn($transactionId);
$payments = Mockery::mock(Payments::class);
$payments->shouldReceive('captures')
->andReturn([$capture]);
$purchaseUnit = Mockery::mock(PurchaseUnit::class);
$purchaseUnit->shouldReceive('payments')
->andReturn($payments);
$wcOrder = Mockery::mock(\WC_Order::class);
$wcOrder->expects('update_meta_data')
->with(PayPalGateway::ORDER_PAYMENT_MODE_META_KEY, 'live');
$wcOrder->shouldReceive('set_transaction_id')
->with($transactionId);
$orderStatus = Mockery::mock(OrderStatus::class);
$orderStatus
->expects('is')
@ -226,6 +309,9 @@ class OrderProcessorTest extends TestCase
$currentOrder
->shouldReceive('payment_source')
->andReturnNull();
$currentOrder
->shouldReceive('purchase_units')
->andReturn([$purchaseUnit]);
$sessionHandler = Mockery::mock(SessionHandler::class);
$sessionHandler
->expects('order')
@ -238,7 +324,9 @@ class OrderProcessorTest extends TestCase
$authorizedPaymentProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$settings = Mockery::mock(Settings::class);
$testee = new OrderProcessor(
$logger = Mockery::mock(LoggerInterface::class);
$testee = new OrderProcessor(
$sessionHandler,
$cartRepository,
$orderEndpoint,
@ -246,7 +334,9 @@ class OrderProcessorTest extends TestCase
$orderFactory,
$threeDSecure,
$authorizedPaymentProcessor,
$settings
$settings,
$logger,
false
);
$cart = Mockery::mock(\WC_Cart::class);
@ -270,4 +360,4 @@ class OrderProcessorTest extends TestCase
}
}
}

View file

@ -2,7 +2,7 @@
/**
* Plugin Name: WooCommerce PayPal Payments
* Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
* Description: PayPal's latest complete payments processing solution. Accept PayPal, PayPal Credit, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
* Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
* Version: 1.2.1
* Author: WooCommerce
* Author URI: https://woocommerce.com/