public interface Plugin
extends javax.ejb.EJBObject
This interface is implemented by a payment plug-in.
A payment plug-in (or simply plug-in) is a stateless session bean. It 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 herein should map directly to the related back-end financial transactions.
Payment plug-ins are extensions to the IBM Payment Plug-in Controller. Payment Plug-in Controller provides a unified view of payment services to IBM WebSphere Commerce. Although the Payment Plug-in Controller concerns itself with persistence, database transaction management, and other facilities. It does not provide direct connectivity with payment back-end systems. Connectivity is the payment plugin's goal. Payment Plug-in Controller supports multiple plug-ins running at the same time and hides the complexity from WebSphere Commerce behind a unique payment service API.
The Plugin specification defines a list of financial transactions that can be implemented by a plug-in:
Some transactions might not make sense for some plug-ins if the equivalent functionality is not available by the payment back-end system. Under these circumstances, a plug-in writer should determine which transactions to implement. For the transactions not implemented by the plug-in, FunctionNotSupportedException should be thrown.
As a guide, here is a list of financial transactions to be implemented based on the type of the plug-in. Please note that this list is not exhaustive:
Financial transaction | Credit card | Electronic check | Gift certificate |
checkPaymentInstruction | x | x | x |
validatePaymentInstruction | x | x | x |
approveAndDeposit | x | x | - |
approve | x | - | x |
reverseApproval | x | - | - |
deposit | x | x | x |
reverseDeposit | x | - | - |
credit | x | - | - |
reverseCredit | x | - | - |
A plug-in may implement more than one type of payment protocol. For instance, it can implement a protocol for credit card processing and also for electronic check processing. In that case, the plug-in should implement not only the recommended methods for credit card processing but also the recommended methods for electronic check transactions.
TimeoutException
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, since if the plug-in hasn't received a response from the back end (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 may be a short period for some applications, may be a long period for others.
Since plug-ins are stateless session beans (SSB) (and as such are not supposed to spawn their own background threads). Plug-ins may 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.
Approve sequence diagram
The diagram below shows the execution flow of the approve transaction. Similar flows happen for the other financial transactions.
Modifier and Type | Field and Description |
---|---|
static java.lang.String | COPYRIGHT
The IBM copyright notice field.
|
Modifier and Type | Method and Description |
---|---|
FinancialTransaction | approve(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry)
This method approves an amount against a particular payment instruction.
|
FinancialTransaction | approveAndDeposit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry)
This method deposits a payment without a prior approval.
|
boolean | checkHealth()
This method checks whether XML configuration for the Plugin is available.
|
void | checkPaymentInstruction(PluginContext pluginContext, PaymentInstruction paymentInstruction)
This method checks the existence of all required parameters in a PaymentInstruction and its syntactic correctness.
|
FinancialTransaction | credit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry)
This method credits an amount against a specific PaymentInstruction.
|
FinancialTransaction | deposit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry)
This method deposits an amount against a previously approved Payment.
|
java.lang.String | getMessage(PluginContext pluginContext, java.lang.String messageKey)
This method gets the translated error message associated with the particular error key.
|
FinancialTransaction | reverseApproval(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry)
This method cancels a payment that has been previously approved.
|
FinancialTransaction | reverseCredit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry)
This method cancels the specified credit.
|
FinancialTransaction | reverseDeposit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry)
This method cancels a previously deposited amount.
|
void | validatePaymentInstruction(PluginContext pluginContext, PaymentInstruction paymentInstruction)
This method validates the correctness and existence of any account associated with a PaymentInstruction.
|
static final java.lang.String COPYRIGHT
java.lang.String getMessage(PluginContext pluginContext, java.lang.String messageKey) throws PluginException, java.rmi.RemoteException
This method gets the translated error message associated with the particular error key.
Plug-ins are supposed to throw exceptions with translated error messages because the error messages need to be displayed and logged in a particular locale. However, the error messages might need to be referenced again later on a different locale. For that reason, error keys are stored by users of the payment subsystem instead of the error messages themselves.
Error messages are usually known at plug-in deployment time. However, error codes may change by the PSP's protocol being implemented by the plug-in. If that is the case, this method will be used to obtain these error messages once the messages become available.
If the plug-in cannot obtain the error message for the specified messageKey, the plug-in should return the messageKey itself.
If this method is not implemented, the Payment Plug-in Controller will assume that the error message is unknown.
FinancialTransaction approve(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry) throws PluginException, java.rmi.RemoteException
This method approves an amount against a particular payment instruction.
An approval reserves funds on a particular payment instruction without actually moving money from the payer to the payee. For instance, in credit cards, this should be mapped into a credit card authorization against the payment back-end system.
This method is typically implemented for Credit Cards and gift cards or similar payment methods where funds are reserved and later on captured. For example: Merchants processing credit cards will often approve the ordered amount during order capture and deposit when packages are shipped. Nevertheless, this method is not typically implemented for electronic check processing.
FinancialTransaction approveAndDeposit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry) throws PluginException, java.rmi.RemoteException
This method deposits a payment without a prior approval. Also called a "sale" transaction or "authorization with capture."
For example, plug-ins which support electronic check processing, or immediate sale of credit card transactions in a single back-end system call may use this method.
Executing a sale transaction might be advantageous for merchants because it minimizes the number of overall transactions and the total processing fees.
void checkPaymentInstruction(PluginContext pluginContext, PaymentInstruction paymentInstruction) throws PluginException, java.rmi.RemoteException
This method checks the existence of all required parameters in a PaymentInstruction and its syntactic correctness.
This method implementation should not incur in any connectivity to the payment back-end system. It implies quick parameter validation and fast in-memory processing.
If this method is not implemented, the Payment Plug-in Controller assumes that the PaymentInstruction is valid.
FinancialTransaction credit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry) throws PluginException, java.rmi.RemoteException
This method credits an amount against a specific PaymentInstruction.
This method supports dependent (associated with a prior deposit) and independent (not associated with a prior deposit) credits. The PaymentInstruction associated with the Credit in the FinancialTransaction allows the plug-in to determine which type of credit this transaction represents.
Independent Credit: the PaymentInstruction referenced by Credit will not have any Payments associated with it.
Dependent Credit: PaymentInstruction referenced by Credit will have at least one Payment associated with it. If the associated Payment does not have an actual approved and deposited amount, this is not a real dependent credit transaction.
FinancialTransaction deposit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry) throws PluginException, java.rmi.RemoteException
This method deposits an amount against a previously approved Payment.
This is typically invoked after the merchant has shipped the goods and is now entitled to receive payment.
This method should be implemented if the method approve(PluginContext, FinancialTransaction, boolean) is implemented. This method is typically implemented for credit cards, gift cards or similar payment methods where funds are reserved and captured later on. For example: Merchants processing credit cards will often approve the total ordered amount and capture when packages are shipped.
FinancialTransaction reverseApproval(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry) throws PluginException, java.rmi.RemoteException
This method cancels a payment that has been previously approved.
The amount can be partial if the plug-in back-end supports it. If the plug-in does not support partial amounts then the InvalidDataException should be thrown.
A reverse approval transaction is only requested against a plug-in if a previous approve transaction has been requested and is either in FinancialTransaction.STATE_SUCCESS or FinancialTransaction.STATE_FAILED.
FinancialTransaction reverseCredit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry) throws PluginException, java.rmi.RemoteException
This method cancels the specified credit.
The amount can be partial if the plug-in supports partial amounts. If the plug-in does not support partial amounts, then the InvalidDataException should be thrown.
A reverse credit transaction is only requested against a plug-in if a previous credit transaction has been requested and is either in FinancialTransaction.STATE_SUCCESS or FinancialTransaction.STATE_FAILED.
FinancialTransaction reverseDeposit(PluginContext pluginContext, FinancialTransaction financialTransaction, boolean retry) throws PluginException, java.rmi.RemoteException
This method cancels a previously deposited amount.
The amount can be partial if the plug-in supports partial amounts. If the plug-in does not support partial amounts, then the InvalidDataException should be thrown.
A reverse deposit transaction is only requested against a plug-in if a previous deposit transaction has been requested and is either in FinancialTransaction.STATE_SUCCESS or FinancialTransaction.STATE_FAILED.
void validatePaymentInstruction(PluginContext pluginContext, PaymentInstruction paymentInstruction) throws PluginException, java.rmi.RemoteException
This method validates the correctness and existence of any account associated with a PaymentInstruction.
This method may result in transactions to the back-end system. No funds should be transfered. This method goes beyond checkPaymentInstruction(PluginContext, PaymentInstruction). The intention of this method is to provide a thorough validation of the PaymentInstruction at an account level.
Example: Verify if a credit line account exists in an accounting system.
Some plug-ins might not be able to actually validate the existence and correctness of an account without actually transfering funds. Plug-ins might also implement this method using the same validation performed in checkPaymentInstruction(PluginContext, PaymentInstruction). If this method is not implemented, the Payment Plug-in Controller will invoke checkPaymentInstruction(PluginContext, PaymentInstruction) to validate a PaymentInstruction. If this method is also not implemented, then Payment Plug-in Controller will assume that the PaymentInstruction is valid.
boolean checkHealth() throws java.rmi.RemoteException
This method checks whether XML configuration for the Plugin is available. For the SimpleOffline, if the XML file is missing, or renamed, or its content is invalid, then false is returned. Otherwise true is returned. And for other Plugin, always true is returned since no corresponding XML configuration file exists.
This API is used by PluginFactory in accelerator. When false is returned, PluginFactory will not put this plugin into the available collection. And further it will not be listed in the available payment methods in accelerator.