Skip to main content
Version: 3.x

Implement a Front-Commerce payment method

Choose the payment workflow wisely

Payment can be handled synchronously or asynchronously.

If Front-Commerce allows both strategies to work, we highly recommend you to implement an asynchronous payment method (using IPN) whenever it is possible.

This will prevent your payments from being rejected later within the provider process without your backend application knowing about it.

In this guide, we'll implement an asynchronous Front-Commerce payment method.

Implement the server logic

Front-Commerce allows you to implement your own payment method. New embedded payment methods have to be registered from a GraphQL module. Let’s create a new "PWAy" payment module for a fictive payment provider.

Handle a sublist of payment methods

You may need to dynamically set the list of payment methods displayed for your module.

This is achieved by registering a replacement handler

my-extension/runtime.ts
export default createGraphQLRuntime({
contextEnhancer: ({ loaders }) => {
/* ... */
loaders.Payment.registerEmbeddedPaymentMethod(
/* ... */
);

loaders.Payment.registerMultiplePaymentMethods({
isMethodToReplace: (method) => method.code === METHOD_CODE,
getReplacementMethods: async () => {
try {
// custom call to fetch the allowed payment methods list
const paymentMethods = call(/* ... */);
return paymentMethods.map((method) => ({
// this is the method code provided to the checkout workflow
// note that all payment methods must have a common prefix
code: `${prefix}_${method.id}`,
// the displayed payment method name on the checkout page
title: method.description,
// this method is called following the onAuthorize call in the AdditionalDataComponent (see bellow) instead of the default method defined with registerEmbeddedPaymentMethod
callback: (paymentData, orderId, orderPaymentDetails) =>
return loader.order(paymentData, orderId, orderPaymentDetails);
})),
} catch (error) {
// handle the error here
return [];
}
},
});
/* ... */
},
});

Display the new payment method on the UI with additional information

While payment methods provided by Front-Commerce don't need any additional information, you may require some, for example, if you want to let users enter a comment related to the payment method/checkout.

note

See the payment workflows specificities for changes to the current example for each workflow.

Payment workflows specificities

Front-Commerce provides different hooks allowing you to use the payment method of your choice. This section explains the implementation specificities of each payment workflows.

note

The documentation here only explains changes to apply to the default implementation example for each workflow.

Async Order

This workflow is recommended for payments that are fully front-end (e.g. Payzen/Lyra, Paypal)

Server changes

Ensure the direct payment processor call does nothing in the extension's contextEnhancer:

my-extension/runtime.ts
export default createGraphQLRuntime({
contextEnhancer: ({ loaders }) => {
// ...
loaders.Payment.registerEmbeddedPaymentMethod(
METHOD_CODE,
METHOD_TITLE,
- (paymentData, orderId, orderPaymentDetails) => {
- return loader.order(paymentData, orderId, orderPaymentDetails);
- },
+ () => {
+ throw new Error(
+ "The payment method should only be handled by IPN notifications"
+ );
+ },
null,
new MyPaymentNotificationProcessor(hipayConfig)
);

return {}; // you may export loaders here in case the payment provides custom Queries (to fetch a payment token for instance)
},
});
note

This implies the order method in the module’s loader is not needed for this method (your may need to implement other methods instead to be used by the NotificationProcessor)

my-extension/loaders/MyPaymentLoader.ts
export default class MyPaymentLoader {
- async order(paymentData, orderId, orderPaymentDetails) {
- // ...
- }
}

Theme changes

Override theme/pages/Checkout/checkoutFlowOf.js to indicate the use of the asyncOrder workflow for the pway_awesomecheckout method code

app/theme/pages/Checkout/checkoutFlowOf.js
const checkoutFlowOf = (method) => {
...
+ if (method === "pway_awesomecheckout") return "asyncOrder";

return "directOrder";
};

export default checkoutFlowOf;

Direct Order

A direct order handles directly the payment on onAuthorize call in the CustomComponent you created (my-extension/theme/modules/CustomComponent/CustomComponent.js).

This onAuthorize call will provide the information to loader.order() implemented server-side. This last method is responsible to handle the full payment process.

Sub workflow : Direct Order with additional action

You may need to handle a second payment step with a Direct order workflow (3DS validation, etc).

In this case, perform the following steps:

Redirect Before Order

warning

This workflow is only supported for Magento2, please contact us if you need this workflow with another backend server

A redirect before order workflow allows to interact with payment providers handling the complete payment workflow on their side.

Front-Commerce will only redirect to the payment provider and ensure the order creation afterwards.

Server changes

Theme changes

warning

No AdditionalDataComponent is required for this implementation as there is no frontend component displayed by Front-Commerce

Using this workflow, you will need to override theme/pages/Checkout/checkoutFlowOf.js to indicate the use of redirectBeforeOrder:

app/theme/pages/Checkout/checkoutFlowOf.js
const checkoutFlowOf = (method) => {
...
+ if (method === "pway_awesomecheckout") return "redirectBeforeOrder";

return "directOrder";
};

export default checkoutFlowOf;
note

We encourage you to have a look at the payment extensions' source code from Front-Commerce to learn about advanced patterns: