Magento2 headless payments

Historically, Magento2 did not support headless payments. Even though some payment providers are slowly exposing REST or GraphQL APIs from their module, most of them often rely on the CheckoutSession or CustomerSession to persist meaningful information across checkout steps.

Front-Commerce’s Magento module provides a generic way to expose Magento payment modules headlessly and supports the relevant Front-Commerce payment workflows.

Supported Payment platforms

Our Magento2 integration currently provides native adapters for the platforms below, learn how to install each one of them from the related documentation page:

If you want to use a Payment module not yet listed above, please contact us so we can provide information about a potential upcoming native support for it.

Implement a new Magento2 Payment method Adapter

Work In Progress This section is not as detailed as we would love it to be. Please let us know if you need further information before we improve it.

We will explain the mechanisms available to implement your own adapter if supported Magento payment modules do not suit your needs.

Payment Adapters must implement the \FrontCommerce\Integration\Api\HeadlessPayment\Adapter interface no matter the workflows they support.

Front-Commerce module will simulate a Magento action as if the page was loaded in a frontend context. It will:

  1. create a RequestInterface instance
  2. dispatch the request through Magento’s Front Controller
  3. converts the response into a Front-Commerce headless API response

Adapters must implement methods that are called at key times in order to:

  • allow to initialize the request
  • or convert a response depending on the payment module internal implementations

redirectionFromCheckoutRedirectActionResponse

Payment flows: Redirect before order

Converts an internal Magento response to a RedirectionInterface value object.

public function redirectionFromCheckoutRedirectActionResponse(
    Response $response,
    ManagerInterface $messagesManager
): RedirectionInterface;

redirectionFromCheckoutRedirectAfterActionResponse

Payment flows: Redirect after order

Converts an internal Magento response to a RedirectionInterface value object.

public function redirectionFromCheckoutRedirectAfterActionResponse(
    Response $response,
    ManagerInterface $messagesManager
): RedirectionInterface;

prepareAfterCheckoutContext

Payment flows: Redirect after order

Populates session objects with information required by the payment action.

public function prepareAfterCheckoutContext(
    CheckoutSession $checkoutSession,
    CustomerSession $customerSession,
    Order $order
);

checkoutRedirectUrl

Payment flows: Redirect before order, Redirect after order

Should return the url that will be dispatched internally to trigger the redirection to the payment provider in the payment module.

public function checkoutRedirectUrl(
    ConfigProviderInterface $configProvider,
    Payment $payment = null
): string;

changeAfterCheckoutResponseFromResult

Payment flows: Redirect after order

May populate or change the Magento response object while still in the correct store context. It can for instance render blocks or things like that…

public function changeAfterCheckoutResponseFromResult(
    HttpInterface $response,
    BlockFactory $blockFactory,
    ResultInterface $result = null,
    ObjectManagerInterface $objectManager
);

buildReturnFromPlatformProxiedAction

Payment flows: Redirect before order, Redirect after order

This is a factory to build a ProxiedAction matching the next step for the Customer depending on information transmitted by the payment system in the return url the user was redirected to when coming back to the store

public function buildReturnFromPlatformProxiedAction(
    string $actionName,
    array $additionalData,
    $customerId = null
): ProxiedAction;

Note: in case an action is not supported, we recommend to throw an exception so Front-Commerce could gracefully prevent the checkout process by displaying a relevant information to the Customer.

Example: throw new \RuntimeException('Checkout flow not supported');

Register the Payment Adapter

Wether you’ve implemented a new Payment Adapter or are reusing an existing one, adapters have to be registered so Front-Commerce’s module could instantiate it when relevant. Using the di.xml, inject the adapter in the FrontCommerce\Integration\Model\HeadlessPayments\AdapterFactory $adapters constructor param.

Below is an example from Front-Commerce’s core:

<type name="FrontCommerce\Integration\Model\HeadlessPayments\AdapterFactory">
  <arguments>
    <argument name="adapters" xsi:type="array">
      <item name="paypal_express" xsi:type="string">FrontCommerce\Integration\Model\HeadlessPayments\Adapter\PaypalExpress</item>
      <item name="payzen_standard" xsi:type="string">FrontCommerce\Integration\Model\HeadlessPayments\Adapter\PayzenStandard</item>
      <item name="ops_cc" xsi:type="string">FrontCommerce\Integration\Model\HeadlessPayments\Adapter\OpsCc</item>
      <item name="adyen_hpp" xsi:type="string">FrontCommerce\Integration\Model\HeadlessPayments\Adapter\AdyenHpp</item>
    </argument>
  </arguments>
</type>
We encourage you to investigate existing Adapters’ source code from Front-Commerce’s core to learn about advanced patterns.
Edit on GitHub