Secure, light-weight validation of transaction receipt IDs
The Fast JV
Transaction Verification Protocol
The Fast JV Transaction Verification Protocol is used by website scripts to validate transaction receipt IDs.
It is designed to provide access to just the necessary information while minimizing bandwidth usage and maximizing security.
To add support for the Fast JV Transaction Verification Protocol to your affiliate program requires three things:
- A script to respond to validation requests.
- A page where affiliates (and vendors, if your system sells products on behalf of other vendors)
may edit a "shared secret" -- similar to a password -- which is used to verify that requests come from the person they purposrt to come from.
- A page (perhaps that same page where the shared secret is edited) telling people how to configure Fast JV to work with your affiliate program.
The information items they will need are:
- Their affiliate ID as it should be specified in "who" as described below.
- The URL of the script mentioned in #1 above (it is referred to as the "Protocol URL" in Fast JV's control panel).
- A product code separator character,
which can be any single character that will never appear in your product codes as returned in the "Product" element described below.
- Instructions for figuring out the product codes for each product as they will be returned in the "Product" element described below.
Subject to this license
you may download sample code to do these things
(view the source to see how to update it to work with your system).
A request is sent as an HTTP "GET" with three arguments:
- who: the ID of the person requesting the validation.
- transaction: the transaction receipt ID.
- validate: an MD5 checksum used to verify that the person is authorized to request the validation.
The format of "who" and "transaction" are dependent on the system to which the request is sent.
"validate" is the lowercase hexidecimal MD5 hash of a shared secret, the user ID and the transaction ID, each separated by a single space character.
The code to generate the hash in PHP would look something like this (PHP automatically outputs in lowercase hexidecimal format):
$validate = md5( $shared_secret.' '.$who.' '.$transaction );
A sample request might look like this (the MD5 hash is truncated, and many possible request headers are omitted):
GET /Validate.php?who=173&transaction=8243N&validate=15fe...3a8 HTTP/1.1
A failed request:
<?xml version="1.0" ?>
A successful request:
<?xml version="1.0" ?>
Responses are returned as XML documents.
The character set used must be UTF-8.
Unless your product IDs contain accented or multi-byte characters, you shouldn't have to do anything about this
-- virtually all character sets are identical to UTF-8 for unaccented letters, digits, most punctuation, spaces, etc.
The namespace name for the format is http://FastJV.com/Transaction-Verification-Protocol/ns/.
The default namespace must be used for elements specified here (ie. no namespace prefix may be used on core element names).
Additional elements and attributes may be added if they have their own namespace (they must have a namespace prefix).
There is no specific MIME media type for this document format.
I recommend using "application/xml".
The document element is "FastJVVerification".
All element names are case sensitive.
It may contain the child elements listed below.
The order of the child elements has no significance.
The value of Error is one of the following numbers:
The document may contain only one Error element.
- 0: Success (ie. no error)
- 1: Unknown user or validation failed.
Which error occurred is not revealed.
- 2: Transaction not found or is not associated with this user.
Which error occurred is not revealed.
- 3: Internal error -- try again later.
- 4: Invalid request -- required parameter missing.
Status may contain one of the following case sensitive values:
A server may report only "Paid" and "Returned" if it doesn't track "Pending" status.
The document may contain only one Status element.
- Paid: Payment completed
- Pending: Payment submitted, but not completed (eg. an uncleared eCheck)
- Failed: Payment failed (eg. a refused eCheck)
- Returned: Payment reversed (eg. refunded, charged back, etc.)
A unique identifier for the product sold.
The document must contain a separate Product element for each product sold in the transaction
(ie. one for each SKU -- multiple items in a single SKU should not have their own Product elements).
The value of WhoAmI identifies the person whose ID was submitted as "who" in the request, and may be one of the following case sensitive values:
The document may contain only one WhoAmI element.
- Seller: "who" is the seller of the product
- Affiliate: "who" is the affiliate who was credited for the referral
Event contains information about things that happen during the processing of a transaction.
It has two child elements, both of which are required.
The order of the child elements is not significant.
The child elements are:
The document may contain multiple Event elements.
The value of Type may be any of the following:
- Paid: The Event marks the time that a transaction was submitted and immediated considered completed.
- Submitted: The Event marks the time a transaction that didn't immediately become "Paid" was submitted and became "Pending".
- Cleared: The Event marks the time that a "Pending" transaction became "Cleared".
- Failed: The Event marks the time that a "Pending" transaction failed to clear.
- Returned: The Event marks the time that a transaction that had previously been "Paid" or "Cleared" was reversed.
The value of "When" is a date and time stamp in the "date-time" format of RFC 3339.
In addtion to the requirements of RFC 3339:
- an uppercase "T" character must be used to separate the date and time.
- in the absense of a numeric time zone offset, an uppercase "Z" must be present.
- the timestamp should be accurate to at least the minute.
- the timestamp must not contain fractional seconds (ie. there must be no decimal point).
"Error" is required.
If the value of "Error" is "0", "Status", "Product", and "WhoAmI" are also required.
If "Status" is "Paid", at least either a "Submitted" or "Paid" event is required.
If "Status" is "Pending", at least a "Submitted" event is required.
All other events are optional.