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
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,4 +402,12 @@ Compatible from Shopware 6.5.0 up to 6.5.6.1

# 3.2.2

- Fix: OAuth token requests now use the correct storefront base URL including language prefix (e.g. /en) when using shop.com/en-style domains.
- Fix: OAuth token requests now use the correct storefront base URL including language prefix (e.g. /en) when using shop.com/en-style domains.

# 3.2.3

- Fix: Session/token loss on payment cancel for multiple storefronts with different domains. Cancel URL now uses the order's sales channel domain (same approach as push URL).
- Fix: SalesChannelContextServiceDecorator now uses context token from URL on payment return routes (buckaroo/cancel, checkout/finish, /payment/) to restore session when cookies are not sent.
- Fix: PaymentContextRestoreSubscriber runs earlier (priority 5) to restore context before Shopware resolves the sales channel.
- Fix: PaymentReturnContextSubscriber now appends context token to all storefront redirects (checkout, account), not just checkout/finish.
- Added: PaymentContextCookieSubscriber to explicitly set sw-context-token cookie when restored from URL, enabling use of cookie_samesite: lax without requiring null.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "buckaroo/shopware6",
"description": "Buckaroo payment provider plugin for Shopware 6",
"type": "shopware-platform-plugin",
"version": "3.2.2",
"version": "3.2.3",
"license": "proprietary",
"minimum-stability": "stable",
"require": {
Expand Down
4 changes: 4 additions & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@
<tag name="kernel.event_subscriber"/>
</service>

<service id="Buckaroo\Shopware6\Subscribers\PaymentContextCookieSubscriber">
<tag name="kernel.event_subscriber"/>
</service>

<service id="Buckaroo\Shopware6\Events\OrderStateChangeEvent">
<argument type="service" id="Buckaroo\Shopware6\Service\TransactionService"/>
<argument type="service" id="Buckaroo\Shopware6\Service\InvoiceService"/>
Expand Down
60 changes: 60 additions & 0 deletions src/Subscribers/PaymentContextCookieSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace Buckaroo\Shopware6\Subscribers;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
* Sets the sw-context-token cookie when we restored it from the URL (payment return).
* With SameSite=lax, the session cookie may not be sent on cross-site redirect from Buckaroo.
* By explicitly setting this cookie in the response, the next request (redirect to cart)
* will have it, allowing context restoration without cookie_samesite: null.
*/
class PaymentContextCookieSubscriber implements EventSubscriberInterface
{
private const CONTEXT_TOKEN_LIFETIME_DAYS = 1;

public static function getSubscribedEvents(): array
{
return [
KernelEvents::RESPONSE => ['onKernelResponse', -5],
];
}

public function onKernelResponse(ResponseEvent $event): void
{
$request = $event->getRequest();
$contextToken = $request->attributes->get('sw-context-token');

if (!is_string($contextToken) || $contextToken === '') {
return;
}

// Only set cookie when we restored from URL (token was in query, not cookie)
$tokenFromUrl = $request->query->has('sw-context-token')
|| $request->query->has('add_sw-context-token')
|| $request->request->has('sw-context-token')
|| $request->request->has('add_sw-context-token');
if (!$tokenFromUrl) {
return;
}

$response = $event->getResponse();
$expire = new \DateTimeImmutable('+' . self::CONTEXT_TOKEN_LIFETIME_DAYS . ' days');

$cookie = Cookie::create('sw-context-token')
->withValue($contextToken)
->withExpires($expire)
->withPath('/')
->withSecure($request->isSecure())
->withHttpOnly(false)
->withSameSite(Cookie::SAMESITE_LAX);

$response->headers->setCookie($cookie);
}
}
2 changes: 1 addition & 1 deletion src/Subscribers/PaymentContextRestoreSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PaymentContextRestoreSubscriber implements EventSubscriberInterface
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest', 50],
KernelEvents::REQUEST => ['onKernelRequest', 5],
];
}

Expand Down
Loading