Updated July 23 1998
An Educom/IMS working paper
by Brad Cox, Ph.D.

This describes the API of the first three levels of the digital commerce architecture in this figure. This document concentrates on defining an API sufficient to support implementation efforts during 1998. The resulting prototype will provide an experimental framework for considering technocentric and sociocentric design issues including hardware-based metering, encryption, and rules of just conduct. These will be addressed in subsequent versions.
This section summarizes prior sections of this report by identifying the essential elements of the invocation metering and superdistribution backoffice system.

The registration process begins with an SSL-protected browser-based interaction between the customer and the back office. The customer fills in web forms with the information the back office needs to handle financial transactions for that customer and agrees to legally binding rules of just conduct.
The only difference between consumers (such as students) and producers (such as courseware providers) is that producers, in addition to being consumers, have registered a digital product for invocation-based revenue collection. The metering infrastructure empowers every customer to consume and produce digital goods and supports both roles via the same CID.
Customers develop products as usual, the only difference being that an invocation meter is present in the development and testing machine. This is to enable (and charge for) the use of sub components by the tools used by the developer, subcomponents used by the product under test, and to support meter calls from the product itself. Development stage products will typically be tested under a special PID used only for product testing. Other PIDs will be used for post-development versions to reflect that their use is covered by different terms and conditions.
PIDs are issued to producers during a web-based interaction with the back office server at the developer's the local branch. The producer (owner) provides the information that the back office needs to establish ownership (CID) and agrees to rules of just conduct. The same interaction provides the TACA (Terms And Conditions Algorithm) that the back office will use to convert invocation counts to monetary amounts due. A successful interaction concludes with the back office issuing a globally unique (franchise-wide) PID that the owner hard-codes into all meter calls made by this product.
Notice that PIDs uniquely identify a backoffice record and that each record contains precisely one TACA. If a given version of a digital property is to be marketed with different terms and conditions, this will be handled by requesting a distinct PID for each one.
This document will use this shorthand for the concepts described above.
These are all implemented as synonyms for ID. ID is a synonym for the Java String type. There are no restrictions on ID length or content except that each ID must uniquely identify a valid record in the franchise-wide database.
All calls that cannot be completed will respond as follows:
<methodResponse> <fault> <value> <struct> <member> <name>faultCode</name> <value><int>4</int></value> </member> <member> <name>faultString</name> <value><string>Too many parameters.</string></value> </member> </struct> </value> </fault> </methodResponse>
These calls identify the current user, e.g. the top-level account from which revenue will be drawn. These are called by the IMS Session creation/tear down logic. It is a violation of the rules of just conduct to call them otherwise.
These calls are issued by digital property of any granularity to record uses of the property that issues these calls, as identified by PID.
|
void Meter.query(PID id)
<methodCall> <methodName>query</methodName> <params> <param> <value> <string>PID</string> </value> </param> </params> </methodCall> <methodResponse> <params> <param> <value><bool>ok</bool></value> </param> </params> </methodResponse> |
Reports whether this use will be allowed. The meter determines this by determining the CID of the party who will be charged for this use (from the enclosing login or query() record in the cache). It determines the account status from the hashtable that was returned by the backoffice and stored in the cache during the prior send operation. The call returns true if CID is a customer in good standing (as of the last send operation). It returns false if no meter is available or if the account of the owner of the calling object was marked "deny service" during the last upload cycle (non-payment, fraud, etc) (see the send method). |
<methodCall> <methodName>commit</methodName> <params> <param> <value> <string>PID</string> </value> </param> </params> </methodCall> <methodResponse> </methodResponse> |
Commits a usage of product PID into the cache. The backoffice will
use PID's TACA to compute the charge. It will debit this charge against the micro-account
of the CID derived from the immediately enclosing call. If the immediately enclosing
call is a login(CID cid), the derived cid is the cid in the login call. If a query(),
the derived CID is the CID of the owner of the PID in the query() call. The backoffice credits this charge to the micro-account of PID's owner. |
<methodCall> <methodName>flush</methodName> </params> </methodCall> <methodResponse> </methodResponse> |
Sends the cache to the back office and downloads a fresh reading of
the account status of each CID in the current cache from the backoffice server. This call should not be used routinely. It is for the benefit of products with such high value that their owner cannot rely on the normal upload cycle, which relies on cached account status information that can be as much as a month old. Typically, the cache manages its upload cycle automatically, either as the cache fills or according to timing parameters that the backoffice preprogrammed into the meter. High-value products may decide to update the customer's account status before accepting another transaction. Calling flush() provides explicit control over flush frequency. |
The meter communicates with the backoffice via these interfaces. It is a violation of the rules of just conduct to use these calls otherwise.
public class MeterReading { final static byte LOGIN = '{'; final static byte LOGOUT = '}'; final static byte QUERY = '('; final static byte COMMIT = ')'; public byte CODE; public PID pid; }; private java.util.Hashtable Meter.send( MID mid, MeterReading[] meterReadings, ) {} <methodCall> <methodName>send</methodName> <params> <param> <array> <struct> <member> <name>PID</name> <value><string>id</string></value> </member> <member> <name>code</name> <value><char>c</char></value> </member> </struct> </array> </param> </params> </methodCall> <methodResponse> <params> <param> <array> <struct> <member> <name>CID</name> <value><string>id</string></value> </member> <member> <name>status</name> <value><bool>s</bool></value> </member> </struct> </array> </param> </params> </methodResponse> |
This is called by the flush method to transmit the meter's cache to the backoffice and download account
status information. The MeterReadings argument contains the cached meter readings. Returns a hashtable whose keys are the CIDs of all records in this batch of cache and whose values are booleans. The meter stored this table internally to provide values for subsequent query calls. |
Person's browser presents the URL of BID's entry page to the backoffice's web server. The server returns a string containing an html page with forms the person can use to register a new account:
HtmlPage BID.WebServer.entry( URL url, );
The specified backoffice (BID) examines the user-specified information and, if acceptable, returns an html page that discloses the globally-unique CID that will uniquely identify this customer from here on.
HtmlPage BID.Person.register( String salutation, String firstName, String middleName, String lastName, String password, String passwordCopy, String street, String city, String state, String zipCode, String country, String emailAddress, String macroaccountCo, String macroaccountID, String agrees, // see rules of just conduct int expirationMonth, int expirationYear, );
The backoffice may refuse the request for several reasons. It indicates this by throwing a Refused exception with a string containing an html page that describes the reason for the refusal and a telephone number to call to resolve the problem.
Question: This call is written as if accuracy of this information can be determined in real time. If not, this call will have to be revised to support delayed responses, perhaps via email.
Response: On the Register and Edit methods: Presumably you are asking how the back-office should confirm the operation. Since waiting on a separate thread for a delayed response is kind of a drag, especially for non-threaded environments, some call-back/send-back scenario is in order. One way is to for now call this an asynchronous method invocation and push it to the environment to deal with ( i.e., we declare the method as synchronous, and any delay handling, for a slow back-office or an off-line client, must be handled by some run-time service outside of us. That way, somebody creative could create an ansynch method invoke service that uses all sorts of things for its actual transport mechanism. ). Another way is to declare the asynchronous nature outright and provide a callback/notification URI member. It is then up to the back-office to determine the nature of the URI and make the appropriate call ( i.e., if it is a mailto: it sends the confirmation message ( a basic one defined by us ) via e-mail, if it is an iiop:// it sends the confirmation message as a CORBA method invoke ( again a basic one designed by us ). This problem is certainly not unique to your work, so it will be good for anyone involved to brainstorm and watch for other industry solutions.
The person types their identifier and password into the page that initiates an IMS session.
HtmlPage BID.WebServer.startSession( String id; // Customer ID or email address String password; // Customer Password );
The server returns an html page whose content depends on the contents of the id and password provided. If the id isn't recognized by this backoffice, or if the password is incorrect, or if the cid field contains a valid email address, the server interprets the command as a request to email the correct cid and password to the customer.
In other words, if the person provides a correct identifier and password, the person is logged in and thereafter recognized as a specific customer. If the identifier is correct but the password is not, or if the identifier provided is an email address in the backoffice's database, the system interprets this as a sign that this person has either forgotten their identifier, password or both, or is a cracker trying to break into the account. The server handles such cases by emailing the correct identifier and password to the email address that was recorded when the account was established, thereby notifying the customer of possible fraudulent use of their account.
The response to a correct identifier and password is an editable form via which the customer can propose updates to their registration information. The form contains two sections, one for updating registration information and the other a listing of all products owned by this customer. The form contains buttons for submitting registration information changes and for registering products for this customer.
HtmlPage BID.Person.edit( String salutation, String firstName, String middleName, String lastName, String password, // new password String passwordCopy, // repeat new password String agrees, // see rules of just conduct. String street, String city, String state, String zipCode, String country, String emailAddress, String macroAccountCo, String macroAccountID, int expirationMonth, // of macroAccountID int expirationYear, );
The customer view/edit page lists all products owned by this person and provides a button for registering new products.
HtmlPage BID.Person.addProduct(
String CID, // product owner's CID
String Name, // product name
String Description, // product description (is this useful?)
TACA taca, // terms and conditions algorithm
String agrees, // see rules of just conduct
) {}
Note: The type, TACA, is not defined because I do not know how to declare "compiled and executable bytecodes of a function of three arguments returning a financial amount.
Response: On the TACA data type issue. What you are asking for is to have the calling routine pass an object, by value that supports the TACA interface. Who cares how many other interfaces it supports, as long as the Superdistribution Backoffice can instantiate the object and manipulate it via the TACA interface. Since Java passes natively by value, this is not a big deal. Therefore, the interface would look something like this:
public interface TACA
{
AMOUNT taca(
CID cid; // CID of account to be debited
CODE code; // Transaction code
PID pid; // Transaction PID
) {}
public AMOUNT taca(
CID cid; // CID of account to be charged
CODE code; // Transaction code
PID pid; // Transaction PID
) {}
};
The string returned by the addProduct() method is an html page. This page is generated by the server to communicate the PID (Product ID) that the backoffice assigned to this product. The page also explains how to code this PID into the query() and commit() calls of their product's executable code with the usual cautions re: rules of just conduct.
void Meter.query(PID id) throws requestDenied;
void Meter.commit(PID id) {}
Question: Is the product description useful? May be better to gather a narrative description of the TACA or possibly the URL of the product itself. The latter would have to involve a delay because the user will only learn the PID to encode into their product from the server's response to the addProduct() message.
Response: Unresolved
The superdistribution backoffice plays no role with respect to how products are delivered to consumers. The producer is free to deliver products by any means that are capable of transmitting executable code: floppy disks, internet or sneakernet exchanges between students. Such "informal distributions" are not only supported but (if the producer desires) explicitly encouraged. With superdistribution, revenue collection occurs when digital products are used as distinct from when they are acquired.
The session begins with session initiatiation (step 2) and ends with session termination (step #x below). Session initiation stores the current customer's ID in the cache as a login(CID) record.
Software usage commences exactly as in traditional (pay to acquire) systems. The metering logic is involved only in software constructed for pay-to-invoke revenue collection. This is signified by query(PID) and commit(PID) calls immediately surrounding the parts of a software product for which usage is to be charged.
According to the rules of just conduct, the product owner is legally responsible to accurately disclose terms and conditions (e.g. prices) in the free part of each product (readme files, splash screens, etc). The user reads the price, decides to continue, and clicks the UI feature (buttons, etc) to indicate acceptance of the terms and conditions. The software tells the meter that a chargeable event is beginning by calling query(PID pid), where pid is the product id that the owner coded into this property.
void Meter.query(PID id) throws requestDenied;
Notice that the CID to be charged is not explicitly coded in such calls. This is always determined implicitly, by the Meter and not the property, from either the PID of the enclosing Meter.query(PID) call or the CID of the enclosing Meter.login(CID), whichever is nearest. The meter consults the cached Hashtable (returned by the most recent Meter.send() operation) and determines whether further invocations should be allowed by this customer. If so, the call returns normally. If not the call throws a requestDenied exception.
The product continues executing as usual. If the product calls invocation-metered subcomponents, these will issue further Meter.query() and Meter.commit() calls. The backoffice will charge these to the owner of the PID in the enclosing Meter.query(). The customer identified in the top-level Meter.login(CID cid) call is only charged for products they invoke directly.
When the product successfully delivers the service that the user requested, it communicates this fact to the backoffice by issuing a Meter.commit() call
void Meter.commit(PID id) {}
The meter records the commit call into its invocation cache and the product returns control to the user.
When the cache fills (or other triggering criteria that the backoffice installed in the meter, such as a trigger to initiate monthly uploads independently of usage level), the meter initiates a connection to its backoffice, uploads its cache contents, and downloads a Hashtable with the current account status (allow vs. deny further service) for each of the CIDs in the cache.
java.util.Hashtable Meter.send(ID MID, MeterReading[] meterReadings)
The backoffice establishes a loop over the array of MeterReadings as described in the Multigranular Property section of this document. Briefly, this loop invokes the TACA for the PID that is encoded inside each reading. Each TACA transforms its invocation record into a monetary amount. The enclosing loop debits this amount from the enclosing microaccount (e.g. the account of the customer who invoked this property), crediting that amount to the microaccount of the registered owner of the current PID.
Question: See responses to previous questions re: asynchronous calls. This call is drafted under the assumption that this computation can be done in real-time, along with prudent journaling, backups and so forth. If prototyping shows that the uploaded information must be buffered and processed later, this API will have to be changed so that the updated account status HashTable is downloaded as a separate call.
During any current session, the customer can view (and to some extent, to modify, limited by policy matters TBD), their account by simply revisiting the screen that was described above under Step 2: Customer initiates session. The top-level screen provides customer account information (address, telephone number, credit card information) as editable forms, lists any products owned by this, and the customer's current microaccount balance.
The same form provides a Transactions Details button that brings up a separate page, analogous to a monthly credit card statement, that details each credit and debit within this billing cycle.
Session-terminating logic is defined elsewhere in the IMS standard. This logic calls
void Meter.logoff(CID cid) {}
This records a logoff record in the cache.
|
© Copyright 1998 by Educom/IMS |