Skip to content
Merged
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
8 changes: 8 additions & 0 deletions CHANGELOG_de-DE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 6.5.7
* Zuverlässigerer Checkout: Der „Bezahlen“-Button wartet jetzt, bis alle erforderlichen Komponenten vollständig geladen sind, wodurch fehlgeschlagene Bestellungen verhindert werden.
* Leistungsverbesserung: Ein redundanter Abruf der Händlerkonfiguration wurde entfernt, wenn die Konfiguration bereits vorhanden ist.
* Bugfix – PayPal Express: Nutzer werden nach der Erstellung der Zahlungsart nun korrekt zum Checkout zurückgeleitet, anstatt eine Fehlerseite zu sehen.
* UI-Fix – Express-Checkout-Buttons: Einheitliche Abstände zwischen den Buttons für Checkout, PayPal Express, Google Pay und Apple Pay auf der Warenkorbseite sowie im Seitenmenü.
* Neu – Transaktionsstatus im Zahlungsverlauf: Eine Status-Spalte wurde im Zahlungsverlauf der Shopware-Bestelldetails (Unzer-Bereich) hinzugefügt und wird mit Webhook-Updates synchron gehalten.
* Bugfix – Express Checkout mit Gutscheinen: Wenn im Warenkorb-Seitenmenü ein Gutschein angewendet und direkt danach Google Pay, Apple Pay oder PayPal Express angeklickt wird, schlägt die Zahlung nicht mehr fehl.

# 6.5.6
* Fix: Fehlende Übersetzungen neuer Zahlungsarten konnten nach einem Update im Frontend zu einer Fehlermeldung führen
* Fix: Dateien veralteter Zahlungsarten wurden nicht korrekt entfernt und konnten in einigen Fällen Probleme verursachen
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG_en-GB.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 6.5.7
* More reliable checkout: The "Pay" button now waits until all required components are fully loaded, preventing failed orders.
* Performance improvement: Eliminated a redundant merchant config fetch when the config is already provided.
* Bugfix – PayPal Express: Users are now correctly returned to checkout after payment type creation instead of seeing an error page.
* UI fix – Express Checkout buttons: Consistent spacing between Checkout, PayPal Express, Google Pay, and Apple Pay buttons on the cart page and side menu.
* New – Transaction status in payment history: Added a Status column to the payment history in Shopware Order Details (Unzer section), kept in sync with webhook updates.
* Bugfix – Express Checkout with vouchers: Applying a voucher in the cart side menu and immediately clicking Google Pay / Apple Pay / PayPal Express no longer causes the payment to fail.

# 6.5.6
* Fix: Missing translation of new payment methods could display an error in Frontend after updating
* Fix: Files from deprecated payment methods was not properly removed and could in some cases create issues
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,3 @@ For any issues or questions please get in touch with our support.
**Twitter**: [@UnzerTech](https://twitter.com/UnzerTech)

**Webpage**: https://unzer.com/

2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "unzerdev/shopware6",
"description": "Unzer payment integration for Shopware 6",
"version": "6.5.6",
"version": "6.5.7",
"type": "shopware-platform-plugin",
"license": "Apache-2.0",
"minimum-stability": "dev",
Expand Down
1 change: 1 addition & 0 deletions src/Components/ConfigReader/ConfigReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class ConfigReader implements ConfigReaderInterface
public const CONFIG_KEY_PRIVATE_KEY = 'privateKey';
public const CONFIG_KEY_TEST_DATA = 'testData';
public const CONFIG_KEY_EXTENDED_LOGGING = 'extendedLogging';
public const CONFIG_KEY_BLOCK_CONFIRM_BUTTON_ON_LOAD = 'blockConfirmButtonOnLoad';

public const CONFIG_KEY_BOOKING_MODE_CARD = 'bookingModeCreditCard';
public const CONFIG_KEY_BOOKING_MODE_PAYPAL = 'bookingModePayPal';
Expand Down
5 changes: 4 additions & 1 deletion src/Components/ExpressCheckout/ExpressCheckoutService.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private function getRegisterDataFromGooglePayData(array $paymentData, SalesChann
{
$data = new DataBag();
$password = Uuid::randomHex();
$name = $paymentData['paymentMethodData']['info']['billingAddress']['name'] ?? '---- ----';
$name = $paymentData['paymentMethodData']['info']['billingAddress']['name'] ?? self::ADDRESS_PART_PLACEHOLDER . ' ' . self::ADDRESS_PART_PLACEHOLDER;
$names = $this->separateName($name);

$shippingAddress = $this->getAddressFromGoogleData($paymentData['shippingAddress'] ?? [], $salesChannelContext->getContext());
Expand Down Expand Up @@ -261,6 +261,9 @@ private function getAddressFromUnzerCustomer(Customer $customer, Context $contex
if (empty($address->getStreet())) {
$address->setStreet(self::ADDRESS_PART_PLACEHOLDER);
}
if (empty($address->getName())) {
$address->setName(self::ADDRESS_PART_PLACEHOLDER . ' ' . self::ADDRESS_PART_PLACEHOLDER);
}

$nameParts = $this->separateName($address->getName());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function pay(
}
}

public static function fetchChannelId(Unzer $client, bool $cached = true): string
public static function fetchChannelId(Unzer $client): string
{
try {
$keyPair = $client->fetchKeyPair(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ protected function hydrateTransactionItem(AbstractTransactionType $item, string
$state = 'success';
if ($item->isError()) {
$state = 'error';
} elseif ($item->isPending()) {
$state = 'pending';
}

return [
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Storefront/ExtensionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private function readConfig(?string $salesChannelId = null): void

private function fetchGooglePayChannelId($salesChannelId = null, int $cacheTtl = 7200): string
{
$cacheKey = 'UnzerGooglePayChannelId_' . ($salesChannelId ?? 'main');
$cacheKey = 'UnzerGooglePayChannelId_' . ($salesChannelId ?? 'main') . '_' . $this->configData->get(ConfigReader::CONFIG_KEY_PUBLIC_KEY);

return $this->cache->get($cacheKey, function (ItemInterface $item) use ($salesChannelId, $cacheTtl) {
$item->expiresAfter($cacheTtl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class UnzerDataPageExtension extends Struct

private bool $showTestData;

private bool $blockButtonOnLoad = true;

private ?array $keyPairConfig = null;

private ?Customer $unzerCustomer;

public function getPublicKey(): string
Expand Down Expand Up @@ -51,6 +55,26 @@ public function setShowTestData(bool $showTestData): void
$this->showTestData = $showTestData;
}

public function getBlockButtonOnLoad(): bool
{
return $this->blockButtonOnLoad;
}

public function setBlockButtonOnLoad(bool $blockButtonOnLoad): void
{
$this->blockButtonOnLoad = $blockButtonOnLoad;
}

public function getKeyPairConfig(): ?array
{
return $this->keyPairConfig;
}

public function setKeyPairConfig(?array $keyPairConfig): void
{
$this->keyPairConfig = $keyPairConfig;
}

public function getUnzerCustomer(): ?Customer
{
return $this->unzerCustomer;
Expand Down
54 changes: 54 additions & 0 deletions src/Components/UnzerUtil/UnzerApiUtil.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php declare(strict_types=1);

namespace UnzerPayment6\Components\UnzerUtil;

use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;

readonly class UnzerApiUtil
{
public function __construct(
private CacheInterface $cache,
) {
}

public function getCachedKeypairConfig(string $publicKey, int $cacheTtl = 7200): ?array
{
$cacheKey = 'UnzerKeypairConfig_' . $publicKey;

return $this->cache->get($cacheKey, function (ItemInterface $item) use ($publicKey, $cacheTtl): ?array {
$item->expiresAfter($cacheTtl);

return $this->getKeypairConfig($publicKey);
});
}

private function getKeypairConfig(string $publicKey): ?array
{
try {
$host = str_starts_with($publicKey, 'p-pub-') ? 'api.unzer.com' : 'sbx-api.unzer.com';

$ch = curl_init('https://' . $host . '/v1/keypair/types');
curl_setopt_array($ch, [
\CURLOPT_RETURNTRANSFER => true,
\CURLOPT_USERPWD => $publicKey . ':',
\CURLOPT_HTTPHEADER => ['Accept: application/json'],
\CURLOPT_TIMEOUT => 5,
]);

$response = curl_exec($ch);
$status = curl_getinfo($ch, \CURLINFO_HTTP_CODE);
curl_close($ch);

if (!\is_string($response) || $status !== 200) {
return null;
}

$decoded = json_decode($response, true);

return \is_array($decoded) ? $decoded : null;
} catch (\Throwable $e) {
return null;
}
}
}
8 changes: 6 additions & 2 deletions src/EventListeners/Checkout/ConfirmPageEventListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use UnzerPayment6\Components\Struct\PageExtension\Checkout\Confirm\PaymentFramePageExtension;
use UnzerPayment6\Components\Struct\PageExtension\Checkout\Confirm\PayPalPageExtension;
use UnzerPayment6\Components\Struct\PageExtension\Checkout\Confirm\UnzerDataPageExtension;
use UnzerPayment6\Components\UnzerUtil\UnzerApiUtil;
use UnzerPayment6\DataAbstractionLayer\Entity\PaymentDevice\UnzerPaymentDeviceEntity;
use UnzerPayment6\DataAbstractionLayer\Repository\PaymentDevice\UnzerPaymentDeviceRepositoryInterface;
use UnzerPayment6\Installer\PaymentInstaller;
Expand All @@ -55,6 +56,7 @@ public function __construct(
private readonly KeyPairConfigReader $keyPairConfigReader,
private readonly ExtensionFactory $extensionFactory,
private readonly CustomerResourceHydratorInterface $customerResourceHydrator,
private readonly UnzerApiUtil $unzerApiUtil,
) {
}

Expand Down Expand Up @@ -126,11 +128,13 @@ private function addUnzerDataExtension(PageLoadedEvent $event): void
$context = $event->getSalesChannelContext()->getContext();

$extension = new UnzerDataPageExtension();
$extension->setPublicKey($this->getPublicKey($event->getSalesChannelContext()));
$publicKey = $this->getPublicKey($event->getSalesChannelContext());
$extension->setPublicKey($publicKey);
$extension->setLocale($this->getLocaleByLanguageId($context->getLanguageId(), $context));
$extension->setShowTestData((bool) $this->configData->get(ConfigReader::CONFIG_KEY_TEST_DATA));
$extension->setBlockButtonOnLoad((bool) $this->configData->get(ConfigReader::CONFIG_KEY_BLOCK_CONFIRM_BUTTON_ON_LOAD));
$extension->setUnzerCustomer($this->getUnzerCustomer($event));

$extension->setKeyPairConfig($this->unzerApiUtil->getCachedKeypairConfig($publicKey));
$event->getPage()->addExtension(UnzerDataPageExtension::EXTENSION_NAME, $extension);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@
use UnzerPayment6\Components\Storefront\ExtensionFactory;
use UnzerPayment6\Components\Struct\PageExtension\Checkout\Confirm\ApplePayV2PageExtension;
use UnzerPayment6\Components\Struct\PageExtension\Checkout\Confirm\GooglePayPageExtension;
use UnzerPayment6\Components\UnzerUtil\UnzerApiUtil;
use UnzerPayment6\Installer\PaymentInstaller;

class ExpressButtonsEventListener implements EventSubscriberInterface
{
public function __construct(
private ConfigReaderInterface $configReader,
private ExtensionFactory $extensionFactory,
private EntityRepository $salesChannelRepository
private EntityRepository $salesChannelRepository,
private UnzerApiUtil $unzerApiUtil
) {
}

Expand All @@ -50,6 +52,7 @@ public function addExpressButtons(PageLoadedEvent $event): void

$event->getPage()->addExtension('UnzerExpressButtons', new ArrayStruct([
'publicKey' => $config->get(ConfigReader::CONFIG_KEY_PUBLIC_KEY),
'keyPairConfig' => $this->unzerApiUtil->getCachedKeypairConfig($config->get(ConfigReader::CONFIG_KEY_PUBLIC_KEY)),
'usePaypal' => $config->get(ConfigReader::CONFIG_KEY_USE_EXPRESS_PAYPAL) && $this->isPaymentMethodActive(PaymentInstaller::PAYMENT_ID_PAYPAL, $event->getSalesChannelContext()),
'useGooglePay' => $config->get(ConfigReader::CONFIG_KEY_USE_EXPRESS_GOOGLE) && $this->isPaymentMethodActive(PaymentInstaller::PAYMENT_ID_GOOGLE_PAY, $event->getSalesChannelContext()),
'useApplePay' => $config->get(ConfigReader::CONFIG_KEY_USE_EXPRESS_APPLEPAY) && $this->isPaymentMethodActive(PaymentInstaller::PAYMENT_ID_APPLE_PAY_V2, $event->getSalesChannelContext()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Component.register('unzer-payment-history', {
type: this.transactionTypeRenderer(transaction.type),
amount: amount,
date: date,
state: transaction.state || '',
resource: transaction,
});
}
Expand Down Expand Up @@ -114,6 +115,13 @@ Component.register('unzer-payment-history', {
),
rawData: true,
},
{
property: 'state',
label: this.$tc(
'unzer-payment.paymentDetails.history.column.state'
),
rawData: true,
},
];
},
},
Expand Down
3 changes: 2 additions & 1 deletion src/Resources/app/administration/src/snippets/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"column": {
"type": "Typ",
"amount": "Betrag",
"date": "Datum"
"date": "Datum",
"state": "Status"
},
"type": {
"authorization": "Reservierung",
Expand Down
3 changes: 2 additions & 1 deletion src/Resources/app/administration/src/snippets/en-GB.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"column": {
"type": "Type",
"amount": "Amount",
"date": "Date"
"date": "Date",
"state": "State"
},
"type": {
"authorization": "Authorization",
Expand Down
Loading
Loading