Custom Payment Method
Implement a new Front-Commerce Payment method
The payment strategies
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.
Let’s go to the implementation (with IPN)
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.
-
add a depency upon
"Magento2/Checkout"
and"Front-Commerce/Payment"
export default {
namespace: "Payments/PWAy",
dependencies: ["Magento2/Checkout", "Front-Commerce/Payment"],
}; -
register the payment method from the module’s
contextEnhancer
export default {
namespace: "Payments/PWAy",
dependencies: ["Magento2/Checkout", "Front-Commerce/Payment"],
contextEnhancer: ({ loaders }) => {
// [...] initialization here
const loader = new MyPaymentLoader();
const METHOD_CODE = "pway_awesomecheckout";
const METHOD_TITLE = "PWAy";
loaders.Payment.registerEmbeddedPaymentMethod(
METHOD_CODE,
METHOD_TITLE,
// this method is called following the onAuthorize call in the AdditionalDataComponent (see below)
// e.g. to trigger the payment authorization on the provider (validation and capture will be handled asynchronously by IPN)
(paymentData, orderId, orderPaymentDetails) => {
return loader.order(paymentData, orderId, orderPaymentDetails);
},
null,
// The notification processor will handle IPN notifications from the payment provider
new MyPaymentNotificationProcessor(hipayConfig)
);
return {}; // you may export loaders here in case the payment provides custom Queries (to fetch a payment token for instance)
},
}; -
implement your loader's
order
method to process a payment
export default class MyPaymentLoader {
constructor(...) {
...
}
async order(paymentData, orderId, orderPaymentDetails) {
// process the paymentData and call the payment provider
const paymentStatus = call(...)
// return payment DomainEvents representing what happened in the remote payment system.
// These events are broadcasted by Front-Commerce to the registered external event listeners
// that can use this information to update other remote systems (e.g: adding an Order comment in Magento)
switch(paymentStatus.status) {
case SUCCESS:
// as the IPN handler will handle final authorisation it is often only an authorisation at this step
return new PaymentAuthorized(
new PurchaseIdentifier({ orderId }),
paymentStatus.paymentReference
)
case REFUSED:
return new PaymentRefused(
new PurchaseIdentifier({ orderId }),
paymentStatus.reason
)
}
}
}
- Implement the notification processor (for IPN handling)
See how to implement a NotificationProcessor
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
export default {
namespace: "Payments/PWAy",
dependencies: ["Magento2/Checkout", "Front-Commerce/Payment"],
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
see the custom payment information for details on the front-end implementation of a payment method
see the payment workflows specificities for changes to the current example for each worflow
We encourage you to investigate payment-
modules' source code from
Front-Commerce's core
to learn about advanced patterns.