Status: XML group, confidential.
There are currently three metallic payment systems fielded in varying degrees of market evolution, with more on the way. Each of these provides approximately the same features, to whit:
With the above five primitives, a full monetary system is possible using the web (HTTP over SSL) as the primary interface for the account owner.
Whilst users tend to access all these primitives, merchant systems such as Intertrader's CashBox, TGC, and the MetalSavings system, tend to use the Spend as the important primitive, with other requirements being met more or less manually.
See the following:
To set down the requirements for an XML interface over which Spends and other primitives can be conducted.
The spend is the most important.
All others can be done manually, to a greater or lesser extent, by a merchant setup.
Others can come later. Concentrating on one will give us a degree of familiarity, and shrink the task down to manageable proportions.
The Spend request must be authenticated.
It's the Money, dude!
Unauthenticated Spends don't make sense. Spends can be authenticated by a number of means:
How this is done is not specified here as yet, although the initial method is probable the standard SSL password and hash trick.
The spend is normally authenticated within the context of the payer. This specification does not exclude payee authentications, neither does it defined what the result of such a request is.
Payee and Payer must be specified as a string.
It is unknown what the format of the account identifiers is likely to be. Both must be present, and probably both must have valid contents (i.e., there is no particular concept of bearer in a spend).
Known systems use integers, email addresses and hashes, but all have a consistent string representation.
The amount must be capable of accepting an integer number of arbitrary length, or an integer of arbitrary length followed by a decimal point followed by an integer number of arbitrary length.
Amounts can be positive, integral quantities or positive decimals, both including zero. Negative can considered to be illegal. No other characters excepting digits and the decimal point are legal.
Zero must be specifically accepted (some payment systems use a zero tranasction as a test).
There is a case for making the comma act as a decimal point, as per European money formats, but in a protocol, this is not likely to be useful.
A spend may be idempotent if and only if a unique spend identifier is provided.
The net is unreliable, caller can crash and burn at any time, and attempt to retry when restarted (and unburnt). This call is equivalent to the first one, and both calls should result in the same transaction being completed once and only once, rather than twice or nonce.
The caller guarantees that each spend that is the same action has the same spend identifier supplied within it. Each repeated request uses the same identifier.
The caller does not guarantee that each repeated request includes the same details. That is, the caller takes her chances on which call has actually gone through. This allows the caller to cancel a previous call in order to determine state, by doing a zero transaction with a previously used (but lost) spend id.
Note that this requirement is optional. It is taken from the Ricardo architecture, where it is pervasive and fundamental, but will not apply to others necessarily.
If the caller supplies the spend identifier, however, the server must provide the idempotency feature, or reject the spend. If the server handles the idempotency feature, and no spend identifier is supplied, then no idempotency is provided.
A type of value string should be passed in each Spend.
Most implementations will need to specify what sort of currency, etc, is to be transferred, as most will implement multi-currency accounts.
It is possible for a payment system to only implement one type of value, so this requirement is a should only. This would be unusual.
In order to express a currency, many different methods have been tried:
The contents of the string should therefore be flexible.
There should be a field holding a user-specified description.
People like to write notes on their payments in order to remind them as to what they were for.
The description should be freeform, with binary or text conversions possible (but encoded / decoded by upper layers).
This set of requirements does not set a limit on length, but different implementations may set such a limit.
An action time may be included.
Some systems support the setting of the action time of the spend, thus making the funds available at that point.
The format of the time is not specified here, but is assumed to be either a Unix time (seconds since 1970) or a Java time (milliseconds since 1970), or, if Date below is included, the seconds since midnight.
Whether there should be separated dates and times at all is a matter for debate, as it complicates the protocol.
An action date may be included.
Some systems support the setting of the action date of the spend, thus making the funds available on that date.
The format of the date is not specified here, as there are many variants.
The time during the day is not defined, unless it is specified in the above Time requirement, in which case it should be seconds after midnight.
Errors must be returned when failure is detected. Error number must be returned, and an explanatory error string may also be returned.
Some errors are ignorable, such as failure of net, whilst others are cause for panic.
Errors would need to be both definate and variable.
In order to cover both types of error, the error return should include an error number indicating a class of error and thus a reasonable range of responses to the caller, as well as a freeform string. Adding a string explanation may be useful for debugging or further explanation.
The type of request, or primitive, must be indicated.
Cannot mix ones modes.
The various primitives should be easily discernable when they come into the server.
There should be two versions, being the overall specification version, and the sub-request version.
The entire format can change, and each request primitive can also evolve independently.
There should be a major specification version number at the earliest moment.
Immediately after identifying the primitive type, there may be a primitive version number. Probably, the request primitive version would only be needed if there were variants within the specification for a particular implementation.
The responses should match the definition as defined by the request. That is, if the response needs to change, it can only change with a new version of request.