Skip to content

Payment Integration API

Register a payment method

Any payment method that is enabled for a store in the system configuration will be listed in the payment step.
This only makes sense for payment methods that do not need to collect any information from the customer.
All others will need to provide some form of user interaction beyond simply being selectable.

Layout XML

To display content when the payment method is selected, a block for the payment method needs to be declared as a child of the checkout.payment.methods block in the layout/hyva_checkout_components.xml file.

For example:

<referenceBlock name="checkout.payment.methods">
    <block name="checkout.payment.method.checkmo"
               as="checkmo"
               template="Hyva_Checkout::component/payment/method/checkmo.phtml"/>
</referenceBlock>

The block alias (as="...") has to match the payment method code

The name of the payment block in layout XML and the template name are not required to follow a specific convention, but we suggest you follow the example above.

The order of payment methods is defined by the system configuration "Sort Order" values, not by the order of the child blocks in layout XML.

The template will be shown on the page when the payment method is selected.

In the template, the instance of \Magento\Quote\Api\Data\PaymentMethodInterface for the payment method is available from $block->getData('method').

If the template only needs to display information, then this is all you need.
An example of this kind of simple payment method is the built-in payment method Check / Money Order.
The template can be found at hyva-themes/magento2-hyva-checkout/src/view/frontend/templates/component/payment/method/checkmo.phtml.

Additional display properties

Common frontend display properties such as a payment provider logo or a subtitle can be added to payment methods as metadata.
Metadata allows payment methods to be expanded with frontend features without the need to modify the Magento payment method object.

Metadata is added to a payment method by specifying block arguments for the method in layout XML.

Currently, supported metadata types are icons and subtitles. More may be added in the future.

Metadata is a specific feature of Hyva Checkout that is currently limited to payment methods, but will soon be implemented for shipping methods as well.

Payment Method Icon

To display an icon for a specific payment method, an argument with the name icon and the type array has to be added to the metadata array argument. The icon path is then specified in an svg child array item.
Icons can be loaded from a Hyvä icon pack extension, or they can be svg files that are added in the payment integration modules view/frontend/web/svg folder.

Additional attributes can be specified if needed.

For example:

<referenceBlock name="checkout.payment.methods">
    <block name="checkout.payment.method.checkmo"
           as="checkmo"
           template="Hyva_Checkout::component/payment/method/checkmo.phtml"
    >
        <arguments>
            <argument name="metadata" xsi:type="array">
                <item name="icon" xsi:type="array">
                    <item name="svg" xsi:type="string">payment-icons/light/paypal</item>
                    <!-- optional attributes, specify as needed -->
                    <item name="attributes" xsi:type="array">
                        <item name="fill" xsi:type="string">none</item>
                    </item>
                </item>
            </argument>
        </arguments>
    </block>
</referenceBlock>

Payment Subtitle

A payment method may display a subtitle below the method title.

This can be accomplished by specifying a subtitle item on the block metadata array. For example:

<referenceBlock name="checkout.payment.methods">
    <referenceBlock name="checkout.payment.method.checkmo">
        <arguments>
            <argument name="metadata" xsi:type="array">
                <item name="subtitle" xsi:type="string">
                    Visa, Mastercard &amp; More
                </item>
            </argument>
        </arguments>
    </block>
</referenceBlock>

If the subtitle value refers to a Magento system configuration setting, it will be displayed as the subtitle.

For example:

<argument name="metadata" xsi:type="array">
    <!-- Specifying a configuration path to the subtitle -->
    <item name="subtitle" xsi:type="string">payment/my-psp/my-awesome-subtitle</item>
</argument>

Payment integration API

Without further customization, all this will do is ensure the method code will be set on the quote payment instance, and the \Hyva\Checkout\Magewire\Main::placeOrder method is called when the Place Order button is clicked.

The main purpose of a Magewire payment component is to gather the required payment information from the customer and pass them to the selected payment method on the quote item.
Sensitive payment information is not collected directly, but rather with the help of a Payment Service Provider.

Usually, a payment method template will either render an iframe showing a form provided by the PSP, or it will show a button that will take the customer to the payment provider's website.

After a customer completes the necessary steps on the PSP website, the payment method template might change and render a confirmation message instead of the form or button.

If the Magewire payment component implements the \Hyva\Checkout\Model\Magewire\Component\EvaluationInterface it should return an Evaluation\Blocking instance if the customer has not yet completed the process with the PSP.
Otherwise, if the visitor has provided all information to the PSP, it should return an Evaluation\Success instance.

public function evaluateCompletion(EvaluationResultFactory $factory): EvaluationResultInterface
{
    // If this payment method is selected, only return a Success if all required data is present
    return $this->isRequiredDataPresent()
        ? $factory->createSuccess()
        : $factory->createBlocking();
}

private function isRequiredDataPresent(): bool {...}
A payment components evaluateCompletion method will only be called when that payment method is selected by the customer.

This ensures the "Place Order" or "Proceed to next step" button is disabled until a payment method has all the information it requires.

Frontend payment phases

The following examples describe the payment process from a customers point of view and how it is enabled by the returned Evaluation Result types.

Example: Redirect to PSP during payment method integration

Step Customer action State "Proceed" or "Place Order" button Evaluation result
1 Visits payment step. No payment method selected. Clicking the button shows a "Please select a payment method" error message. -
2 Selects payment method. Payment method displays button(s) to redirect to PSP website. Disabled Blocking
3 Clicks PSP button. Is transferred to the PSP website. - -
4 Provides payment data and submits form on PSP website. When complete the PSP transfers the payment result token to Magento. - -
5 Is redirected back to payment step of Hyvä Checkout. PSP buttons are replaced with "Payment Authorized" message. Clicking the button takes the customer to the next checkout step or starts order placement. Success

Example: PHP iframe method integration

Step Customer action State "Proceed" or "Place Order" button Evaluation result
1 Visits payment step. No payment method selected. Clicking the button shows a "Please select a payment method" error message. -
2 Selects payment method. Payment method displays PSP form in iframe. Disabled Blocking
3 Provides payment data. Waits for payment token from PSP. Disabled Blocking
4 Completes PSP form. PSP iframe is replaced with "Payment Authorized" message. Clicking the button takes the customer to the next checkout step or starts order placement. Success

Placing the order

Order placement for a payment method integration is handled by a \Hyva\Checkout\Model\Magewire\Payment\PlaceOrderServiceInterface class.
An abstract implementation \Hyva\Checkout\Model\Magewire\Payment\AbstractPlaceOrderService can be extended, so only the required methods need to be implemented.

The PlaceOrderServiceInterface is not the Magewire payment component - it is a separate class.
According to the Hyvä Checkout conventions, a suitable location for a custom Place Order Service would be the Model/Magewire/Payment directory inside your module.

A default implementation is used automatically if no custom logic is present.
If the standard Magento order placement is sufficient for a payment integration, no custom place order service needs to be built.

Customer Payment Data during Order Placement

Any customer data collected by the Magewire payment component must be made available to the order place service through the Quote or a Session object, because the Magewire component is not available at the time the order placement is processed.

Default order placement

The default implementation DefaultPlaceOrderService is sufficient for all payment methods that only require the core Magento payment method to execute during order placement.

In this case nothing needs to be done - the default place order service for the payment method needs to be created.

Under the hood: order creation

This is the code that is used by the default order placement service:

public function placeOrder(Quote $quote): ?int
{
    $orderId = $this->paymentManagement->savePaymentInformationAndPlaceOrder($quote->getId(), $quote->getPayment());
    return (int) $orderId;
}

Redirecting when an order is placed

Some payment methods require additional logic to be executed when an order is placed, for example, the customer might need to be redirected to the PSP website when the order is placed.
This requires a custom order placement service.

This service class has to be registered for the payment method with the PlaceOrderServiceProvider in the module's etc/frontend/di.xml file:

<type name="Hyva\Checkout\Model\Magewire\Payment\PlaceOrderServiceProvider">
    <arguments>
        <argument name="placeOrderServiceList" xsi:type="array">
            <item name="my-pament-method" xsi:type="object">My\PaymentMethod\Model\Magewire\Payment\PlaceOrderService</item>
        </argument>
    </arguments>
</type>

The item name has to match the payment method code.

A place order service that redirects the customer to the PSP website when the order is placed looks something like this:

<?php

namespace My\PaymentMethod\Model\Magewire\Payment;

use Hyva\Checkout\Model\Magewire\Payment\AbstractPlaceOrderService;

class PlaceOrderService extends AbstractPlaceOrderService
{
    public function canPlaceOrder(): bool
    {
        return false;
    }

    public function getRedirectUrl(Quote $quote, ?int $orderId = null): string
    {
        return 'https://payments.example.com/pay?token=' . $quote->getPayment()->getData('exampletoken');
    }
}

It is also possible to redirect to an "internal" Magento URL by returning the target path only:

    public function getRedirectUrl(Quote $quote, ?int $orderId = null): string
    {
        return '/my-payment/checkout/redirect';
    }

By extending a place order service class from AbstractPlaceOrderService only the required methods need to be overridden.

Exception-handling during order placement

It's essential to handle exceptions when developing a custom place order service.

The process when an exception is raised during order placement on a high level is as follows:

  1. An attempt to place the order is made, but an exception is thrown by the order place service.
  2. The Exception is caught.
  3. The JavaScript events order:place:error and order:place:{method_code}_error are queued to be dispatched when the request completes.
    The event details include a property text containing the exception message and a property method with payment method code.
  4. The Place Order Service method handleException is called, which by default re-throws the exception.
  5. The Exception thrown during handleException is caught.
  6. The exception-handling code logs the exception and queues a flash message to be shown in the browser when the request is completed.

Controlling the flash message text

If the exception is a Magento\Framework\Exception\LocalizedException, the text will override the default flash message displayed to the customer.

Handling exceptions with the default Place Order Service

If you don't use a custom place order service for your payment method, but have implemented frontend code, you can listen for either the order:place:error or the order:place:{method_code}_error events to handle payment specific requirements.

For Example:

<div x-data="{ show: false }" @order:place:custom-method-code_error.window="show = true">
    <p x-show="show" class="text-red-600"><?=
     __('We are sorry, something went wrong while trying to process your order.')
    ?></p>
</div>

Handling exceptions with a custom Place Order Service

If you implement a custom place order service, you can use your own handleException logic.
You can choose between two approaches: either throw another exception to leverage the default exception-handling mechanism, or implement your own custom exception-handling logic.

Example of executing custom logic while using the default exception reporting logic:

public function handleException(Exception $exception, Component $component, Quote $quote): void
{
    $methodCode = $quote->getPayment()->getMethod();

    if ($methodCode === 'custom-method-code') {
        $externalPaymentPortal->prepareApiCall('TOKEN-123')->report(
            $exception->getMessage(),
            'CLIENT-123',
            ['id' => $quote->getId(), 'method' => $methodCode]
        );
    }

    throw $exception;
}