Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Migrations/Migration20250625103600.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Plugin\ws5_mollie\Migrations;

use JTL\Plugin\Migration;
use JTL\Update\IMigration;

class Migration20250625103600 extends Migration implements IMigration
{
/**
* @inheritDoc
*/
public function up()
{
$this->execute('ALTER TABLE xplugin_ws5_mollie_queue MODIFY COLUMN cType VARCHAR(128);');
}

public function down()
{
// No need to change since 'xplugin_ws5_mollie_orders' is removed in Migration where it is created, and we don't support downgrading of Plugins
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions adminmenu/react-plugin-backend/build/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<!doctype html>
<html lang="en">
<head>
<script type="module" crossorigin src="/assets/index-Drj1xyRg.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BPGDPV5O.css">
<script type="module" crossorigin src="/assets/index-DipnXkst.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-_l2XLrC5.css">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
2 changes: 1 addition & 1 deletion info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ShopVersion>5.3.0</ShopVersion>
<PluginID>ws5_mollie</PluginID>
<CreateDate>2023-02-13</CreateDate>
<Version>2.0.1</Version>
<Version>2.0.4</Version>
<ExsID>689388c6-9f04-4648-b516-e67d96b0dc1d</ExsID>
<Install>
<FlushTags>
Expand Down
34 changes: 33 additions & 1 deletion lib/Checkout/PaymentCheckout.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ public function loadRequest(array &$options = []): static
$this->$key = $value;
}

// captureMode manual is required for riverty and optional but requested by mollie for the others: https://docs.mollie.com/docs/place-a-hold-for-a-payment
if (in_array($this->method, [PaymentMethod::KLARNA_ONE, PaymentMethod::KLARNA_SLICE_IT, PaymentMethod::KLARNA_PAY_LATER, PaymentMethod::KLARNA_PAY_NOW, PaymentMethod::BILLIE, PaymentMethod::RIVERTY])) {
// Set CaptureMode to "manual" for Riverty according to Mollie Api Docs
$this->captureMode = 'manual';
Expand Down Expand Up @@ -289,9 +290,36 @@ public function capture(): string
}
}

/**
* @return string
* @throws Exception
*/
public function releaseAuthorization(): string
{
if (!is_null($this->getMollie())) {
if ($this->getMollie()->isAuthorized()) {
$this->getAPI()->getClient()->payments->releaseAuthorization($this->getMollie()->id);
$status = $this->getMollie(true)->status;
if ($status === PaymentStatus::STATUS_CANCELED) {
PluginHelper::getDB()->executeQueryPrepared('UPDATE tbestellung SET cStatus = -1 WHERE kBestellung = :kBestellung',
[
':kBestellung' => $this->getBestellung()->kBestellung
], 10);

}

/**
return 'Released Payment authorization.';
}

return 'Payment status invalid for releasing authorization: ' . $this->getMollie()->id;
} else {
throw new Exception('Mollie Payment zur Bestellung (' . $this->getBestellung()->cBestellNr . ') konnte nicht geladen werden.');
}

throw new RuntimeException('Bestellung konnte nicht storniert werden: ' . $this->getBestellung()->cBestellNr);
}

/**
* @throws Exception
* @return null|stdClass
*/
Expand Down Expand Up @@ -325,6 +353,10 @@ public function cancelOrRefund(): string
$res = $this->getAPI()->getClient()->payments->cancel($this->getMollie()->id);

return 'Payment cancelled, Status: ' . $res->status;
} elseif ($this->getMollie()->isAuthorized() && $this->getMollie()->captureMode === "manual") {
$this->getAPI()->getClient()->payments->releaseAuthorization($this->getMollie()->id);
$status = $this->getMollie(true)->status;
return 'Payment cancelled, Status: ' . $status;
}
$res = $this->getAPI()->getClient()->payments->refund($this->getMollie(), ['amount' => $this->getMollie()->amount]);

Expand Down
111 changes: 79 additions & 32 deletions lib/Controller/MollieController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Plugin\ws5_mollie\lib\Controller;

use Exception;
use JTL\Catalog\Currency;
use JTL\DB\ReturnType;
use JTL\Plugin\Helper;
use JTL\Plugin\Payment\LegacyMethod;
Expand Down Expand Up @@ -45,44 +46,79 @@ public static function methods(stdClass $data): AbstractResult
}
$api = new MollieAPI($test);

$_methods = $api->getClient()->methods->allAvailable([/*'includeWallets' => 'applepay', 'resource' => 'orders'*/]);
$methods = [];
$oPlugin = self::Plugin('ws5_mollie');

foreach ($_methods as $method) {
if (in_array($method->id, ['voucher', PaymentMethod::DIRECTDEBIT, PaymentMethod::GIFTCARD], true)) {
continue;
}
$id = 'kPlugin_' . Helper::getIDByPluginID('ws5_mollie') . '_' . $method->id;
$oZahlungsart = PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM tzahlungsart WHERE cModulId = :cModulID;', [
':cModulID' => $id
], 1);

// If Mollie has new payment method that we don't support currently
if (!$oZahlungsart) {
continue;
$_methods_arr = [];
// Get methods for default currency EUR
$_methods = $api->getClient()->methods->allActive(['includeWallets' => 'applepay']);
$_methods_arr['EUR'] = $_methods;

// Get methods for all other active currencies
$currencies = Currency::loadAll();
if (is_array($currencies) && count($currencies) > 0) {
foreach ($currencies as $currency) {
if ($currency->getCode() !== 'EUR') {
$_methods = $api->getClient()->methods->allActive(
[
'includeWallets' => 'applepay',
'amount' => (object)[
'value' => '10.00',
'currency' => $currency->getCode()
]
]
);
if ($_methods->count() > 0) {
$_methods_arr[$currency->getCode()] = $_methods;
}
}
}
}

$oPaymentMethod = LegacyMethod::create($oZahlungsart->cModulId);
$methods = [];
$oPlugin = self::Plugin('ws5_mollie');

$methods[$method->id] = (object)[
'log' => PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM tzahlungslog WHERE cModulId = :cModulId AND dDatum < DATE_SUB(NOW(), INTERVAL 30 DAY)', [':cModulId' => $oZahlungsart->cModulId], ReturnType::AFFECTED_ROWS),
'linkToSettingsPage' => Shop::Container()->getLinkService()->getStaticRoute('/admin/zahlungsarten.php') . "?kZahlungsart=$oZahlungsart->kZahlungsart&token={$_SESSION['jtl_token']}",
'mollie' => $method,
'duringCheckout' => (int)$oZahlungsart->nWaehrendBestellung === 1,
'allowDuringCheckout' => $oPaymentMethod::ALLOW_PAYMENT_BEFORE_ORDER ?? null,
'paymentMethod' => $oZahlungsart,
'linkedShippingMethods' => PluginHelper::getDB()->executeQueryPrepared('SELECT v.* FROM tversandart v
foreach ($_methods_arr as $iso => $_methods) {
foreach ($_methods as $method) {
if (in_array($method->id, ['voucher', PaymentMethod::DIRECTDEBIT, PaymentMethod::GIFTCARD], true)) {
continue;
}

// Merge different currencies: add currency if method already exist and continue with next element
if (array_key_exists($method->id, $methods)) {
$methods[$method->id]->currencies[] = $iso;
continue;
}

$id = 'kPlugin_' . Helper::getIDByPluginID('ws5_mollie') . '_' . $method->id;
$oZahlungsart = PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM tzahlungsart WHERE cModulId = :cModulID;', [
':cModulID' => $id
], 1);

// If Mollie has new payment method that we don't support currently
if (!$oZahlungsart) {
continue;
}

$oPaymentMethod = LegacyMethod::create($oZahlungsart->cModulId);

$methods[$method->id] = (object)[
'log' => PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM tzahlungslog WHERE cModulId = :cModulId AND dDatum < DATE_SUB(NOW(), INTERVAL 30 DAY)', [':cModulId' => $oZahlungsart->cModulId], ReturnType::AFFECTED_ROWS),
'linkToSettingsPage' => Shop::Container()->getLinkService()->getStaticRoute('/admin/zahlungsarten.php') . "?kZahlungsart=$oZahlungsart->kZahlungsart&token={$_SESSION['jtl_token']}",
'mollie' => $method,
'duringCheckout' => (int)$oZahlungsart->nWaehrendBestellung === 1,
'allowDuringCheckout' => $oPaymentMethod::ALLOW_PAYMENT_BEFORE_ORDER ?? null,
'paymentMethod' => $oZahlungsart,
'linkedShippingMethods' => PluginHelper::getDB()->executeQueryPrepared('SELECT v.* FROM tversandart v
JOIN tversandartzahlungsart vz ON v.kVersandart = vz.kVersandart
JOIN tzahlungsart z ON vz.kZahlungsart = z.kZahlungsart
WHERE z.cModulId = :cModulID', [':cModulID' => $id], 2),
];

if ($api = $oPlugin->getConfig()->getValue($id . '_components')) {
$methods[$method->id]->components = $api;
}
if ($dueDays = $oPlugin->getConfig()->getValue($id . '_dueDays')) {
$methods[$method->id]->dueDays = (int)$dueDays;
'currencies' => [$iso]
];

if ($api = $oPlugin->getConfig()->getValue($id . '_components')) {
$methods[$method->id]->components = $api;
}
if ($dueDays = $oPlugin->getConfig()->getValue($id . '_dueDays')) {
$methods[$method->id]->dueDays = (int)$dueDays;
}
}
}

Expand Down Expand Up @@ -317,4 +353,15 @@ public static function getPayment(stdClass $data)

return new AbstractResult($checkout->getMollie());
}

public static function releaseAuthorization(stdClass $data): AbstractResult
{
if (strpos($data->id, 'tr_') !== 0) {
throw new RuntimeException('Invalid Payment ID!');
}

$checkout = PaymentCheckout::fromID($data->id);

return new AbstractResult($checkout->releaseAuthorization());
}
}
6 changes: 3 additions & 3 deletions lib/Payment/OrderLine.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ protected static function getType($nPosTyp, $positive = true): string
case C_WARENKORBPOS_TYP_ARTIKEL:
case C_WARENKORBPOS_TYP_GRATISGESCHENK:
// TODO: digital / Download Artikel?
return OrderLineType::TYPE_PHYSICAL;
return $positive ? OrderLineType::TYPE_PHYSICAL : OrderLineType::TYPE_DISCOUNT;
case C_WARENKORBPOS_TYP_VERSANDPOS:
return OrderLineType::TYPE_SHIPPING_FEE;
return $positive ? OrderLineType::TYPE_SHIPPING_FEE : OrderLineType::TYPE_DISCOUNT;
case C_WARENKORBPOS_TYP_VERPACKUNG:
case C_WARENKORBPOS_TYP_VERSANDZUSCHLAG:
case C_WARENKORBPOS_TYP_ZAHLUNGSART:
case C_WARENKORBPOS_TYP_VERSAND_ARTIKELABHAENGIG:
case C_WARENKORBPOS_TYP_NACHNAHMEGEBUEHR:
return OrderLineType::TYPE_SURCHARGE;
return $positive ? OrderLineType::TYPE_SURCHARGE : OrderLineType::TYPE_DISCOUNT;
case C_WARENKORBPOS_TYP_GUTSCHEIN:
case C_WARENKORBPOS_TYP_KUPON:
case C_WARENKORBPOS_TYP_NEUKUNDENKUPON:
Expand Down
1 change: 0 additions & 1 deletion lib/PaymentMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ protected static function isMethodPossible($method, string $locale, $billingCoun
'value' => number_format($amount, 2, '.', '')
],
'billingCountry' => $billingCountry,
'resource' => 'orders',
'includeWallets' => 'applepay',
]);
foreach ($active as $a) {
Expand Down