Skip to content

Evaluation result types

Hyvä Checkout offers a comprehensive selection of evaluation result types by default, ranging from basic messaging results to more sophisticated combinations. These include the capability to inject executable code directly into the navigation process, enabling specific JavaScript actions when users attempt to navigate forward or place an order.

The API is intentionally crafted to empower developers, providing them with the flexibility to create their own custom evaluation result types to meet unique requirements.

Batch

Available since Hyvä Checkout 1.1.13

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Batch
  • Frontend processor: batch
  • Capabilities: N/A

As the name implies, a batch result is capable of containing multiple results, all of which will be processed on the frontend. There's no restriction on the number of result types a batch can carry. Batches operate akin to arrays and offer various functions to traverse, push, or merge new results into them. Utilizing a batch result is advisable as it facilitates the injection of additional functionality by others if needed.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        $batch = $resultFactory->createBatch(
            [
                $resultFactory->createErrorMessage()
                    ->withMessage('Something went wrong.')
                    ->asWarning(),
                $resultFactory->createEvent()
                    ->withCustomEvent('my-batch-event')
                    ->dispatch()
            ]
        );

        // Example on how to push additional result types.
        if (false === $component->getEvaluationResultBatch()->owns(fn ($value) => $value instanceof Redirect)) {
            $batch->clear()->push($resultFactory->createRedirect('https://hyva.io/hyva-checkout.html')
                ->withNotificationDialog()
                ->withNotificationMessage('You\'re being redirected to the Hyvä Checkout product page.')
                ->withTimeout(2500)
            );
        }

        return $batch;
    }
}

This example begins by creating a batch containing both a warning message and a JavaScript window event, both of which will be immediately dispatched.

Desire seamless access to the result factory without the need for manual injection?

You can achieve this by accessing a batch result. Within the batch result, there's a method named getFactory(), which provides access to the factory instance for creating various other result types.

$batch->push(
    $batch->getFactory()
        ->createErrorMessage()
        ->withMessage('Something went wrong.')
)

Blocking

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Blocking
  • Frontend processor: blocking
  • Capabilities: Details, Blocking, Dispatch

Utilize a blocking result to completely disable all primary navigation buttons, preventing processes such as additional navigation tasks or validations from being triggered. However, be mindful that using this result from the user's perspective can potentially cause confusion. It's imperative to provide clear instructions to end-users, explaining what actions they need to take before they can proceed with navigating forward or placing an order. Additional information should be provided to ensure clarity and guide users effectively.

Use With Caution

Additional care must be taken when choosing to return a Blocking result as there is currently no automated mechanism by which to unblock the checkout - this can only be achieved by satisfying the criteria for the components evaluateCompletion() function to return a Success result or by manually invoking the unblocking via the frontend API.

Consider the example of a payment method which returns a Blocking result until the customer has authorised their payment. Upon selecting that payment method, the checkout becomes blocked. If the customer is unable to authorise their payment for any reason, they are then unable to complete their purchase even if they are to select an alternative payment method due to this Blocking result not being unset.

To simplify your implementation, it is generally advised to avoid returning a Blocking result in favour of an ErrorMessage result instead. The effects of preventing the customer from progressing through the checkout and displaying an informative error message are maintained but without the need to conceive of every scenario where you will have to handle the manual unblocking of the checkout.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        return true ? $resultFactory->createBlocking() : $resultFactory->createSuccess();
    }
}

Custom

Available since Hyvä Checkout 1.1.13

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Custom
  • Frontend processor: N/A
  • Capabilities: Details, Blocking, Dispatch

If you exclusively have a frontend processor, consider utilizing a custom result type. By default, a custom result type encompasses all the necessary capabilities for dispatching, blocking, and adding additional details.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        return $resultFactory->createCustom('foo')
            ->withDetails(['alert' => 'Something went wrong.']);
    }
}
<script>
    // Ensure that the evaluation API is fully initialized.
    window.addEventListener('checkout:init:evaluation', () => {
        // Register evaluation processor "foo".
        hyvaCheckout.evaluation.registerProcessor('foo', (component, el, result) => {
            alert(result.arguments.details.alert);

            return result.result;
        });
    });
</script>

Register custom evaluation processors

To register a custom processor, you can add a .phtml file to the DOM via layout XML. Multiple designated locations are available to ensure the custom processor is positioned correctly depending on the required hyvaCheckout APIs.

The recommended practice is to inject your custom .phtml via layout handle hyva_checkout_index_index with a container preference of hyva.checkout.init-evaluation.after.

Each API has its own after container, ensuring custom code can be injected after its parent API.

For further information, please refer to view/frontend/layout/hyva_checkout_index_index.xml.

ErrorMessage

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\ErrorMessage
  • Frontend processor: message
  • Capabilities: Blocking, Messaging, Dispatch

Utilize an error message either directly or during component validation.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public bool $dispatch = false;
    public bool $successful = true;
    public ?int $duration = null;

    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        $message = $resultFactory->createErrorMessage('Something went wrong');

        if ($this->dispatch) {
            $message->dispatch();
        }
        if ($this->successful) {
            $message->asCustomType('success');
        }
        if ($this->duration) {
            $message->withVisibilityDuration($this->duration);
        }

        return $message;
    }
}

This example initially throws a flash error message with options to be dispatched immediately, served as a success message and/or requiring a certain visibility duration, after which it will automatically be hidden.

Event

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\ErrorMessage
  • Frontend processor: message
  • Extends: ErrorMessageEvent, ErrorEvent, Success
  • Capabilities: Details, Dispatch

In addition to its function as an event shell, the Event result type also extends ErrorMessageEvent and ErrorEvent. The latter two provide specific markup required for error events and message events, enhancing their functionality.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        // Can be caught with window.addEventListener('my-custom-event', event => {})
        return $resultFactory->createEvent()
            ->withCustomEvent('my-custom-event')
            ->dispatch();

        // Dispatch a custom window event with a specific message markup containing the message and its type.
        return $resultFactory->createErrorMessageEvent()
            ->withCustomEvent('my-error-event')
            ->withMessage('Something went wrong')
            ->dispatch();

        // Dispatch a custom window event with a false result and stick it onto the validation API by default.
        return $resultFactory->createErrorEvent()
            ->withCustomEvent('my-custom-event');
    }
}

Executable

Available since Hyvä Checkout 1.1.13

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Executable
  • Frontend processor: executable
  • Capabilities: Dispatch

Utilize an executable, either in combination with the NavigationTask result type or independently, when you need a specific piece of code to be executed on the frontend. An executable can be thought of as a regular method that can receive its own argument parameters, which are set from the backend.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        $executable = $resultFactory->createExecutable('custom-modal')
            ->withParams(['buttons' => ['confirm', 'cancel']]);

        // Dispatch the executable immediately.
        return $executable->withParam('title' => 'My Modal');

        // Attach the executable to the navigation and trigger it only when a customer attempts to navigate.
        return $resultFactory->createNavigationTask('foo', $executable)
    }
}

To utilize an executable, it must be registered with a specific name and can function as either asynchronous or synchronous.

<script>
    // Ensure that the evaluation API is fully initialized.
    window.addEventListener('checkout:init:evaluation', () => {
        // Open a modal after 5 seconds, including fetched data from an external API.
        hyvaCheckout.evaluation.registerExecutable('custom-modal', async (result, el, component) => {
            return new Promise(resolve => setTimeout(() => {
                fetch('https://api.example.extension/random').then(result => {
                    // Custom logic to open a modal goes here.
                })

                resolve()
            }, 5000))
        })
    })
</script>

Available since Hyvä Checkout 1.1.13

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\NavigationTask
  • Frontend processor: navigation_task
  • Capabilities: Dispatch, Stacking

Incorporating a navigation task serves the purpose of delaying specific JavaScript-driven actions until the customer chooses to advance to the subsequent step or place an order. These tasks remain pending until the customer clicks the designated navigation button, upon which they are executed sequentially based on their assigned position (defaulted to 500).

Consider, for instance, address form data that no other component depends on but still requires preservation. This approach negates the need for implementing an auto-save feature, as the navigation mechanism handles data retention when necessary.

A navigation task encompasses any type of evaluation result, which, if dispatchable, will be automatically handled for you.

It also possesses the capability to be assigned after the successful loading of the next step or the completion of the order.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        $task = $resultFactory->createErrorMessage()
            ->withMessage('Welcome to the next step.')
            ->asCustomType('success');

        // "fooCustomNavigationTask" will serve as the identifier for the navigation task on the frontend.
        return $resultFactory->createNavigationTask('fooCustomNavigationTask', $task)->executeAfter();
    }
}

This eventually manifests as an error message, presented as a success-type flash message at the top of the screen. This occurs either after the customer proceeds to the second page or after placing the order, prior to any redirection. For example, you might display a modal through an asynchronous Executable, ensuring navigation waits until the modal is resolved. Since the Redirect result is positioned late in the task stack, it permits other tasks to execute beforehand.

Redirect

Available since Hyvä Checkout 1.1.13

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Redirect
  • Frontend processor: redirect
  • Capabilities: Dispatch, Stacking

A particularly valuable result type for payment vendors is the redirect option, which enables them to seamlessly redirect the customer to their external payment solution either just before or immediately after the order has been placed. This redirect functionality includes a modal that can optionally appear as a notification dialog. Alternatively, developers have the option to present a confirmation dialog to the customer, featuring both cancel and confirm buttons.

These options can be configured within the redirect system settings, allowing system administrators to enforce confirmation dialogs for all redirects, even if developers choose not to attach them initially.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        $task = $resultFactory->createRedirect('https://hyva.io/hyva-checkout.html');

        return $resultFactory->createNavigationTask('foo', $task)->executeAfter();
    }
}

Success

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Success
  • Frontend processor: event
  • Capabilities: Details, Dispatch

Although Success is simply a standard Event result type, it holds significance as it is the primary type used, particularly for clearing a component and marking it as completed. In addition to dispatching a success result for the component, which proves valuable on the frontend, it also returns a true result, indicating the component's completion status. It's important to note that other result types, such as a custom one returning a true result, will also function effectively. However, we provide a standardized type to streamline these common functionalities for your convenience.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public bool $success = true;

    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        if ($this->success) {
            return $resultFactory->createSuccess();
        }

        return $resultFactory->createErrorMessage()
            ->withMessage('Please mark this component as completed.')
            ->asInformally()
            ->dispatch()
    }
}

Validation

Available since Hyvä Checkout 1.1.13

  • Class: \Hyva\Checkout\Model\Magewire\Component\Evaluation\Validation
  • Frontend processor: validation
  • Capabilities: Stacking, Details

The validate result type is tightly integrated with the frontend Validation API, offering developers the flexibility to inject custom validation logic onto primary navigation buttons. This validation occurs after navigation tasks have been successfully fulfilled. Functionally, a validation result behaves similarly to a NavigationTask, with the main distinction being that the registered callback serves as a validator. Additionally, developers have the option to specify another result type, such as ErrorMessage, to handle failure scenarios automatically. This can be achieved using the withFailureResult method.

<?php

class Foo extends \Magewirephp\Magewire\Component implements \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface
{
    public function evaluateCompletion(EvaluationResultFactory $resultFactory): EvaluationResult
    {
        // Reflects one of the tree register validators on the frontend.
        $validator = ['a', 'b', 'c'][random_int(0, 2)];

        return $resultFactory->createValidation($validator)
            ->withFailureResult($resultFactory->createErrorMessage()
                ->withMessage(sprintf('Validator "%s" failed.'))
                ->dispatch()
            );
    }
}

To utilize a validation, it must be registered with a specific name and can function as either asynchronous or synchronous.

<script>
    window.addEventListener('checkout:init:evaluation', () => {
        // Fails validation immediately.
        hyvaCheckout.evaluation.registerValidator('a', (element, component) => {
            throw new Error('Foo')
        })

        // Successful validation after 2.5 seconds.
        hyvaCheckout.evaluation.registerValidator('b', async (element, component) => {
            return new Promise(resolve => setTimeout(() => resolve(true), 2500))
        })

        // Rejects and fails validation after 2.5 seconds.
        hyvaCheckout.evaluation.registerValidator('c', async (element, component) => {
            return new Promise((resolve, reject) => setTimeout(() => reject(), 2500))
        })
    })
</script>

Register custom validator

To register a custom validator, you can add a .phtml file to the DOM via layout XML. Multiple designated locations are available to ensure the custom processor is positioned correctly depending on the required hyvaCheckout APIs.

The recommended practice is to inject your custom .phtml via layout handle hyva_checkout_index_index with a container preference of hyva.checkout.init-evaluation.after.

Each API has its own after container, ensuring custom code can be injected after its parent API.

For further information, please refer to view/frontend/layout/hyva_checkout_index_index.xml.

EvaluationResult (abstract)

Available since Hyvä Checkout 1.1.13

For checkout versions before 1.1.13, every evaluation result type mandates an implementation of Hyva\Checkout\Model\Magewire\Component\EvaluationResultInterface.

However, starting from version 1.1.13, this interface has been deprecated and replaced with \Hyva\Checkout\Model\Magewire\Component\Evaluation\EvaluationResult.

Every core evaluation result type builds upon the EvaluationResult abstraction, ensuring that all necessary requirements are fulfilled. The recommended approach is to extend custom results from this abstraction, adhering to best practices.

<?php

namespace My\Module\Model\Magewire\Component\Evaluation;

class Foo extends \Hyva\Checkout\Model\Magewire\Component\Evaluation\EvaluationResult
{
    public const TYPE = 'foo';

    public function getArguments(Component $component): array
    {
        return [];
    }

    // Alternative for defining a TYPE constant.
    public function getType(): string
    {
        return 'foo';
    }
}