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
.
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 {...}
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:
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.