Is Sylius PayumBundle handling payment details incorrectly?

467 Views Asked by At

I am testing Bitbag/PayUPlugin and I was stopped by gateway API with error "Required data missing".

After some debugging, I realised that Sylius Payment entity, specifically "details" property, is not fulfilled with data.

After change condition on line 53:

https://github.com/Sylius/Sylius/blob/4e06a4dfb8dc56731470016bb97165f3025947b7/src/Sylius/Bundle/PayumBundle/Action/CapturePaymentAction.php#L53

to

if ($status->isNew() || $status->isUnknown()) {

payment gateway seems to work correctly.

Is it a bug or am I doing something wrong ?

Sylius/Sylius v1.4.6 Bitbag/PayUPlugin v1.8.0

2

There are 2 best solutions below

2
Dr.X On BEST ANSWER

Unlikely there is an error in PayumBundle/CapturePaymentAction (because more people used PayumBundle than PayUPlugin, so probability of bug is less), conceptually payment object status at the beginning should be "new" instead of "unknown", so the condition should work.

So you should find out https://github.com/BitBagCommerce/SyliusPayUPlugin/blob/master/src/Action/StatusAction.php#L58 class, why it doesn't reach markNew() line.

0
Mike Doe On

I guess the BitBagCommerce/SyliusPayUPlugin is dead as this issue hasn't been addressed yet, since July.

In order to fix this I had to decorate the StatusAction class:

<?php

declare(strict_types=1);

namespace App\Payment\PayU;

use BitBag\SyliusPayUPlugin\Action\StatusAction;
use BitBag\SyliusPayUPlugin\Bridge\OpenPayUBridgeInterface;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\Request\GetStatusInterface;

final class StatusActionDecorator implements ActionInterface
{
    private $action;

    public function __construct(StatusAction $action)
    {
        $this->action = $action;
    }

    public function setApi($api): void
    {
        $this->action->setApi($api);
    }

    public function execute($request): void
    {
        /** @var $request GetStatusInterface */
        RequestNotSupportedException::assertSupports($this, $request);

        $model = ArrayObject::ensureArrayObject($request->getModel());
        $status = $model['statusPayU'] ?? null;

        if (empty($status) || OpenPayUBridgeInterface::NEW_API_STATUS === $status) {
            $request->markNew();

            return;
        }

        if (OpenPayUBridgeInterface::PENDING_API_STATUS === $status) {
            $request->markPending();

            return;
        }

        if (OpenPayUBridgeInterface::CANCELED_API_STATUS === $status) {
            $request->markCanceled();

            return;
        }

        if (OpenPayUBridgeInterface::WAITING_FOR_CONFIRMATION_PAYMENT_STATUS === $status) {
            $request->markSuspended();

            return;
        }

        if (OpenPayUBridgeInterface::COMPLETED_API_STATUS === $status) {
            $request->markCaptured();

            return;
        }

        $request->markUnknown();
    }

    public function supports($request): bool
    {
        return $this->action->supports($request);
    }
}

then in the services.yaml:

App\Payment\PayU\StatusActionDecorator:
    decorates: bitbag.payu_plugin.action.status
    arguments: ['@App\Payment\PayU\StatusActionDecorator.inner']