Show "Venmo" instead of "PayPal" when using its' button

This commit is contained in:
Alex P 2021-12-09 17:29:48 +02:00
parent cf5d1ec21f
commit f4a32a01e7
8 changed files with 155 additions and 161 deletions

View file

@ -14,7 +14,10 @@ const bootstrap = () => {
const errorHandler = new ErrorHandler(PayPalCommerceGateway.labels.error.generic);
const spinner = new Spinner();
const creditCardRenderer = new CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);
const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway);
const onSmartButtonClick = data => {
window.ppcpFundingSource = data.fundingSource;
};
const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick);
const messageRenderer = new MessageRenderer(PayPalCommerceGateway.messages);
const context = PayPalCommerceGateway.context;
if (context === 'mini-cart' || context === 'product') {

View file

@ -4,7 +4,8 @@ const onApprove = (context, errorHandler) => {
method: 'POST',
body: JSON.stringify({
nonce: context.config.ajax.approve_order.nonce,
order_id:data.orderID
order_id:data.orderID,
funding_source: window.ppcpFundingSource,
})
}).then((res)=>{
return res.json();
@ -13,7 +14,7 @@ const onApprove = (context, errorHandler) => {
errorHandler.genericError();
return actions.restart().catch(err => {
errorHandler.genericError();
});;
});
}
location.href = context.config.redirect;
});

View file

@ -5,7 +5,8 @@ const onApprove = (context, errorHandler, spinner) => {
method: 'POST',
body: JSON.stringify({
nonce: context.config.ajax.approve_order.nonce,
order_id:data.orderID
order_id:data.orderID,
funding_source: window.ppcpFundingSource,
})
}).then((res)=>{
return res.json();

View file

@ -1,7 +1,8 @@
class Renderer {
constructor(creditCardRenderer, defaultConfig) {
constructor(creditCardRenderer, defaultConfig, onSmartButtonClick) {
this.defaultConfig = defaultConfig;
this.creditCardRenderer = creditCardRenderer;
this.onSmartButtonClick = onSmartButtonClick;
}
render(wrapper, hostedFieldsWrapper, contextConfig) {
@ -19,6 +20,7 @@ class Renderer {
paypal.Buttons({
style,
...contextConfig,
onClick: this.onSmartButtonClick,
}).render(wrapper);
}

View file

@ -184,6 +184,9 @@ class ApproveOrderEndpoint implements EndpointInterface {
throw new RuntimeException( $message );
}
$funding_source = $data['funding_source'] ?? null;
$this->session_handler->replace_funding_source( $funding_source );
$this->session_handler->replace_order( $order );
wp_send_json_success( $order );
return true;

View file

@ -40,6 +40,13 @@ class SessionHandler {
*/
private $insufficient_funding_tries = 0;
/**
* The funding source of the current checkout (venmo, ...) or null.
*
* @var string|null
*/
private $funding_source = null;
/**
* Returns the order.
*
@ -84,6 +91,28 @@ class SessionHandler {
return $this;
}
/**
* Returns the funding source of the current checkout (venmo, ...) or null.
*
* @return string|null
*/
public function funding_source(): ?string {
return $this->funding_source;
}
/**
* Replaces the funding source of the current checkout.
*
* @param string|null $funding_source The funding source.
*
* @return SessionHandler
*/
public function replace_funding_source( ?string $funding_source ): SessionHandler {
$this->funding_source = $funding_source;
$this->store_session();
return $this;
}
/**
* Returns how many times the customer tried to use the PayPal Gateway in this session.
*
@ -113,6 +142,7 @@ class SessionHandler {
$this->order = null;
$this->bn_code = '';
$this->insufficient_funding_tries = 0;
$this->funding_source = null;
$this->store_session();
return $this;
}

View file

@ -241,6 +241,12 @@ class PayPalGateway extends \WC_Payment_Gateway {
$this->description = $this->config->has( 'description' ) ?
$this->config->get( 'description' ) : $this->method_description;
$funding_source = $this->session_handler->funding_source();
if ( 'venmo' === $funding_source ) {
$this->title = 'Venmo';
$this->description = __( 'Pay via Venmo.', 'woocommerce-paypal-payments' );
}
$this->init_form_fields();
$this->init_settings();

View file

@ -28,75 +28,104 @@ use function Brain\Monkey\Functions\when;
class WcGatewayTest extends TestCase
{
private $isAdmin = false;
private $sessionHandler;
private $fundingSource = null;
private $settingsRenderer;
private $orderProcessor;
private $authorizedOrdersProcessor;
private $settings;
private $refundProcessor;
private $onboardingState;
private $transactionUrlProvider;
private $subscriptionHelper;
private $environment;
private $paymentTokenRepository;
private $logger;
private $paymentsEndpoint;
private $orderEndpoint;
public function setUp(): void {
parent::setUp();
expect('is_admin')->andReturnUsing(function () {
return $this->isAdmin;
});
$this->settingsRenderer = Mockery::mock(SettingsRenderer::class);
$this->orderProcessor = Mockery::mock(OrderProcessor::class);
$this->authorizedOrdersProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$this->settings = Mockery::mock(Settings::class);
$this->sessionHandler = Mockery::mock(SessionHandler::class);
$this->refundProcessor = Mockery::mock(RefundProcessor::class);
$this->onboardingState = Mockery::mock(State::class);
$this->transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$this->subscriptionHelper = Mockery::mock(SubscriptionHelper::class);
$this->environment = Mockery::mock(Environment::class);
$this->paymentTokenRepository = Mockery::mock(PaymentTokenRepository::class);
$this->logger = Mockery::mock(LoggerInterface::class);
$this->paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$this->orderEndpoint = Mockery::mock(OrderEndpoint::class);
$this->onboardingState->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
$this->sessionHandler
->shouldReceive('funding_source')
->andReturnUsing(function () {
return $this->fundingSource;
});
$this->settings->shouldReceive('has')->andReturnFalse();
$this->logger->shouldReceive('info');
}
private function createGateway()
{
return new PayPalGateway(
$this->settingsRenderer,
$this->orderProcessor,
$this->authorizedOrdersProcessor,
$this->settings,
$this->sessionHandler,
$this->refundProcessor,
$this->onboardingState,
$this->transactionUrlProvider,
$this->subscriptionHelper,
PayPalGateway::ID,
$this->environment,
$this->paymentTokenRepository,
$this->logger,
$this->paymentsEndpoint,
$this->orderEndpoint
);
}
public function testProcessPaymentSuccess() {
expect('is_admin')->andReturn(false);
$orderId = 1;
$wcOrder = Mockery::mock(\WC_Order::class);
$wcOrder->shouldReceive('get_customer_id')->andReturn(1);
$wcOrder->shouldReceive('get_meta')->andReturn('');
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$orderProcessor
$this->orderProcessor
->expects('process')
->andReturnUsing(
function(\WC_Order $order) use ($wcOrder) : bool {
return $order === $wcOrder;
}
);
$authorizedPaymentsProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$settings = Mockery::mock(Settings::class);
$sessionHandler = Mockery::mock(SessionHandler::class);
$sessionHandler
$this->sessionHandler
->shouldReceive('destroy_session_data');
$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);
$subscriptionHelper = Mockery::mock(SubscriptionHelper::class);
$subscriptionHelper
$this->subscriptionHelper
->shouldReceive('has_subscription')
->with($orderId)
->andReturn(true)
->andReturn(false);
$subscriptionHelper
$this->subscriptionHelper
->shouldReceive('is_subscription_change_payment')
->andReturn(true);
$paymentTokenRepository = Mockery::mock(PaymentTokenRepository::class);
$logger = Mockery::mock(LoggerInterface::class);
$logger->shouldReceive('info');
$paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$orderEndpoint = Mockery::mock(OrderEndpoint::class);
$testee = new PayPalGateway(
$settingsRenderer,
$orderProcessor,
$authorizedPaymentsProcessor,
$settings,
$sessionHandler,
$refundProcessor,
$state,
$transactionUrlProvider,
$subscriptionHelper,
PayPalGateway::ID,
$this->environment,
$paymentTokenRepository,
$logger,
$paymentsEndpoint,
$orderEndpoint
);
$testee = $this->createGateway();
expect('wc_get_order')
->with($orderId)
@ -121,45 +150,9 @@ class WcGatewayTest extends TestCase
}
public function testProcessPaymentOrderNotFound() {
expect('is_admin')->andReturn(false);
$orderId = 1;
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$authorizedPaymentsProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$settings = Mockery::mock(Settings::class);
$settings
->shouldReceive('has')->andReturnFalse();
$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);
$subscriptionHelper = Mockery::mock(SubscriptionHelper::class);
$paymentTokenRepository = Mockery::mock(PaymentTokenRepository::class);
$logger = Mockery::mock(LoggerInterface::class);
$paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$orderEndpoint = Mockery::mock(OrderEndpoint::class);
$testee = new PayPalGateway(
$settingsRenderer,
$orderProcessor,
$authorizedPaymentsProcessor,
$settings,
$sessionHandler,
$refundProcessor,
$state,
$transactionUrlProvider,
$subscriptionHelper,
PayPalGateway::ID,
$this->environment,
$paymentTokenRepository,
$logger,
$paymentsEndpoint,
$orderEndpoint
);
$testee = $this->createGateway();
expect('wc_get_order')
->with($orderId)
@ -184,56 +177,20 @@ class WcGatewayTest extends TestCase
public function testProcessPaymentFails() {
expect('is_admin')->andReturn(false);
$orderId = 1;
$wcOrder = Mockery::mock(\WC_Order::class);
$lastError = 'some-error';
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$orderProcessor
$this->orderProcessor
->expects('process')
->andReturnFalse();
$orderProcessor
$this->orderProcessor
->expects('last_error')
->andReturn($lastError);
$authorizedPaymentsProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$settings = Mockery::mock(Settings::class);
$settings
->shouldReceive('has')->andReturnFalse();
$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);
$subscriptionHelper = Mockery::mock(SubscriptionHelper::class);
$subscriptionHelper->shouldReceive('has_subscription')->with($orderId)->andReturn(true);
$subscriptionHelper->shouldReceive('is_subscription_change_payment')->andReturn(true);
$this->subscriptionHelper->shouldReceive('has_subscription')->with($orderId)->andReturn(true);
$this->subscriptionHelper->shouldReceive('is_subscription_change_payment')->andReturn(true);
$wcOrder->shouldReceive('update_status')->andReturn(true);
$paymentTokenRepository = Mockery::mock(PaymentTokenRepository::class);
$logger = Mockery::mock(LoggerInterface::class);
$paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$orderEndpoint = Mockery::mock(OrderEndpoint::class);
$testee = new PayPalGateway(
$settingsRenderer,
$orderProcessor,
$authorizedPaymentsProcessor,
$settings,
$sessionHandler,
$refundProcessor,
$state,
$transactionUrlProvider,
$subscriptionHelper,
PayPalGateway::ID,
$this->environment,
$paymentTokenRepository,
$logger,
$paymentsEndpoint,
$orderEndpoint
);
$testee = $this->createGateway();
expect('wc_get_order')
->with($orderId)
@ -261,49 +218,31 @@ class WcGatewayTest extends TestCase
*/
public function testNeedsSetup($currentState, $needSetup)
{
expect('is_admin')->andReturn(true);
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$authorizedOrdersProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$config = Mockery::mock(ContainerInterface::class);
$config
->shouldReceive('has')
->andReturn(false);
$sessionHandler = Mockery::mock(SessionHandler::class);
$refundProcessor = Mockery::mock(RefundProcessor::class);
$onboardingState = Mockery::mock(State::class);
$onboardingState
$this->isAdmin = true;
$this->onboardingState = Mockery::mock(State::class);
$this->onboardingState
->expects('current_state')
->andReturn($currentState);
$transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$subscriptionHelper = Mockery::mock(SubscriptionHelper::class);
$paymentTokenRepository = Mockery::mock(PaymentTokenRepository::class);
$logger = Mockery::mock(LoggerInterface::class);
$paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$orderEndpoint = Mockery::mock(OrderEndpoint::class);
$testee = new PayPalGateway(
$settingsRenderer,
$orderProcessor,
$authorizedOrdersProcessor,
$config,
$sessionHandler,
$refundProcessor,
$onboardingState,
$transactionUrlProvider,
$subscriptionHelper,
PayPalGateway::ID,
$this->environment,
$paymentTokenRepository,
$logger,
$paymentsEndpoint,
$orderEndpoint
);
$testee = $this->createGateway();
$this->assertSame($needSetup, $testee->needs_setup());
}
/**
* @dataProvider dataForFundingSource
*/
public function testFundingSource($fundingSource, $title, $description)
{
$this->fundingSource = $fundingSource;
$testee = $this->createGateway();
self::assertEquals($title, $testee->title);
self::assertEquals($description, $testee->description);
}
public function dataForTestCaptureAuthorizedPaymentNoActionableFailures() : array
{
return [
@ -330,4 +269,13 @@ class WcGatewayTest extends TestCase
[State::STATE_ONBOARDED, false]
];
}
public function dataForFundingSource(): array
{
return [
[null, 'PayPal', 'Pay via PayPal.'],
['venmo', 'Venmo', 'Pay via Venmo.'],
['qwerty', 'PayPal', 'Pay via PayPal.'],
];
}
}