Reference > Payments subsystem


Payment plug-in specification

This section provides an overview of the payment plug-in specification.


Version: 1.0


Purpose: This specification accompanies the Java API information for the IBM Payment plug-in. This information provides an overview of payment plug-ins and the payment plug-in specification.


Target audience and skill requirements: The target audience for this information is application developers for payment service providers, e-commerce solutions, or external payment systems.


Related information: This payment plug-in API specification is intended to be used with the following API information:


Features: The payment plug-in specification has the following features:

*Plug-ins are provided in WebSphere Commerce to support these methods. If you write the own plug-in, follow this specification.


Organization of this specification: This specification includes a list of terminology used, specification details that supplement the API information, examples of the plug-in deployment descriptor and related XSD file, and diagrams that help illustrate important concepts. It also contains information about error handling and security considerations.

The following topics are included in this specification:


Terminology used in this specification

Container

A value object that contains financial information and can aggregate or relate to other containers. The containers defined in the plug-in specification are:

  • PaymentInstruction
  • Payment
  • Credit

Financial transaction

A transaction (object) that...

  • validates or authenticates payment information
  • reserves funds in accounts
  • transfers funds from one account to another

The ExtendedData value object of the financial transaction provides plug-ins with a mechanism to the store protocol data that is used during financial transactions.

Payment protocol

A payment protocol is the convention that governs the exchange of data between a payment plug-in and a payment back-end system (payment service provider or payment processor). A payment protocol can involve online or offline processing to allow financial transactions to be carried out. Online processing or the online protocol refers to the processing of financial transactions that do not require external intervention for successful execution. The online processing of a financial transaction is done completely electronically and automatically without the need for any external or human intervention. Offline processing or the offline protocol refers to the processing of financial transactions that require external intervention for successful execution. For example, when a credit card needs to be processed over the phone or by using a swipe box, it is considered offline processing because the external intervention by a human is needed in order to process the transaction.


Specification description


Plug-in deployment descriptor

A plug-in deployment descriptor enables a plug-in to integrate with WebSphere Commerce. It is an XML file that contains information about a plug-in and describes to the Payment plug-in controller how the plug-in should be deployed. A plug-in deployment descriptor contains common properties that are used by the Payment plug-in controller during system initialization to launch and send requests to the plug-in. It is used by the WebSphere Commerce installation and configuration programs to enable the payment plug-in within the Payment plug-in controller and the WebSphere Commerce instance.

The plug-in deployment descriptor describes the specific configuration requirements that must be resolved in order for the plug-in to work correctly. The descriptor must contain the plug-in home interface name.

Plug-in deployment descriptors are named PluginDeployment.xml and reside in the deployed instance's EAR directory in WebSphere Application Server.

A plug-in deployment descriptor must exist for every plug-in, and can be used to define additional properties that are specific to a particular plug-in. A Plug-in deployment descriptor XSD and PluginDeployment.xml are included in this specification.


Understand the plug-in interfaces

For more information about these interfaces, see the related API information.

Plugin interface

Stateless session bean with a remote interface that externalizes payment services for a particular payment back-end system, payment processor, or payment service provider (PSP). Plug-ins can be considered proxies to payment back-end systems and the methods in this interface should map directly to the related back-end financial transactions.

Payment plug-ins are extensions to the Payment plug-in controller, which provides a collective view of payment services to WebSphere Commerce. The Payment plug-in controller does not provide direct connectivity to a payment back-end system. Such connectivity is the goal of a payment plug-in.

The financial transactions that can be implemented by a Plug-in interface are:

  • Payment approval (or authorization)
  • Payment deposit (or capture)
  • Credit (or refund)
  • Reversals for the preceding transactions

As a plug-in writer, you decide what methods in the Plug-in interface to implement, based on the payment protocol and the back-end system capability. Since some transactions do not apply for some plug-ins, you should determine which transactions to implement. For transactions that are not implemented by a plug-in, the exception FunctionNotSupportedException should be thrown.

TimeOutException in the Plugin interface

To avoid resource contention, a plug-in should not block a request for long periods of time. Whenever possible, a plug-in should throw TimeOutException when a configurable amount of time has elapsed.

For example, during an approve() request, a plug-in could wait for at most 45 seconds. After that period of time, if the plug-in has not received a response from the back-end system (payment service provider), it will throw a TimeOutException.

Note that the plug-in should make the waiting period a configurable property in the plug-in deployment descriptor. What might be a short period for some applications can be a long period for others.

Since plug-ins are stateless session beans (SSB) (and as such are not supposed to create their own background threads), they might not be able to detect a timeout by themselves. In these cases, the EJB transaction which contains the plug-in request will be rolled back automatically by the EJB container according to a pre-configurable timeout.

QueryablePlugin interface

Extends the Plugin interface and supports financial queries. As plug-in writer, decide if the plug-in should implement this interface based on the query capability of the back-end system. It is the responsibility of the plug-in to determine whether it uses information received by querying the back-end system.

In general, the Payment plug-in controller manages the state of financial objects for plug-ins. However, if the payment back-end system supports real-time queries, you might want to use this capability by implementing this interface.

By implementing this interface, you can have real-time and up-to-date statuses of financial objects (payments and credits). However, use of this interface will need greater network connectivity than no querying.

If the payment back-end system does not support real-time queries, do not implement this interface.

When a Plugin implementation uses this interface and some of the query methods are not supported by the back-end system, the plug-in should throw the exception FunctionNotSupportedException.

Plugin_V2 interface

Extends the QueryablePlugin interface and supports batch processing. Therefore this interface should only be implemented if the plug-in also supports batch processing.

PluginConfiguration interface

In-memory image of the plug-in deployment descriptor. The plug-in deployment descriptor describes a plug-in implementation (plug-in metadata and configuration information). It also provides plug-in-specific properties that can be used by the plug-in during the processing of financial transactions.

PluginContext interface

Provides the context of the request used in processing financial transactions and queries. For example, it provides the plug-in configuration information and the locale to be used for processing.

PaymentInstruction interface

Value object containing detailed information required by plug-ins to process financial transactions. It contains information including the account number, and payment or credit amounts. It does not contain information used to track a particular transaction with a payment back-end system. (Tracking information is obtained by using the Payment, Credit, and FinancialTransaction interfaces.)

For an illustration of the relationship between the PaymentInstruction value object container and the Payment, Credit, and FinancialTransaction containers, see the Payment plug-in containers class diagram.

The amounts section in the PaymentInstruction represents the maximum target amount that the Payment plug-in controller can collectively consume on the payment instruction.

The Payment approvedAmount attribute identifies how much has been approved (authorized) and limits how much can be deposited (captured).

The Payment depositedAmount attribute identifies how much has been deposited.

The Payment plug-in controller ensures that the PaymentInstruction amount is always equal to or greater than the total amount of all requests. The Payment plug-in controller allows approve and credit financial transactions to occur up to that amount.

For example, A PaymentInstruction is created with an amount of $100.00 U.S. dollars, followed by an approve transaction of $40.00, and then another approve of $65.00. The Payment plug-in controller will not allow the second approve amount to happen since it exceeds the maximum PaymentInstruction amount. The caller of the Payment plug-in controller then decides whether to increase the PaymentInstruction's amount to permit the larger aggregated approve (authorization) amount.

Extra protocol data beyond the standard attributes defined in the PaymentInstruction definition are managed by ExtendedData and Keywords

Because this container is a value object, no financial transactions actually occur in this object. This object contains information about the financial transactions before, during, and after the transactions are processed.

FinancialTransaction

Value object container representing a financial transaction. This container represents all possible types of financial transactions that can be processed by a plug-in. The actual attributes used will depend on the type of transaction taking place.

A flow diagram showing an example of how a financial transaction is run in Financial transaction execution flow example.

The transaction types supported in this specification are:

  • approve
  • deposit
  • approveAndDeposit
  • credit
  • reverseApproval
  • reverseDeposit
  • reverseCredit

The financial transactions involving reversals (reverseApproval, reverseDeposit, and reverseCredit) apply to currently approved amounts. Reversal amounts can be equal to or less than the approvedAmount, depositedAmount, and creditedAmount. The amount currently approved might not be obvious; for example, an approve transaction for $50 U.S. dollars can be followed by a reverse approval of $25 and another reverse approval of $25. In this case, the currently approved amount is $0.

A plug-in must update the FinancialTransaction container while processing financial transactions. Several attributes are predefined in this container. A plug-in can also add additional information to the FinancialTransaction container by using the ExtendedData class.

Response codes and reason codes

In this interface, the response code is a back-end-specific representation of a financial transaction result. It is typically used by the back-end system to indicate if a financial transaction was successful or not. For example, the response code might indicate that a credit card authorization has failed.

The reason code is a back-end specific representation of an error condition. It is typically used by the back-end system to indicate why a financial transaction has failed. For example, it might indicate that a credit card has expired. When the response code alone cannot identify what has happened in a financial transaction, the reason code can be used to determine the financial transaction error.

The response code and reason code attributes can be viewed as primary and secondary error codes. Use them to perform problem determination when the standard plug-in exceptions that can be thrown back to the Payment plug-in controller in the Plugin or QueryablePlugin interface are insufficient to determine the source of a problem.

The response code and reason codes are helpful when performing problem determination. For example, if a plug-in throws FinancialException during a credit card approve transaction, the response code and reason code might indicate whether the credit card is stolen or expired.

For successful transactions, plug-ins should always set response code "0" (String type) and reason code "0" (String type). For pending transactions, plug-ins do not have to set these two codes. For failed transactions, the payment plug-in should define the codes.

TheWCPayments plug-in sets the primary return code (PRC) of the Payment plug-in controller system to a response code. It also sets the "PRCxxxSRCxxx" to the reason code. PRCxxxSRCxxx is the String representation of PRCxxx concatenating SRCxxx. Where:

PRC Primary Return Code
SRC Secondary Return Code
xxx Corresponding return code

Track IDs

The tracking ID is an optional attribute used by the plug-in to identify the financial transaction in the payment back-end system. It is set by the plug-in during the processing of a financial transaction, and is unique to the plug-in and in the back-end system. Although this attribute is optional, it might be the only way to track a financial transaction in the back-end system if an error occurs. For example, if network connectivity is lost during a financial transaction, the plug-in would not be able to tell if the back-end system actually processed the transaction. The tracking ID is the only mechanism available to query the back-end system later on after connectivity is established again.

The reference number is an ID generated by the payment back-end system during the processing of financial transactions. It is typically required by the payment back-end system to process subsequent and related transactions. For example, during a deposit transaction, the reference number of a previous approve transaction is required. In this case, the reference number is the authorization code returned by the back-end system during the approve transaction.

While the tracking ID is used to identify a financial transaction from the plug-in perspective, the reference number is used to identify a financial transaction from the payment back-end system perspective. The tracking ID is the first identifier of the transaction to exist. After the reference number is obtained from the back-end system, the plug-in might not need the tracking ID anymore since the reference number is known by both the plug-in and the payment back-end system.

Since this container is a value object, no financial transactions actually occur in this object. This object contains information about the financial transactions before, during, and after the transactions are processed.

Payment interface

Value object container for payment-related transactions. This container can hold a single payment approval (authorization) and multiple deposits (captures) for the same approval. However, multiple deposits for a single approval might not be supported by all payment back-end systems.

This container is created before the approval transaction and is used on subsequent transactions such as deposits and reversals. The Payment plug-in controller ensures that only one approve transaction is issued against a Payment. It also ensures that only one transaction is in a pending state for a given Payment at the same time.

Payments are always associated with a PaymentInstruction container. A PaymentInstruction keeps references to all Payment containers and all Credit containers associated with it.

The following are the states associated with a Payment:

New For a payment container object when newly created

Approve On a pending approve transaction Approved On a successful approve transaction Canceled When a payment is canceled Expired When the approval has expired Failed When a transaction has failed

For an illustration of how a Payment moves from state to state when financial transactions or edits are run against it, see the Payment state machine.

Since this container is a value object, no financial transactions actually occur in this object. This object contains information about the financial transactions before, during, and after the transactions are processed.

Credit interface

A refund instruction is very similar to a payment instruction. A return merchandise authorization (RMA) can have multiple refund instructions. However, refund rules are not configurable.

The Credit interface is a value object container for credit-related transactions. Credits are sometimes referred to as refunds when associated with a return merchandise authorization. The following are possible transactions associated with a Credit:

  • Credit
  • Credit reversal

A Credit container supports only one credit transaction during its life span. However, multiple reversals can be supported for the same credit transaction.

Since this container is a value object, no financial transactions actually occur in this object. This object contains information about the financial transactions before, during, and after the transactions are processed.

The states associated with a Credit are:

New For a credit container object when newly created.
Crediting When a credit transaction is pending.
Credited When a successful credit transaction has been completed.
Canceled When a credit has been fully reversed.
Failed When a transaction has failed.

For an illustration of how a Credit moves from state to state when financial transactions, queries, or edits are run against it, see the Credit state machine.

Two types of credit transactions can occur:

Dependent credit Dependent credits are transactions associated with a PaymentInstruction where deposits have already taken place. For example, after a deposit of $100 U.S. dollars, a credit up to $100.00 would be considered a dependent credit.
Independent credit Independent credits are transactions associated with a PaymentInstruction where no previous deposits have taken place, or the amount of credit goes beyond the previously deposited amount. For example, after a deposit of $100.00, a credit of $150.00 is an independent credit. Also, without any previous deposit, a credit of any amount would be an independent credit.

Support for dependent and independent credits can vary among payment back-end systems.

A plug-in can access the associated Payment containers to determine if a credit transaction depends on a previous deposit transaction. If that is the case, the credit transaction can be handled as a dependent credit and the plug-in can proceed accordingly. Otherwise, the transaction is an independent credit.


Understand the plug-in classes

ExtendedData class

In a payment plug-in context, extended data is non-standard protocol data required in financial transactions. The ExtendedData class collects the non-standard protocol data that is required by a financial transaction. Plug-ins require extra protocol data that goes beyond the standard attributes defined in a PaymentInstruction container. These extra attributes are passed from the Payment plug-in controller to a plug-in by using the ExtendedData class.

When associated with a PaymentInstruction, the ExtendedData class is potentially used by all financial transactions run against the same PaymentInstruction.

However, ExtendedData can also be attached to a particular FinancialTransaction container so that the additional attributes are used only in the same FinancialTransaction container. Subsequent financial transactions can reuse the contents of the ExtendedData class if they are related to a previous FinancialTransaction container.

NamedValueObject

Data attribute with a name, a value, and an encryption flag. These objects are typically used to store information about a protocol, and make up the ExtendedData class. If the encryption flag is set on the name-value pair, the attribute values will be encrypted while stored in the WebSphere Commerce database.

PluginMessages

Defines standard translated messages and the utility to retrieve these messages. For a list of the standard plug-in messages, see the API information for this class. Plugin messages are included in logged exception messages. The predefined WebSphere Commerce tracing component, WC_PPC_PLUGIN, is used as the WebSphere Application Server logger name for plug-in messages.

The properties file for messages is located in the following directory:

  • WC_EAR/properties/com/ibm/commerce/negotiation/properties/com/ibm/commerce/payments/plugin/PluginMessages *.properties

  • WC_EARur\properties\com\ibm\commerce\payments\plugin\PluginMessages *.properties


Payment plug-in error handling

The payment plug-in specification identifies a set of predefined exceptions. If a plug-in does not implement a particular method, the plug-in should throw the exception FunctionNotSupportedException. If additional exceptions need to be added for a plug-in, the exception PluginException should be extended. However, the Payment plug-in controller will not be able to process these exceptions in any particular way. Although all exceptions are caught, plug-in-specific errors cannot be handled properly. For example, a FinancialException informs the Payment plug-in controller that some financial error has occurred and the Payment plug-in controller can act accordingly by informing other software layers, such as the Payment rules engine. However, if an ABCException occurs, it is wrapped as a generic plug-in exception.

Exceptions thrown by a plug-in should contain as much contextual information as possible to allow convenient error handling and problem determination. Information can include the result codes from the payment back-end system, and container reference to the payment instruction, payment, and credit.

Exception hierarchy of payment is independent of ECException. The root exception for payment is BaseException which extends from Exception. There are two sub-exceptions of BaseException:

EDPException

The root exception of the Payment rules engine.

PluginException

The root exception of the payments plug-in.
For each kind of PluginException, there is a corresponding type of EDPException. For example, com.ibm.commerce.payments.plugin.InvalidDataException is a PluginException, and com.ibm.commerce.edp.api.InvalidDataException is its corresponding EDPException.

In the case of exceptional situations, throw PluginException (or sub-exceptions) in the payment plug-in.

InvalidDataException

If the payment transaction failure is caused by invalid payment information that a shopper inputs, you can throw an InvalidDataException with the message key and resource bundle.

InvalidDataException ie = new InvalidDataException();  ie.setMessageKey(your message key);  ie.setFormatArguments(your message arguments);  ie.setResourceBundleName(your resource bundle); throw ie;

This exception is mapped to the ECApplicationException with an error message containing the message of the InvalidDataException. For example:

A generic payment user exception occured. The exception is... "error message of InvalidDataException"

If you do not want extra messages other than what you have defined in the InvalidDataException, you can override the NLV message definition in the resource bundle. The resource bundle is located in the following directory:

  • WC_EAR/Stores.war/WEB-INF/classes/storedir

  • workspace_dir\Stores\Web Content\WEB-INF\classes\storedir

For example, you can add English messages in this file: storeErrorMessages_en_US.properties.

    _ERR_PAYMENT_GENERIC_USER_EXCEPTION={0}

Then the error message displayed in the store page will be:

    error message of InvalidDataException

6.0.0.3 The exception handling and error messages of the plug-in exception have been enhanced. Error messages display on the store page. it is no longer necessary to customize the resource bundle as described in the preceding example.

CommunicationException

If the payment plug-in experiences a connectivity problem while communicating with the payment back-end system. You can throw a CommunicationException with the message key and resource bundle.

    CommunicationException ce = new CommunicationException(); ce.setMessageKey(your message key); ce.setFormatArguments(your message arguments); ce.setResourceBundleName(your resource bundle); throw ce;

This exception is mapped to the ECSystemException with an error message containing the contents of the CommunicationException error message: Failed to execute payment action due to {error message of CommunicationException} If you do not want message contents that are other than what you defined in the CommunicationException, you can override the NLV message definition in resource bundle of your store under WC_EAR/Stores.war/WEB-INF/classes/storedir workspace_dir\Stores\Web Content\WEB-INF\classes\storedir For example, if the store only addresses the language environment of English, you can add the following NLV message definition in storeErrorMessages_en_US.properties under this directory: _ERR_PAYMENT_DO_PAYMENT_ACTIONS_POLICY_CMD={1}. Then the error message displayed in the store page becomes: error message of CommunicationException. Note that since CommunicationException is mapped to ECSystemException, which causes the overall transaction to roll back, WebSphere Commerce the payment request would be resubmitted if the calling WebSphere Commerce controller command is configured to be retriable=1.

For example, the OrderProcessCmd is configured such that if this exception is thrown due to a payment authorization failure at a submitted order, this command is retried and payment authorization is triggered again. If you do not want the command to be retried in such a situation, set the calling command to retriable=0 the CMDREG database table. Do not set this command to not retry for ECSystemException, because the command needs to retry to handle exceptional situations.

FunctionNotSupportedException

If this type of financial transaction is not supported by your plug-in implementation, you can throw the FunctionNotSupportedException with the message key and resource bundle. For example, if the plug-in does not support approveAndDeposit API but the merchant tries to call this API, then the FunctionNotSupportedException is thrown. This exception is mapped to ECApplicationException, so the behavior after this exception is thrown is similar to InvalidDataException.

ConfigurationException

If the payment plug-in fails to find the required information in the plug-in configuration, you can throw a ConfigurationException with the message key and resource bundle. For example, if the configuration in the plug-in deployment xml file is invalid, then the ConfigurationException is thrown. This exception is mapped to the ECSystemException, so the behavior after this exception is thrown is similar to CommunicationException.

InternalErrorException

If the payment plug-in experiences an unexpected error happened in the plug-in implementation, you can throw InternalErrorException with the message key and resource bundle. For example, if the plug-in receives the response from the gateway of payment service provider with invalid format, then the InternalErrorException is thrown. This exception is mapped to ECSystemException, so the behavior after this exception is thrown is similar to CommunicationException.

TimeoutException

If the payment plug-in times out waiting for a response, you can throw TimeoutException with the message key and resource bundle. For example, if the plug-in is configured such that the time out waiting for a response is over and there has been no response, then TimeoutException is thrown. The TimeoutException is thrown by the Payment plug-in controller. If you throw this kind of exceptions, the overall WebSphere Commerce transaction will not roll back instead the payment status is set to pending. If the payment service provider supports retrying the payment transaction, then you can throw this exception when you fail to receive the response.

FinancialException

Thrown by the Payment plug-in controller. If you throw this exception, the overall WebSphere Commerce transaction does not roll back, but instead the involved payment status is set to failure.

To capture the order in the case that a payment fails to run, use the FinancialException in the plug-in. There are three sub-exceptions of FinancialException:

ApprovalExpiredException

Thrown when the payment approval (authorization) has expired. This exception is different from the following two sub-exceptions because it is not mapped to an ECSystemException.

InvalidPaymentInstructionExcepiton

Thrown to indicate that the PaymentInstruction is invalid.

PaymentInstructionBlockedException

Thrown when a financial transaction cannot be processed against a PaymentInstruction. This is a temporary situation. The financial transaction can be tried again after some time, against the same PaymentInstruction. For example, the credit card associated with a payment instruction might have been put on hold. The behavior of InvalidPaymentInstructionException and PaymentInstrutionBlockedException are the same as FinancialException.

PluginException

If you cannot find an appropriate exception from those mentioned above, you can throw a PluginException. This exception is mapped to ECSystemException, so the behavior after this exception is thrown is similar to CommunicationException. (6.0.0.3) We improved the framework of the exception handling of the payments plug-in:

  1. Only CommunicationException and InternalErrorException are mapped to ECSystemException, while all other plug-in exceptions are mapped to ECApplicationException.

  2. When the plug-in exceptions are mapped to an ECException, the message key of the resource bundle that is set in the plug-in exceptions is then composed into a new ECMessage object as the message key of this ECException. In the store page, the error message which is set in the plug-in is displayed without any extra content as above. You do not need to customize in this case.

You can define the own exceptions as needed, but these exceptions must extend from PluginException. The behavior is the same as a PluginException.


Security considerations for payment plug-ins

Payment plug-ins are responsible for the security of the communication with their payment back-end systems. Since payment information is sensitive data, the plug-ins should encrypt all data that is sent over network connections. The Payment plug-in controller does not provide encryption services for this type of communication with the payment back-end system.

All sensitive data in a PaymentInstruction container is encrypted by the Payment plug-in controller when they are persistent in the PPCEXTDATA table.

If the plug-in persists sensitive data on its own, either in the file system or using databases, this sensitive data should be encrypted. The Payment plug-in controller does not provide encryption services for this persistence.

If you decide to use Java EE or EJB access control, the plug-in documentation that you produce needs to be clear about what user roles and permissions are required to use the plug-in implementation so that the plug-in can be deployed accordingly.

Transient sensitive data, for example, Card Validation Code, is passed to the plug-in as the extended data of the current payment instruction. You can retrieve the data in the plug-in and pass it to the back-end payment system if necessary. Note that you should not persist or remove any of the transient sensitive data in the plug-in. The Payments plug-in controller is responsible for removing transient sensitive data and guaranteeing that it is not persisted in the DB.


Related concepts

Financial transactions

Payment plug-ins