Documentation

Implementing a New Payment Method

This tutorial will show you how to add a new payment method by implementing the CommercePaymentMethod interface.

Payment methods represent various ways customers can pay for orders. Liferay Commerce provides several out-of-the-box payment methods including Authorize.Net, Mercanet, Money Order, and PayPal.

Out-of-the-box payment methods

Deploy an Example

In this section, we will get an example payment method up and running on your instance of Liferay Commerce.

Start a new Liferay instance by running

docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.29-ga29

Sign in to Liferay at http://localhost:8080. Use the email address test@liferay.com and the password test. When prompted, change the password to learn.

Then, follow these steps:

  1. Download and unzip the Acme Commerce Payment Method.

    curl https://learn.liferay.com/commerce/latest/en/developer-guide/sales/liferay-b1c3.zip -O
    
    unzip liferay-b1c3.zip
    
  2. Build and deploy the example.

    ./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
    

    Note

    This command is the same as copying the deployed jars to /opt/liferay/osgi/modules on the Docker container.

  3. Confirm the deployment in the Docker container console.

    STARTED com.acme.b1c3.impl_1.0.0
    
  4. Verify that the example payment method was added. Open your browser to https://localhost:8080. Then click the Applications Menu (Applications Menu), navigate to CommerceChannels, and scroll to the Payment Methods section.

Note

In Liferay Commerce 2.1 and earlier, navigate to Site AdministrationCommerceSettingsPayment Methods.

New payment method

Congratulations, you’ve successfully built and deployed a new payment method that implements CommercePaymentMethod.

Next, let’s dive deeper to learn more.

Walk Through the Example

In this section, we will review the example we deployed. First, we will annotate the class for OSGi registration. Second, we will review the CommercePaymentMethod interface. And third, we will complete our implementation of CommercePaymentMethod.

Annotate the Class for OSGi Registration

@Component(
	property = "commerce.payment.engine.method.key=b1c3",
	service = CommercePaymentMethod.class
)
public class B1C3CommercePaymentMethod implements CommercePaymentMethod {

It is important to provide a distinct key for the payment method so that Liferay Commerce can distinguish our new payment method from others in the payment method registry. Reusing a key that is already in use will override the existing associated payment method.

Review the CommercePaymentMethod Interface

Implement the following methods:

	public String getDescription(Locale locale);

This populates the “Description” column in the Payment Methods administration page. See the implementation in B1C3CommercePaymentMethod.java for a reference in retrieving the description with a language key.

	public String getKey();

This provides a unique identifier for the payment method in the payment method registry. The key can be used to fetch the payment method from the registry. Reusing a key that is already in use will override the existing associated payment method.

	public String getName(Locale locale);

This populates the “Name” column in the Payment Methods administration page. It works similarly to the getDescription method.

	public int getPaymentType();

This identifies how the payment engine will use a given payment method.

We use the value COMMERCE_PAYMENT_METHOD_TYPE_OFFLINE to inform the payment engine that there are no online processing requirements for this payment method. There are two other payment type constants available out-of-the-box: COMMERCE_PAYMENT_METHOD_TYPE_ONLINE_STANDARD and COMMERCE_PAYMENT_METHOD_TYPE_ONLINE_REDIRECT.

	public String getServletPath();

A servlet may be required to enable proper interfacing with an external payment provider for online payment methods. Since no servlet path is required for an offline payment method, getServletPath must return null.

Complete the Payment Method

The payment method is comprised of backend logic for processing and completing payments, as well as many more optional custom behaviors. Do the following:

Implement Payment Processing Logic

@Override
public boolean isProcessPaymentEnabled() {
	return true;
}

This method must return true for the payment method to process payments. This informs the payment engine what functionality is supported by our payment method.

@Override
public CommercePaymentResult processPayment(
		CommercePaymentRequest commercePaymentRequest)
	throws Exception {

	return new CommercePaymentResult(
		null, commercePaymentRequest.getCommerceOrderId(),
		CommerceOrderConstants.PAYMENT_STATUS_AUTHORIZED, false, null, null,
		Collections.emptyList(), true);
}

Implement custom payment logic in this method. The CommercePaymentResult should store information relevant to the processing of a payment. See CommercePaymentResult.java for more information.

Implement Payment Completion Logic

@Override
public boolean isCompleteEnabled() {
	return true;
}

This must return true for the payment method to complete payments. This informs the payment engine what functionality is supported by our payment method.

@Override
public CommercePaymentResult completePayment(
		CommercePaymentRequest commercePaymentRequest)
	throws Exception {

	return new CommercePaymentResult(
		null, commercePaymentRequest.getCommerceOrderId(),
		CommerceOrderConstants.PAYMENT_STATUS_PAID, false, null, null,
		Collections.emptyList(), true);
}

Implement custom payment completion logic in this method. CommercePaymentResult is a container that stores information relevant to the completion of a payment process. See CommercePaymentResult.java for more information.

Implement Optional Methods

There are additional methods that may be implemented to provide additional functionality, such as subscriptions, recurring payments, and refunds. These can be seen in CommercePaymentMethod.java. These methods come in pairs: one method to enable and the other to implement a given piece of functionality.

Many of these methods are important for payment methods using online APIs. See PayPalCommercePaymentMethod for an example of an online payment method.

Our example does not override any of these optional methods.

Add the Language Keys to Language.properties

Add the language keys and their values to a Language.properties file within our module:

b1c3-commerce-payment-method=B1C3 Commerce Payment Method
pay-via-b1c3-commerce-payment-method=Pay via B1C3 commerce payment method.

See Localizing Your Application for more information.

Conclusion

Congratulations! You now know the basics for implementing the CommercePaymentMethod interface and have added a new payment method to Liferay Commerce.

Additional Information