This supersedes the old SEMPER activity paper, 212ZR054: Payment Manager Overview.
An active instance of the payment service block will contain the following objects:
PaymentManager object
      (in reality, the functionality of the payment manager is split
     over several classes, including the class PaymentManager)
 Purse objects
 PaymentTransaction objects (each corresponding
     to an ongoing purse transaction)
 PaymentTransactionRecord for each
     PaymentTransaction object. (Note: this is
      created each time a
      PaymentTransaction is created.  But the
     PaymentTransaction 
      object is transient (i.e. discarded at the end of a session or
     at the completion of the transaction) while the
      PaymentTransactionRecord is stored for longer periods.
 
 Figure 1: A Payment Service Block in Action 
   (Courtesy Günter Karjoth)
The functionality expected from payment systems is captured in the
PurseServices interface hierarchy.   The root
PurseServices interface contains methods corresponding to
services expected from all payment systems.  Additional services
that are specific to various payment models is captured in sub-interfaces
that extend the root interface. Initially, two basic payment models
are supported: the account-based model and the cash-like model.  A
specialisation of the account-based model for
electronic cheque payment systems is also available.
 - PurseServices -+--- AccountBasedPurseServices
                  |
                  |
                  |
                  +--- CashLikePurseServices
                  |
                  |
   These interfaces describe the generic purse services required by the
    various payment models.  These will be implemented by:
    the PaymentTransaction subclass (see below) corresponding to
    each payment system of the appropriate model.
Purse services that are optional are defined separately.  An example
is the MicropaymentServices interface.  Each category of
optional services will be in the form of a parallel interface
hierarchy similar to the PurseServices hierarchy.
It is not mandatory for the subclasses of the Transaction
class to implement the optional part of the purse services interface.
 - Purse-+--- AccountBasedPurse -+---AbcPurse
         |                       |
         |                       +---....
         |
         +--- CashLikePurse  -------+---....
         |                          |
         |                          +---....
A purse is a repository of information related an installed payment
system.  As with the PurseServices hierarchy, the
Purse class hierarchy has a root class and model-specific
subclasses of it. The root class defines a set of services. Some are
in the form of abstract method definitions which need to be
implemented by the Purse subclasses. For the rest,
default implementations are provided; the subclasses may override them
if needed.
 - PaymentTransaction -+--- AbcTransaction
              |
              |
              |
              +--- ....
              |
Objects of this class hierarchy are the primary objects in the payment
service block for providing payment services.  A
 PaymentTransaction
 object can
be thought of as an abstraction of a "transaction."  The root class
simply provides the functionality of a generic "transaction" (e.g.: methods
to abort and to status check).  Each payment system is required to have a subclass
of the PaymentTransaction class that implement the
PurseServices interfaces for its payment model.
Note that we could have abstract subclasses AccountBasedTransaction and
CashLikeTransaction and then make AbcTransaction a subclass of one of
these classes.  We have not done this at this time because there
doesn't seem to be a need for it (if defined, such classes would be empty
at least as of now).  If it becomes necessary, they can always be
defined.
Currently, the model-specific functionality provided by the
transaction objects is expressed by the corresponding sub-interface in the
PurseServices
interface hierarchy.  Functionality expected from a generic transaction is
expressed by the PaymentTransaction class.  The adapter of a
payment system will subclass the PaymentTransaction
class to inherit
specifications of the generic transaction functionality and implement
the model-specific PurseServices sub interface to inherit
specifications of the model-specific functionality.
Hence there is no need for the aforementioned intermediate
subclasses of PaymentTransaction.
Finally, note that subclass designers should ensure that only methods
corresponding to a single transaction are executed on an
PaymentTransaction object.  (e.g. if someone creates an
PaymentTransaction object, invokes pay() on it and
then attempts to make another invocation of a purse service on the same object, the
second attempt must be disallowed;  however multiple invocations of
doMicroPayment() or capture() on the same PaymentTransaction
object is legal).
PaymentTransaction object keeps any data with
long-term relevance in a corresponding
PaymentTransactionRecord object.  Recall that the latter
object is the one that is archived after the transaction is complete.
Typically, the designer of the adapter for a payment system will
subclass the PaymentTransactionRecord class in order to
keep information specific to that payment system. The
startTransaction() method in the Purse
subclass should do the following:
getNewTXRHandle() method in the Purse
      class,
  PurseServices interface hierarchy. For example, the
PaymentTransactionRecord object has an attribute of this
class to denote the service that was provided during the corresponding
transaction. Each model may have an optional subclass of the root
ServiceType class. Individual adapters are free to extend
the hierarchy further. The various methods in the transaction class of
an adapter should use these service type identifiers to keep the
transaction record up-to-date. 
 - PaymentTransactionState-+--- AccountBasedTransactionState-+--...
         |                                                   |
         |                                                   +---....
         |
         +--------------------- CashLikeTransactionState ----+---....
         |                                                   |
         |                                                   +---....
This class hierarchy is used to represent the states of a
transaction. Again, the
PaymentTransactionRecord object has an attribute of this
class to denote the state of the corresponding transaction. The root
class is extended for each model and adapters are free to extend it
further. Each class in this hierarchy provides the following:
TS_INITIATED [in
      PaymentTransactionState] and
      TS_AB_CAPTURED [in
      AccountBasedTransactionState]) 
  setState[in
      PaymentTransactionState] 
      setAccountBasedState [in
      AccountBasedTransactionState] etc.)
  PaymentManager  class.
 PurseSelection
     class.  
To incorporate a payment system into the payment service block, the following are necessary:
PaymentTransaction class which
      implements the purse services defined in the interface corresponding
      to the appropriate payment model, AbcTransaction class that implements:
     AccountBasedPurseServices interface, and
       MicropaymentServices interface)  
     
     When an object of this subclass is created, it should create a
     corresponding object of the PaymentTransactionRecord
     class.  If necessary, a subclass of the
     PaymentTransactionRecord class may be defined and
     used to suit the needs of specific payment systems. The
     PaymentTransactionRecord uses objects of other
     classes to record information about the transaction. Examples
     are: 
     
Purse class,
     implementing all abstract methods in the Purse
     class.  Please pay attention to pre- and post-conditions defined
     in the javadoc documentation for each method in this class.  If
     you provide and implementation of your own, make sure they
     satisfy these requirements (e.g the startTransaction
     method has such restrictions; see below).
     
  AbcPurse class that extends:
     AccountBasedPurse class.
     PurseManagement
      
      provides a set of methods to
      facilitate the creation and configuration of purses using
      interaction via Tinguin.
      Each adapter will have to provide certain standard methods that
      are used by the PaymentManager and
      PurseManagement classes.  Currently, these are all
      expected from the subclass of the Purse class.  They
      are:
      init() to initialise the purse during
	    startup, and
	setup() to perform configuration of a
	    purse via user interaction.
	    Default implementations are available in the root
	    Purse class.
      Purse subclass need to be
      overridden:
      startTransaction() in the
      Purse class are expected to behave in a particular
      way, as documented in the section on
      PaymentTransactionRecord above.
  semper.util.install package for
      more details on making adapters installable. Each installable
      adapter must come with a Java properties file called
      props.txt. The mandatory properties that are
      required in general are described in the documentation mentioned
      above. The payment block has the following additional mandatory
      properties:
      purseClassName should have the name of the
	    Purse subclass as its value. For example,. the
	    props.txt file of the SET adapter can have the following line:
	    purseClassName ibm.SETAdapter.SETPurse
Installer which implements the
      semper.util.install.ModuleInstallHook
      interface. 
CreatePurse
	    method of the
	    PaymentManager).
	These applications are typically sufficient for most payment systems. In this case, there is no need for any additional special applications. However, if a payment system provides more functionality than the what is assumed by the SEMPER payment service block model, special applications will be necessary to configure, and use such functionality.
PaymentAccessControlStructure
provides a method isAllowed. Adapters can invoke this
method to see if the global configuration permits a proposed
transaction. Of course, adapters can also perform additional checks if
necessary. The recommended use of this facility is as follows:
_acl attribute. E.g.,
      
          this._acl = new PaymentAccessControlStructure ();
      
  PurseServices methods
      (e.g., pay), retrieve the access control handle
      from the corresponding purse and invoke the
      isAllowed method.  E.g.,
      
        Purse this_purse = (Purse) this._tr_rec.getFirstPurseRef().getPurse();
        PaymentAccessControlStructure ac = this_purse.getACHandle();
	if (!ac.isAllowed(this._tr_rec)) {
	  String msg = "User disallowed payment";
	  Log.log (this, Log.ERROR, msg);
	  state.setState(PaymentTransactionState.TS_CANCELLED);
	  // write transaction record to stable storage before we quit
	  try {
	    this._tr_rec.store();
	  }
	  catch (Throwable e) {
	    String nmsg = "Failed to write transaction record to archive: " +
	      e.toString();
	    Log.log (this, Log.ERROR, nmsg);
	    msg = msg + nmsg;
	  }
	 throw new AccessDenied (msg);
	}
      
      
isAllowed method is
controlled by the configuration variable
semper.payment.access-control (also referred to by the constant
PaymentAccessControlStructure.CONFIG_VAR . If this is set
to the string "AskAlways"
(PaymentAccessControlStructure.CONFIG_ASK_ALWAYS),
the user is prompted.  If it is set to the string "AskNever"
(PaymentAccessControlStructure.CONFIG_ASK_NEVER), the
user is not prompted.  The former is the default.
The intent is that commerce layer or some business application can do something like:
          String user_payment_config =
            Configuration.get(PaymentAccessControlStructure.CONFIG_VAR);
	  if (null == user_payment_config) {
            // The user has not set a default configuration;  so we will
            // tell the payment block not to prompt the user.
	    Configuration.put
	      (PaymentAccessControlStructure.CONFIG_VAR,
	       PaymentAccessControlStructure.CONFIG_ASK_NEVER);
	  } else {
            // The user has set the default configuration.  We have no
            // business overriding this!
          }
 The Lifecycle of Purses
A payment system adapter contains a sub-class of the
Purse class. Whenever a new adapter is installed, the
name of the the Purse subclass must be registered with the
PaymentManager using the registerPurseClassName service.
During startup, the PaymentManager will poll each known
purse class to see if it is enabled: i.e. whether a
purse object of this class can be instantiated. Each purse provides a
isEnabled
method using which the PaymentManager can check
if a Purse class is enabled. The official way to
create and delete purses is to use the API provided by the
PaymentManager in the form of the createPurse
and deletePurse services.  
Each purse also provides an initialisation
service. During startup, the PaymentManager
will attempt to initialise each purse. The purses that are
successfully initialised are called active. Inactive
purses cannot be used in any value transfer transaction.
A user can deactivate a purse via the purse management application. The payment manager will not attempt to initialise deactivated purses during startup. Therefore, a deactivated purse will remain inactive (until explicitly reactivated by the user again), and thus will not be available for value transfer transactions.
Purse deletion is an irrecoverable operation.  When a purse is
deleted, all the transaction records associated with that purse are
also deleted.
Before a purse is deleted, the PaymentManager
will attempt to disable it first.
Each Purse class also provides a setup service to
configure purses. This service must take care of all the necessary
configuration before a purse can be used in value transfer
transactions. Purses that can not configured properly should fail
their initialisation.
Finally, the  
     Note that if trusted I/O is required by an object in the payment service
     block during the execution of such a special business application, it
     may have to deal directly with TINGUIN (and not via the access control
     manager).
 
In this section, we give brief examples of usage:
 
Here is what the user does:
 
Simultaneously, the shop does the following:
 
The above assumes that
 
Configuration:
The following configuration variables are understood by the payment
       block:
        
To this end, we define a token-based PurseServices hierarchy rooted at
the TPurseServices
interface. The token-based interface has a
 
The SEMPER model was assumed to be synchronous in that both the
payer and payee is expected to have already started business
sessions and therefore, for example, invoke PurseReferences
class provides a standard and permanent way to refer to purses (in the
absence of persistent storage, java object references are transient).
	 
 Purse Transactions 
For each transaction, there will be a corresponding PaymentTransaction object.
The caller would do something like:
Here are some examples of usage:
	abcTr1 = (AbcTransaction) abcPurse1.startTransaction(<parameters>);
	abcTr1.pay(<parameters>);
	abcTr1.endTransaction();
	abcTr1 = (AbcTransaction) abcPurse1.startTransaction(<parameters>);
	abcTr1.startMicropayment (<parameters>);
	abcTr1.doMicropayment (<parameters>);
	[...]
	abcTr1.doMicropayment (<parameters>);
	abcTr1.stopMicropayment (<parameters>);
        abcTr1.endTransaction();
	state = abcTr1.getState();
or
	abcTr1.abort();
 Protocols 
Initially at least, only a simple negotiation protocol will be
implemented.  Messages in the negotiation protocol will be in the form
of a list of lists.  Each secondary list is used to negotiate the value
of a single parameter (e.g. "payment service name").  The head of this
list will be an object of the MessageListHead class.
It contains the following attributes:
  
The class PurseSelection provides various methods such as
choosePS and requestPSChoice to negotiate
the selection of payment systems.  Further, there are methods for
local selection as well (for example, based on preferences,
or interaction with the user).  Different purse selection
policies can be implemented by combining these methods in different
ways.  A pair of methods selectPayingPurse and
selectReceivingPurse implementing a particular policy
are also provided in the PurseSelection class.
Currently, we plan for synchronous negotiations between two
payment managers.
Later, we may extend this to asynchronous negotiations, and
negotiations between two PaymentTransaction objects.
 Interaction with the User
[to be done]
 Notes 
PurseManagement
     class.
   
     In addition,
     each payment system will come with special business applications to
     create a purse and perform additional system-specific tasks.
      Interactions with Other Blocks 
   
 Issues 
In this section, we list proposed or forthcoming changes to the design
and issues that need to be discussed:
 Using the Payment Service Block 
Transfer Manager in the SEMPER transfer layer is likely to be the
most common user of services from the Payment Service Block.  However,
as mentioned before special Business Applications that manipulate the
configuration of the payment service block will interact directly with
objects in the payment service block.  Also, in principle, there is
nothing to prevent normal Business Applications or the Commerce Layer
to interact directly with these objects as well.
 Simple Payment 
Scenario: A user "Alice" wants to make a payment of 100 PST to a
shop, "Bob Inc.".
The shop is at bob.com.  The user and the
shop have already started a commerce session.  They agree to use a
common external reference string (we assume that this is available in
the variable ext_ref) to identify this session.  They have
also not selected any specific payment mechanisms but would like to
leave it to their respective payment service blocks to negotiate it.
// seller's address
// The port number and path have no relevance -- so we just use placeholders
ComPointAddress seller_addr = new ComPointAddress ("tcp", "bob.com", 0, "");
PaymentEntity seller = new PaymentEntity ("Bob Inc.", seller_addr);
// We don't want to use any specific alias (just the name we have on
// the selected purse)
String my_alias = null;
// We have no preferences about the means of payment
Vector preferred_payment_systems = null;
Vector preferred_purses = null;
// We have no security options
Vector options = null;
// External reference (already agreed upon between payer and payee)
String ext_ref = "order-# 1233";
// Now select a purse -- this involves negotiation with peer
PurseReference chosen_purse_ref = PurseSelection.selectPayingPurse
	(seller, my_alias, amount, preferred_payment_systems,
	 preferred_purses, options, ext_ref);
Purse chosen_purse = chosen_purse_ref.getPurse();
// carry out the payment
PaymentTransaction tr = chosen_purse.startTransaction();
tr.pay(seller, amount, options, ext_ref);
tr.endTransaction();
// our address (PaymentManager.init() had already registered this address
// with the communication manager
// The port number and path have no relevance -- so we just use placeholders
ComPointAddress seller_addr = new ComPointAddress ("tcp", "bob.com", 0, "");
PaymentEntity seller = new PaymentEntity ("Bob Inc.", seller_addr);
// We don't particularly care for the buyer's address since they will open
// a channel to us with the agreed upon "ext_ref"
PaymentEntity buyer = null;
// The rest, as with the buyer side
Vector preferred_payment_systems = null;
Vector preferred_purses = null;
Vector options = null;
String ext_ref = "order-# 1233";
// Now select a purse -- this involves negotiation with peer
PurseReference chosen_purse_ref = PurseSelection.selectReceivingPurse
	(buyer, seller, amount, preferred_payment_systems,
	 preferred_purses, options, ext_ref);
Purse chosen_purse = chosen_purse_ref.getPurse();
// receive the payment
PaymentTransaction tr = chosen_purse.startTransaction();
tr.receivePayment(buyer, amount, options, ext_ref);
tr.endTransaction();
Since these are not yet available, any test program should do the
necessary initialisation by itself.  The test programs
purse
PaymentManager and
    each purse has already been executed.  This is typically done
    by Library.init()
Seller.java and Buyer.java in the
Test directory of the source are examples of such test programs.
 Configuration and Preferences 
Preferences:
      The init() method of the
      PaymentManager> will attempt to load the
      its preference group from the preference manager;  if none
      exists, one will be created with initial defaults.  Each purse
      should also do the same. Currently, the payment manager
       understands the following preferences:
       
	 
       
	      Default:  Prompt the user to break ties.
       
	 
 Default:  English.
	 
 Default:  False.
       Token-based Definitions of Interfaces to Protocols 
In defining the interfaces, we have assumed that the payment block is
responsible for running its protocols: the payment manager carries out
the negotiation protocol and adapters of payment systems take care of
their respective payment protocols. An alternate approach, in the
style of GSS-API, is to define the interface in terms of
tokens. The payment block is still responsible for constructing
and interpreting protocol messages; but the actual communication
between peers is left to the caller.
start<service> method corresponding to every
<service> method in the PurseServices
interface hierarchy. The sub-classes of the
PaymentTransaction will implement the token-based
interface as well.
pay() and
receivePayment() synchronously. With the token-based
interface, we can also support an asynchronous model.
Forthcoming Changes
  
Negotiation class to do this.
   PaymentTransactionRecord class hierarchy similar to
      the Purse class hierarchy (e.g. with model-specific
      intermediate classes)
Miscellany
The payment service block will be in package
semper.payment.
The documentation includes an  index 
and a
 tree depicting the class structure.
Individual payment modules should be in packages like
semper.payment.ecash.  The semper.payment
package is unaware of
the various individual modules.  Each payment module may provide an
"installer/configurator" application which can use the services that
have been already provided,such as
createPurse 
and those in the 
PurseManagement  class as well as any additional
services speicific to that payment module.