Skip to content

Commit

Permalink
Merge branch 'feature/PIWOO-229' into release/7.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
inpsyde-maticluznar committed Oct 24, 2023
2 parents 207c5f6 + 5732e5c commit ad40c09
Show file tree
Hide file tree
Showing 19 changed files with 667 additions and 13 deletions.
30 changes: 30 additions & 0 deletions inc/settings/mollie_advanced_settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,36 @@ class="mollie-settings-advanced-payment-desc-label button button-secondary butto
__('Clear now', 'mollie-payments-for-woocommerce')
) . '</a>)',
],
[
'id' => $pluginName . '_place_payment_onhold',
'title' => __('Placing payments on Hold', 'mollie-payments-for-woocommerce'),
'type' => 'select',
'desc_tip' => true,
'options' => [
'immediate_capture' => __('Capture payments immediately', 'mollie-payments-for-woocommerce'),
'later_capture' => __('Authorize payments for a later capture', 'mollie-payments-for-woocommerce'),
],
'default' => 'immediate_capture',
'desc' => sprintf(
__(
'Authorized payment can be captured or voided by changing the order status instead of doing it manually.',
'mollie-payments-for-woocommerce'
)
),
],
[
'id' => $pluginName . '_capture_or_void',
'title' => __(
'Capture or void on status change',
'mollie-payments-for-woocommerce'
),
'type' => 'checkbox',
'default' => 'no',
'desc' => __(
'Capture authorized payments automatically when setting the order status to Processing or Completed. Void the payment by setting the order status Canceled.',
'mollie-payments-for-woocommerce'
),
],
[
'id' => $pluginName . '_sectionend',
'type' => 'sectionend',
Expand Down
2 changes: 2 additions & 0 deletions mollie-payments-for-woocommerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

namespace Mollie\WooCommerce;

use Mollie\WooCommerce\MerchantCapture\MerchantCaptureModule;
use Mollie\WooCommerce\Vendor\Inpsyde\Modularity\Package;
use Mollie\WooCommerce\Vendor\Inpsyde\Modularity\Properties\PluginProperties;
use Mollie\WooCommerce\Activation\ActivationModule;
Expand Down Expand Up @@ -161,6 +162,7 @@ function initialize()
new GatewayModule(),
new VoucherModule(),
new PaymentModule(),
new MerchantCaptureModule(),
new UninstallModule(),
];
$modules = apply_filters('mollie_wc_plugin_modules', $modules);
Expand Down
54 changes: 45 additions & 9 deletions resources/js/advancedSettings.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
(
function ({_, jQuery }) {
function ({_, jQuery}) {

function mollie_settings__insertTextAtCursor(target, text, dontIgnoreSelection) {
if (target.setRangeText) {
if ( !dontIgnoreSelection ) {
if (!dontIgnoreSelection) {
// insert at end
target.setRangeText(text, target.value.length, target.value.length, "end");
} else {
Expand All @@ -16,13 +16,14 @@
}
target.focus();
}
jQuery(document).ready(function($) {

jQuery(document).ready(function ($) {
$(".mollie-settings-advanced-payment-desc-label")
.data("ignore-click", "false")
.on("mousedown", function(e) {
.on("mousedown", function (e) {
const input = document.getElementById("mollie-payments-for-woocommerce_api_payment_description");
if ( document.activeElement && input === document.activeElement ) {
$(this).on("mouseup.molliesettings", function(e) {
if (document.activeElement && input === document.activeElement) {
$(this).on("mouseup.molliesettings", function (e) {
$(this).data("ignore-click", "true");
$(this).off(".molliesettings");
const tag = $(this).data("tag");
Expand All @@ -31,15 +32,15 @@
});
}
let $this = $(this);
$(window).on("mouseup.molliesettings drag.molliesettings blur.molliesettings", function(e) {
$(window).on("mouseup.molliesettings drag.molliesettings blur.molliesettings", function (e) {
$this.off(".molliesettings");
$(window).off(".molliesettings");
});
})
.on("click", function(e) {
.on("click", function (e) {
e.preventDefault();
e.stopImmediatePropagation();
if ( $(this).data("ignore-click") === "false" ) {
if ($(this).data("ignore-click") === "false") {
const tag = $(this).data("tag");
const input = document.getElementById("mollie-payments-for-woocommerce_api_payment_description");
mollie_settings__insertTextAtCursor(input, tag, false);
Expand All @@ -48,9 +49,44 @@
}
})
;
registerManualCaptureFields();
});
}
)
(
window
)

function registerManualCaptureFields() {
const onHoldSelect = jQuery('[name="mollie-payments-for-woocommerce_place_payment_onhold"]');
if (onHoldSelect.length === 0) {
return;
}
toggleManualCaptureFields(onHoldSelect);
onHoldSelect.on('change', function(){
toggleManualCaptureFields(onHoldSelect);
})
}

function toggleManualCaptureFields(onHoldSelect) {
const currentValue = onHoldSelect.find('option:selected');
if (currentValue.length === 0) {
return;
}

const captureStatusChangeField = jQuery('[name="mollie-payments-for-woocommerce_capture_or_void"]');
if (captureStatusChangeField.length === 0) {
return;
}

const captureStatusChangeFieldParent = captureStatusChangeField.closest('tr');
if (captureStatusChangeFieldParent.length === 0) {
return;
}

if (currentValue.val() === 'later_capture') {
captureStatusChangeFieldParent.show();
} else {
captureStatusChangeFieldParent.hide();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Mollie\WooCommerce\MerchantCapture\Capture\Action;

use Mollie\WooCommerce\SDK\Api;
use Mollie\WooCommerce\Settings\Settings;
use Psr\Log\LoggerInterface;

class AbstractPaymentCaptureAction
{
protected $apiHelper;
protected $settingsHelper;
protected $apiKey;
protected $order;
protected $logger;
protected $pluginId;

public function __construct(
int $orderId,
Api $apiHelper,
Settings $settingsHelper,
LoggerInterface $logger,
string $pluginId
) {

$this->apiHelper = $apiHelper;
$this->settingsHelper = $settingsHelper;
$this->order = wc_get_order($orderId);
$this->logger = $logger;
$this->pluginId = $pluginId;
$this->setApiKey();
}

protected function setApiKey()
{
$this->apiKey = $this->settingsHelper->getApiKey();
}
}
65 changes: 65 additions & 0 deletions src/MerchantCapture/Capture/Action/CapturePayment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace Mollie\WooCommerce\MerchantCapture\Capture\Action;

use Mollie\Api\Exceptions\ApiException;
use Mollie\WooCommerce\MerchantCapture\ManualCaptureStatus;
use Mollie\WooCommerce\MerchantCapture\MerchantCaptureModule;

class CapturePayment extends AbstractPaymentCaptureAction
{
public function __invoke()
{
try {
$paymentId = $this->order->get_meta('_mollie_payment_id');

if (!$paymentId) {
$this->logger->error('Missing Mollie payment ID in order ' . $this->order->get_id());
$this->order->add_order_note(
__(
'The Mollie payment ID is missing, and we are unable to capture the funds.',
'mollie-payments-for-woocommerce'
)
);
return;
}

$paymentCapturesApi = $this->apiHelper->getApiClient($this->apiKey)->paymentCaptures;
$captureData = [
'amount' => [
'currency' => $this->order->get_currency(),
'value' => $this->order->get_total(),
],
];
$this->logger->debug(
'SEND AN ORDER CAPTURE, orderId: ' . $this->order->get_id(
) . ' transactionId: ' . $paymentId . 'Capture data: ' . json_encode($captureData)
);
$paymentCapturesApi->createForId($paymentId, $captureData);
$this->order->update_meta_data(
MerchantCaptureModule::ORDER_PAYMENT_STATUS_META_KEY,
ManualCaptureStatus::STATUS_WAITING
);
$this->order->add_order_note(
sprintf(
__(
'The payment capture of %s has been sent successfully, and we are currently awaiting confirmation.',
'mollie-payments-for-woocommerce'
),
wc_price($this->order->get_total())
)
);
$this->order->save();
} catch (ApiException $exception) {
$this->logger->error($exception->getMessage());
$this->order->add_order_note(
__(
'Payment Capture Failed. We encountered an issue while processing the payment capture.',
'mollie-payments-for-woocommerce'
)
);
}
}
}
34 changes: 34 additions & 0 deletions src/MerchantCapture/Capture/Action/VoidPayment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Mollie\WooCommerce\MerchantCapture\Capture\Action;

use Mollie\Api\Exceptions\ApiException;
use Mollie\WooCommerce\MerchantCapture\ManualCaptureStatus;
use Mollie\WooCommerce\MerchantCapture\MerchantCaptureModule;

class VoidPayment extends AbstractPaymentCaptureAction
{
public function __invoke()
{
$paymentId = $this->order->get_meta('_mollie_payment_id');
$paymentCapturesApi = $this->apiHelper->getApiClient($this->apiKey)->payments;
try {
$paymentCapturesApi->cancel($paymentId);
$this->order->update_meta_data(
MerchantCaptureModule::ORDER_PAYMENT_STATUS_META_KEY,
ManualCaptureStatus::STATUS_VOIDED
);
$this->order->save();
} catch (ApiException $exception) {
$this->logger->error($exception->getMessage());
$this->order->add_order_note(
__(
'Payment Void Failed. We encountered an issue while canceling the pre-authorized payment.',
'mollie-payments-for-woocommerce'
)
);
}
}
}
51 changes: 51 additions & 0 deletions src/MerchantCapture/Capture/Type/ManualCapture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Mollie\WooCommerce\MerchantCapture\Capture\Type;

use Mollie\WooCommerce\MerchantCapture\Capture\Action\CapturePayment;
use Mollie\WooCommerce\Vendor\Psr\Container\ContainerInterface;

class ManualCapture
{
/**
* @var ContainerInterface $container
*/
protected $container;
protected const MOLLIE_MANUAL_CAPTURE_ACTION = 'mollie_capture_authorized_payment';

public function __construct(ContainerInterface $container)
{
$this->container = $container;
add_action('woocommerce_order_actions', [$this, 'enableOrderCaptureButton'], 10, 2);
add_action('woocommerce_order_action_' . self::MOLLIE_MANUAL_CAPTURE_ACTION, [$this, 'manualCapture']);
add_filter('woocommerce_mollie_wc_gateway_creditcard_args', [$this, 'sendManualCaptureMode']);
}

public function enableOrderCaptureButton(array $actions, \WC_Order $order): array
{
if (!$this->container->get('merchant.manual_capture.can_capture_the_order')($order)) {
return $actions;
}
$actions[self::MOLLIE_MANUAL_CAPTURE_ACTION] = __(
'Capture authorized Mollie payment',
'mollie-payments-for-woocommerce'
);
return $actions;
}

public function sendManualCaptureMode(array $paymentData): array
{
if ($this->container->get('merchant.manual_capture.enabled')) {
$paymentData['captureMode'] = 'manual';
}
return $paymentData;
}

public function manualCapture(\WC_Order $order)
{

($this->container->get(CapturePayment::class))($order->get_id());
}
}
55 changes: 55 additions & 0 deletions src/MerchantCapture/Capture/Type/StateChangeCapture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace Mollie\WooCommerce\MerchantCapture\Capture\Type;

use Mollie\WooCommerce\MerchantCapture\Capture\Action\CapturePayment;
use Mollie\WooCommerce\MerchantCapture\Capture\Action\VoidPayment;
use Mollie\WooCommerce\Shared\SharedDataDictionary;
use Mollie\WooCommerce\Vendor\Psr\Container\ContainerInterface;

class StateChangeCapture
{
/**
* @var ContainerInterface $container
*/
protected $container;

public function __construct(ContainerInterface $container)
{
$this->container = $container;
add_action('woocommerce_order_status_changed', [$this, "orderStatusChange"], 10, 3);
}

public function orderStatusChange(int $orderId, string $oldStatus, string $newStatus)
{
$stateChangeCaptureEnabled = $this->container->get('merchant.manual_capture.on_status_change_enabled');
if (empty($stateChangeCaptureEnabled) || $stateChangeCaptureEnabled === 'no') {
return;
}

if (!in_array($oldStatus, $this->container->get('merchant.manual_capture.void_statuses'))) {
return;
}

if (in_array($newStatus, [SharedDataDictionary::STATUS_PROCESSING, SharedDataDictionary::STATUS_COMPLETED])) {
$this->capturePayment($orderId);
return;
}

if ($newStatus === SharedDataDictionary::STATUS_CANCELLED) {
$this->voidPayment($orderId);
}
}

protected function capturePayment(int $orderId)
{
($this->container->get(CapturePayment::class))($orderId);
}

protected function voidPayment(int $orderId)
{
($this->container->get(VoidPayment::class))($orderId);
}
}
Loading

0 comments on commit ad40c09

Please sign in to comment.