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 any 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_CheckoutDefault::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 does not have to follow a specific convention technically, 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/checkout-default/src/view/frontend/templates/component/payment/method/checkmo.phtml.

Payment integration PHP API

Magewire components are registered as payment methods with the wire binding wire:payment-method="...".

The wire:payment-method binding has to be on the template root element!

The value of the attribute is the payment method code. For example:

<div class="col-span-6" wire:payment-method="purchaseorder">
    ...template content to show when the payment method is selected...
</div>

Without further customization, all this will do is ensure the method placeOrder() of the Magewire component is called when the Place Order button is clicked.

However, this will only happen when the payment component is on the last step in the checkout.
If there are more steps, the order will be placed by a generic order placement method \Hyva\CheckoutCore\Magewire\Main::placeOrder.

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.
Usually, the payment information is not collected directly, but rather with the help of a Payment Service Provider.

Typically, 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 completed 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\CheckoutCore\Model\Magewire\Component\EvaluationInterface it should only return an Evaluation\Blocking instance if the method is currently selected, but the customer has not yet completed the process with the PSP.
Otherwise, if the payment method is not selected, or if the visitor has provided all information to the PSP, it should always return an Evaluation\Success instance.

public function evaluateCompletion(): EvaluationResultInterface
{
    if ($this->sessionCheckout->getQuote()->getPayment()->getMethod() !== 'method-code') {
        // Allow other payment methods to be selected
        return $this->evaluationResultFactory->createSuccess();
    }

    // If this payment method is selected, only return a Success if all required is present
    return $this->isRequiredDataPresent()
        ? $this->evaluationResultFactory->createSuccess()
        : $this->evaluationResultFactory->createBlocking();
}

private function isRequiredDataPresent(): bool {...}

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. Success
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. None -
4 Provides payment data and submits form on PSP website. When complete the PSP transfers the payment result token to Magento. None -
5 Is redirected back to payment step of Hyvä Checkout. PSP buttons are replaced with "Please proceed to place order" 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. Success
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 Submits PSP form. PSP iframe is replaced with "Please proceed to place order" 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\CheckoutCore\Model\Magewire\Payment\PlaceOrderServiceInterface class.
An abstract implementation \Hyva\CheckoutCore\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, the Model/Magewire/Payment directory inside your module is a suitable place for it.

A default implementation is used automatically if no custom logic is required.

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 that time.

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 default:

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\CheckoutCore\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\CheckoutCore\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';
    }

Work in progress

Missing sections:

  • Payment integration hook methods
  • Payment integration JS API