|
38 | 38 | use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderCaptureRequest; |
39 | 39 | use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderRequest; |
40 | 40 | use Psr\Log\LoggerInterface; |
| 41 | +use OxidSolutionCatalysts\PayPal\Exception\NotFound; |
41 | 42 | use OxidSolutionCatalysts\PayPal\Event\PayPalOrderCompletedEvent; |
42 | 43 |
|
43 | 44 | class AjaxPaymentController extends BaseController |
@@ -267,16 +268,32 @@ public function captureOrder(): void |
267 | 268 | } |
268 | 269 | $shopOrderId = $this->orderRepository->fetchCurrentShopOrderId(); |
269 | 270 | $order = $this->orderRepository->fetchCurrentShopOrder(); |
| 271 | + |
| 272 | + // If session-based resolution failed (e.g. sess_challenge was cleared |
| 273 | + // by a concurrent cancel request), fall back to the persisted |
| 274 | + // relationship in oscpaypal_order via the PayPal order ID. |
| 275 | + if (empty($shopOrderId) || !$order->isLoaded()) { |
| 276 | + try { |
| 277 | + $order = $this->orderRepository->getShopOrderByPayPalOrderId($payPalOrderId); |
| 278 | + $shopOrderId = (string)$order->getId(); |
| 279 | + $this->logger->log( |
| 280 | + 'info', |
| 281 | + 'PayPal captureOrder: resolved shop order from DB fallback (sess_challenge was missing)', |
| 282 | + ['payPalOrderId' => $payPalOrderId, 'shopOrderId' => $shopOrderId] |
| 283 | + ); |
| 284 | + } catch (NotFound $e) { |
| 285 | + // Neither session nor DB could resolve the shop order |
| 286 | + } |
| 287 | + } |
| 288 | + |
270 | 289 | $basket = Registry::getSession()->getBasket(); |
271 | 290 | $user = $basket->getUser(); |
272 | 291 |
|
273 | | - // Validate that a valid shop order could be resolved from the session. |
274 | | - // If sess_challenge was cleared (e.g. by a concurrent cancel request), |
275 | | - // we must not proceed with tracking an orphaned PayPal capture. |
276 | | - if (empty($shopOrderId) || !$order->isLoaded()) { |
| 292 | + // Validate that a valid, non-cancelled shop order could be resolved. |
| 293 | + if (empty($shopOrderId) || !$order->isLoaded() || $order->getFieldData('oxstorno') == 1) { |
277 | 294 | $this->logger->log( |
278 | 295 | 'error', |
279 | | - 'PayPal captureOrder: cannot resolve shop order from session (sess_challenge missing or order not loaded)', |
| 296 | + 'PayPal captureOrder: cannot resolve valid shop order (sess_challenge missing, DB fallback failed, or order cancelled)', |
280 | 297 | ['payPalOrderId' => $payPalOrderId, 'shopOrderId' => $shopOrderId] |
281 | 298 | ); |
282 | 299 | $this->outputJson([ |
|
0 commit comments