PaySwarm 1.0 - Web API

Unofficial Draft 14 December 2011

Editor:
Manu Sporny, Digital Bazaar, Inc.

This document is also available in this non-normative format: diff to previous version.


Abstract

The PaySwarm Web platform is an open web standard that enables Web browsers and Web devices to perform Universal Web Payment. PaySwarm enables the people that create digital content such as blog posts, music, film, episodic content, photos, virtual goods, and documents to distribute their creations through their website and receive payment directly from their fans and customers. The technology is designed to be integrated directly into blogging platforms, content management systems and general purpose websites. The standard can be applied to the entire content distribution lifecycle, from asset description, to product listings, to licenses, contracts and financial transactions. Features include the ability to exchange money, transact individual sales, subscriptions and micropayments.

Status of This Document

This document is merely a public working draft of a potential specification. It has no official standing of any kind and does not represent the support or consensus of any standards organisation.

Table of Contents

1. Introduction

The PaySwarm Web platform is an open web standard that enables Web browsers and Web devices to perform Universal Web Payment. PaySwarm enables the people that create digital content such as blog posts, music, film, episodic content, photos, virtual goods, and documents to distribute their creations through their website and receive payment directly from their fans and customers. The technology is designed to be integrated directly into blogging platforms, content management systems and general purpose websites.

The technology is provided as an open web platform, which is a combination of technology that is patent-free, royalty-free, published in a free specification, using well-defined protocols and other open technologies. The entire PaySwarm standard, like HTML, HTTP, and JavaScript, is an open web platform. Almost every successful Web technology is built and released in this way.

PaySwarm supports Micropayments. The standard assumes that customers do not want to be bothered to reach for their wallet every time they need to spend a couple of cents, or even a couple of dollars. Micropayment in this case, specifically refers to the ability to automatically distribute payments in increments of up to 1/100,000th of a cent to anybody listed in PaySwarm digital contracts.

It is the goal of this specification to create an environment that is friendly to content creators and customers alike. Distribution of digital goods is becoming an increasing part of the Web and therefore compensation for these digital goods must be as easy to perform as downloading the digital goods. The PaySwarm specification works with the architecture of the Web to deliver a solution that is universal across websites, industries and countries.

2. The Conceptual Model

There are three primary participants in a PaySwarm transaction; the buyer, the vendor, and the PaySwarm Authority.

2.1 Identity and Identifiers

In order for a universal payment system to work seamlessly, there must be a universal way of identifying things in the environment. This specification uses Internationalized Resource Identifiers [IRI] to refer to things on the network. These things can be a personal identity (https://example.com/people/bob), financial account information (https://example.com/people/bob/accounts/42), public cryptography keys (https://example.com/people/bob/keys/14), assets, licenses and a variety of other pieces of long-lived information that exists on the Web. By naming these things with long-lived unique identifiers, it becomes possible to create a decentralized but stable universal payment architecture.

2.2 Participants

2.2.1 Buyers

A buyer is an entity that is capable of acquiring the rights to a particular asset via a contract. The entity is typically a person or an organization that would like to view, copy or otherwise utilize the asset that is being acquired.

2.2.2 Vendors

A vendor is the entity providing an asset for sale. Typically, the vendor is the legal owner of the asset that is being listed for sale. Ownership of an asset can manifest in a variety of different forms. Copyright ownership, physical ownership, and sub-leased property or services are just a few of the types of ownership that apply to vendors.

2.2.3 PaySwarm Authorities

A PaySwarm Authority is used to store money, process and store contracts, and transfer monetary amounts between financial accounts. While a PaySwarm Authority may hold a great deal of financial data, they are built with data portability in mind. PaySwarm participants may move their money and purchase history from one authority to another. Data portability is a mandatory part of this specification.

2.3 Commerce Model

2.3.1 Assets

An asset describes a particular item that is provided as a part of a commercial transaction. It is usually an item that can be accessed or acquired on the basis of a sale or rental under the terms of a particular license. Examples of assets include web pages, crowd-funded loans or grants, music files, video streams, use of virtual machines by the hour, 3D printer files for on-demand manufacturing, radio spectrum and many other items that are capable of being transacted.

2.3.2 Licenses

A license is a legal description of a licensee's rights to a particular asset. Licenses are usually included as a part of a contract to express what a buyer may do with the asset that has been purchased.

2.3.3 Listings

A listing describes the combination of an asset that is for sale under a specific license and a set of payment terms that must be fulfilled in order to access the asset. Listings are often published on websites that sell assets via PaySwarm as a way to express wares for sale in a decentralized manner.

2.3.4 Contracts

A contract is the result of a commercial transaction in PaySwarm and contains information such as the listing, the asset that was purchased, the parties involved in the transaction, the license outlining the rights to the asset, and payment information associated with the transaction.

3. Base Technologies

PaySwarm builds on a number of successful Internet and Web technologies. These technologies are introduced in this section.

3.1 Representational State Transfer

REpresentational State Transfer [REST] is the architectural style that underpins the World Wide Web. It consists of a set of constraints to ensure that servers, gateways, proxies and clients may interact in a way that is predictable. Systems that are designed with this architecture in mind are called RESTful systems. PaySwarm is designed to be RESTful by ensuring that the constraints of REST are applied to all transactions performed via PaySwarm systems.

3.2 JavaScript Object Notation for Linking Data

JavaScript Object Notation for Linking Data [JSON-LD] is a lightweight Linked Data format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on the already successful JSON format and provides a way to help JSON data interoperate at Web-scale. If you are already familiar with JSON, writing JSON-LD is very easy. There is a smooth migration path from the JSON you use today, to the JSON-LD you will use in the future. These properties make JSON-LD an ideal Linked Data interchange language for JavaScript environments, Web services, and JSON document-based databases.

3.3 The Advanced Encryption Standard

The Advanced Encryption Standard (AES) [FIPS-197] is a world standard adopted by the United States Government and used to secure a vast majority of the commercial transactions over the Internet via OpenSSL. Since much of the data exchanged over PaySwarm participants is sensitive, it is important that a strong cryptography suite is utilized to digitally sign and transfer the messages.

3.4 HTML+RDFa

Web sites are largely implemented on top of the HyperText Markup Language (HTML). This format is known to be fairly easy to author and publish on the Web. In addition to being easy to publish, it is also important that data published via HTML can be easily read by machines without placing an undue burden on Web authors. Publishing structured data in a decentralized manner also requires a language that is capable of being both expressive and deterministic. The Resource Description Framework in attributes [RDFA-CORE] extends HTML [HTML-RDFA] to allow structured data to be expressed via HTML, but in a way that is easy for Web developers to author.

4. Communication

All communication between software operating under this specification is intended to perform according to REST [REST] principles. Additionally, since PaySwarm implements a financial system, the security of messages and data is of paramount importance. A security breach at certain points during the algorithms described in the following sections may introduce attack vectors that criminals could utilize to steal from or cause financial harm to the systems or people involved. However, excellent security does not have to come at a high cost. PaySwarm has been designed so that many parts of the system can be implemented in a way that does not incur significant effort, recurring costs, or financial outlay.

4.1 Requests and Responses

This specification requires that a PaySwarm Authority have a trusted security certificate and operate many of the API services over Transport Layer Security version 1.0 or later. Unless otherwise specified, all API requests must be made over HTTPS to the PaySwarm Authority.

An invalid certificate or TLS error or any kind must result in the API call exiting immediately and not performing the requested action. All API requests sent to the PaySwarm Authority on behalf of a participant of the network that results in any modification to an internal database must be digitally signed by the requestor using the steps provided in the Request Signature Algorithm. All responses to network participants from a PaySwarm Authority must be encrypted according to the steps provided in the Response Encryption Algorithm.

4.2 Communication Terms

The following terminology is used to describe concepts used to generate and secure messages in the system. Many of these terms are borrowed from public/private key cryptography. A more complete description of public/private cryptography can be found in The Advanced Encryption Standard [AES].

message
A JSON-LD byte stream that is used to convey a request or a response in the system.
public key
A cryptographic mechanism that can be used to verify digital signatures or encrypt small messages such that only the software with access to the corresponding private key can decrypt the small message.
private key
A cryptographic mechanism that can be used to generate digital signatures and decrypt encrypted data.
signed message
A type of message that has a digital signature attached to it, generated using a private key, that is verifiable and incredibly difficult to forge.
intermediate value
A cryptographic input to an encryption algorithm. This is typically a 16-byte value in AES.
encrypted message
A type of message that has been obfuscated using a public key, which is incredibly difficult to decode by any person except for the one that holds the associated private key.

4.3 Request Signature Algorithm

The following algorithm ensures that the originator of an API call can be verified as long as the public key can be retrieved by the receiver. A message is provided as input and, using a private key and a public key IRI, a signed message is produced as output.

  1. Remove any sec:signature key-value pair from the top-level of the message. Copy the message to the signed message.
  2. Generate the normalized message by normalizing the message according to the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
  3. Generate the signature value by:
    1. Create a timestamped message and initialize it to the emtpy string. Generate an ISO8601 combined date and time string containing the current date and time, accurate to at least one second, in Universal Time Code format. For example: 2011-09-23T20:21:34Z. Append the combined date and time string to the timestamped message. Append the normalized message to the timestamped message.
    2. Digitally sign the timestamped message using the private key and then base-64 encode the resulting value. The resulting base-64 encoded string is the signature value.
  4. Add a sec:signature key to the signed message with a JSON object containing the following key-value pairs:
    @type
    sec:JsonLdSignature
    dc:created
    The string value of the combined date and time string generated by this algorithm.
    sec:responseToken
    A string value that will be encoded in the encrypted response to the requesting agent. It is recommended that this value is a session identifier that is associated with the user agent that initiated the request, plus a hyphen, plus a cryptographically secure random string used as a one-time pad. For example, jf793ksj72jkf-78p82qpj87dnd2f839. See The Response Token section to understand more about how this value is used to prevent replay attacks and its accepted limitations.
    sec:publicKey
    The value of the input public key IRI.
    sec:signatureValue
    The value of the signature value generated by this algorithm.

The following example shows an input message and the resulting signed message:

*** message
{
   "@context": "http://purl.org/payswarm/v1",
   "dc:title": "Hello World!"
}

*** signed message
{
   "@context": "http://purl.org/payswarm/v1",
   "dc:title": "Hello World!",
   "sec:signature":
   {
      "@type": "sec:JsonLdSignature",
      "dc:created": "2011-09-23T20:21:34Z",
      "sec:signer": "http://payswarm.example.com/i/john/keys/5",
      "sec:signatureValue": "OGQzNGVkMzVm4NTIyZTkZDYMmMzQzNmExMgoYzI43Q3ODIyOWM32NjI="
   }
}
        

4.4 Request Signature Verification Algorithm

In order to ensure a secure communication environment the following algorithm should be used to verify all request signatures in the system. A signed message is provided as input and an indication of whether the signature is valid or a forgery is produced as output.

  1. Generate the original message by copying the signed message and removing the sec:signature value from the original message.
  2. Generate the original normalized message by normalizing the original message according to the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
  3. Verify the original signature value:
    1. Generate the original timestamped message by setting its value to the value of the dc:created key in the signed message. Append the original normalized message to the original timestamped message.
    2. Retrieve the PEM-encoded public key from the public key IRI provided in sec:signer value. The public key may also be retrieved from a cache. ???Verify the original nonced message using the public key???
      We need to be more explicit about what is happening here.

4.5 Response Encryption Algorithm

The following algorithm ensures that a message intended for a particular recipient can be obfuscated such that only the intended recipient can read the message. A message is provided as input and, using a public key and a public key IRI, a encrypted message is produced as output.

  1. Generate a cryptographically secure symmetric key that is exactly 16 bytes in length.
  2. Generate a cryptographically secure initialization vector that is exactly 16 bytes in length.
  3. Generate the encrypted initialization vector by using the public key to encrypt the initialization vector.
  4. Generate the encrypted data by encrypting the message using the RSA with AES 128-bit Cyclic Block Chaining algorithm, using the symmetric key and the initialization vector generated previously in this algorithm.
  5. Generate the encrypted symmetric key by using the public key to encrypt the symmetric key.
  6. Generate the encrypted message by creating a JSON object containing the following key-value pairs:
    @type
    sec:EncryptedMessage
    sec:data
    The base-64 encoded value of the encrypted data.
    sec:encryptionKey
    The base-64 encoded value of the encrypted key.
    sec:cipher
    The value rsa-aes-128-cbc.
    sec:iv
    The base-64 encoded value of the encrypted initialization vector.
    sec:publicKey
    The public key IRI associated with the public key that was used to encrypt the symmetric key in this algorithm.

The following example shows a typical input message and what an encrypted message looks like when generated using the algorithm above.

*** message
{
   "@type": "ps:Preferences"
   "com:currency": "USD",
   "com:minimumAmount": "0.05",
   "com:maximumRate": "10.0",
   "com:destination": "https://example.com/people/manu/accounts/article-sales",
   "sec:publicKey": "http://payswarm.example.com/i/manu/keys/23",
   "ps:license": "http://purl.org/payswarm/licenses/blogging",
   "ps:licenseHash": "961ec496092bf6ee08d6255d96069b5186332689",
}

*** encrypted message
{
   "@type": "sec:EncryptedMessage",
   "sec:data": "VTJGc2RHVmtYMThOY3h2dnNVN290Zks1dmxWc3labi9sYkU0TGloRTdxY0dpblE4OHgrUXFNNi9l\n↩
a1JMWjdXOApRSGtrbzh6UG5XOFo3WWI4djJBUG1abnlRNW5CVGViWkRGdklpMEliczNWSzRQTGdB\n↩
UFhxYTR2aWFtemwrWGV3Cmw0eFF4ancvOW85dTlEckNURjMrMDBKMVFubGdtci9abkFRSmc5UjdV\n↩
Rk55ckpYalIxZUJuKytaQ0luUTF2cUwKcm5vcDU1eWk3RFVqVnMrRXZZSkx6RVF1VlBVQ0xxdXR4\n↩
L3lvTWd4bkdhSksxOG5ZakdiekJxSGxOYm9pVStUNwpwOTJ1Q0Y0Q2RiR1NqL0U3OUp4Vmh6OXQr\n↩
Mjc2a1V3RUlNY3o2Z3FadXZMU004KzRtWkZiakh6K2N5a1VVQ2xHCi9RcTk3b2o3N2UrYXlhZjhS\n↩
ZmtEZzlUeWk3Q2szREhSblprcy9WWDJWUGhUOEJ5c3RiYndnMnN4eWc5TXhkbHoKUkVESzFvR0FJ\n↩
UDZVQ09NeWJLTGpBUm0zMTRmcWtXSFdDY29mWFNzSGNPRmM2cnp1Wko0RnVWTFNQMGROUkFRRgpB\n↩
bFQ0QUpPbzRBZHpIb2hpTy8vVGhNOTl1U1ZER1NPQ3graFAvY3V4dGNGUFBSRzNrZS8vUk1MVFZO\n↩
YVBlaUp2Ckg4L1ZWUVU4L3dLZUEyeTQ1TzQ2K2lYTnZsOGErbGg0NjRUS3RabktFb009Cg==",
   "sec:encryptionKey": "uATtey0c4nvZIsDIfpFffuCyMYGPKRLIVJCsvedE013SpEJ+1uO7x6SK9hIG9zLWRlPpwmbar2bt\n↩
gTX5NBzYC5+c5ZkXtM1O8REwIJ7wmtLdumRYEbr/TghFl3pAgXhv0mVt8XZ+KLWlxMqXnrT+ByNw\n↩
z7u3IxpqNVcXHExjXQE=",
   "sec:cipher": "rsa-aes-128-cbc",
   "sec:iv": "vcDU1eWTy8vVGhNOszREhSblFVqVnGpBUm0zMTRmcWtMrRX==",
   "sec:publicKey": "http://payswarm.example.com/i/manu/keys/23"
}
        

4.6 Response Decryption Algorithm

The following algorithm is used to decrypt an encrypted response. The input is an encrypted message and the result is the original unencrypted message.

  1. Generate the decryption key by base-64 decoding the sec:encryptionKey value and using the private key associated with the public key IRI in sec:publicKey to decrypt the base-64 decoded value.
    Refer to the exact algorithm that is used to do the decryption in the AES spec.
  2. Generate the intermediate value by base-64 decoding the sec:iv value and then using the private key associated with the public key IRI in sec:publicKey to decrypt the base-64 decoded value.
  3. Generate the original unencrypted message by applying the sec:cipher to the sec:data value. Use the decryption key and intermediate value generated in this algorithm as inputs to the cipher algorithm.

4.7 Security Considerations

Since this specificationd describes a financial system, the security of the communication in the system is of utmost importance. The following section describes security considerations that developers implementing this specification should be aware of in order to create secure software.

4.7.1 The Response Token

The sec:responseToken mechanism is used in order to prevent replay attacks, but implementers must be aware that it is not capable of preventing man-in-the-middle attacks. Only a full end-to-end encryption channel is capable of accomplishing that feat and if implementers are concerned about man-in-the-middle attacks, they are strongly advised to run all callbacks over HTTPS.

While implementation of the response token to prevent replay attacks is left as an exercise to the developer, it is advised that it is treated as a one-time token. That is, when a response token is sent from one peer to another peer, the sender must note the response token in an internal database. When the response token is returned in an encrypted message, the response token must be deleted from the internal database so all successive calls using the same response token will fail. This simple behavior prevents replay attacks and is simpler to implement than a security nonce.

To further increase security, it is advised that the response token is tied to the originating client's IP address in some way. The resulting response callback should be executed by the same client's IP address, thus many classes of man-in-the-middle attacks can be prevented, requiring quite a sophisticated attack in order to hijack the response. Note that the hijacker will not be able to modify the response, but merely callback-jack the response. The result of the callback-jack would be fairly benign in most cases - gaining access to an article that was purchased by the original user agent that initiated the request. The original purchaser will still have access to the article, so the only damage done is the ability to view or download an article as someone else. If this is a concern to implementers, they are advised to purchase a valid SSL certificate and ensure that all callbacks to their site occur over SSL.

5. The Registration Process

The registration process is necessary in order to specify details about the participants in a PaySwarm transaction.

5.1 Registration Terms

There are a number of terms that are used during the course of the registration process.

user agent
The piece of software operating on behalf of the buyer. This is typically a Web Browser, but could be some other piece of Web-aware automated software acting on behalf of a person.
publishing agent
A software agent acting on behalf of the vendor that publishes assets for sale. Typically, this is blogging software, content distribution software, online merchant software or a Web-based game.
configuration service
A Web service that is used to publish the public Web service end-points and other public configuration information for a PaySwarm Authority. A PaySwarm Authority must publish this service at a top-level IRI named payswarm-v1-config. The document must be available in JSON-LD compacted form and must use the http://purl.org/payswarm/v1 JSON-LD context. The following keys must be present in the published document; ps:publicKeyService, ps:licenseService, and ps:contractsService.
public key registration service
An interactive Web service used to register PEM-encoded X.509 public keys with the PaySwarm Authority.
license service
A utility service is used by a publishing agents to retrieve license hashes, which are used when listing assets for sale.
contracts service
The contract service is used to process purchases by submitting and retrieving digital contracts.

5.2 Buyer Registration

In order for a buyer to transact, they must have an account on a PaySwarm Authority. Typically, this account must also contain a positive amount of funds that may be used to acquire goods or services. How this account is created and funds are deposited are outside of the scope of this specification. However, the end result of this sign up process must result in the following items being created for the buyer:

  1. An identity IRI that will be used to identify the entity that is transacting. For example: https://example.com/people/jane.
  2. A financial account IRI that is associated with the identity IRI above. For example: https://example.com/people/jane/accounts/primary.
  3. A positive amount of funds in the financial account mentioned above.

5.3 Vendor Registration

In order for a vendor to transact, they must have an account on a PaySwarm Authority. How this account is created and managed is outside of the scope of this specification. However, the end result of this sign up process must result in the following items being created for the vendor:

  1. An identity IRI that will be used to identify the entity that is transacting. For example: https://example.com/people/manu.
  2. A financial account IRI that is associated with the identity IRI above. For example: https://example.com/people/manu/accounts/article-sales.

Since all assets and listings are digitally signed, a public key must be registered for the vendor with the PaySwarm Authority. This is typically performed by the publishing agent software that is publishing the assets and listings for sale on behalf of the vendor. The registration is accomplished by executing the following algorithm:

  1. The publishing agent generates and stores a public/private keypair that will be used to associate the publishing agent with the vendor.
  2. The publishing agent retrieves the PaySwarm Authority configuration from the configuration service IRI.
    1. The configuration service IRI is generated by concatenating a base IRI for the PaySwarm Authority, such as https://example.com/ with the payswarm-v1-config suffix. For example, the previous PaySwarm Authority IRI concatenated with the configuration suffix would result in the following configuration service IRI: https://example.com/payswarm-v1-config.
    2. An HTTPS GET is performed on the configuration service IRI with the HTTP Accept header set to application/ld+json; form=compacted. The PaySwarm Authority must respond with a compacted JSON-LD document using the context specified at http://purl.org/payswarm/v1.
    3. The result must be a JSON-LD document containing a flat set of key-value pairs defined in the configuration service section above.
  3. The publishing agent initiates an HTTP 302 redirect for the user agent. An HTTPS GET request is performed to the public key registration service IRI with the addition of two IRI query parameters. The first parameter, public-key, is the URL-encoded X.509 PEM-encoded public key. The second parameter, registration-callback, is the URL-encoded registration callback service IRI for the publishing agent.
  4. The PaySwarm Authority associates the publishing agent with the vendor based on the provided public key. Note that this process must authenticate the vendor via a login process if the vendor does not have an active login session. Other configuration steps may be performed at this stage, including the specification of defaults for the particular publishing agent.
  5. The PaySwarm Authority specifies a set of publishing agent configuration values and encrypts the message according to the steps outlined in the Response Encryption Algorithm section. The result is sent back to the registration-callback IRI via a POST initiated by the user agent.
    1. The following configuration values must be included in the JSON-LD response to the publishing agent; com:currency, com:minimumAmount, com:maximumRate, com:destination, sec:publicKey, ps:license and ps:licenseHash.
    2. The JSON-LD response is compacted and encrypted using the public key associated with the registration request according to the algorithm defined in Response Encryption Algorithm.
    3. The encrypted response is transmitted to the registration-callback via an HTTP POST request that is initiatited by the user agent. This is most commonly accomplished by having the PaySwarm Authority generate an HTML form that can be submitted to the publishing agent when a form submission button is clicked via the user agent.
    4. The publishing agent decrypts the base-64 encoded byte stream, extracts the configuration values and stores each value for use during the latter parts of the publishing and purchase process.

The example below shows the full protocol-level exchange between the publishing agent and the PaySwarm Authority. For the sake of brevity, not every optional parameter is included, just the bare minimum necessary to perform the vendor registration.

--------------------------------- Step #1 -----------------------------------

*** Request: user agent -> publishing agent

POST /register-blog HTTP/1.1
Host: publisher.example.org
Content-Length: 47
Content-Type: application/x-www-form-urlencoded

payswarm-authority=http%3A%2F%2Fpayswarm.example.com%2F

*** publishing agent generates and stores public/private keypair

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDptIkqrXhx7YVGsBZ5fY/Lz0il
0LXJrhUY43V/lLWdRf7JXY6tcgA5AmwNGZtJRyH79QXCJn+BAHUtl6gX2gvjs8N2
B5u4m0LtXyaFWtbQV9+hY3JRLOBiydPeXLgsnLwKiJ9v4CNXSNA5wT8vYGXiqq0B
US89y0M909ZTj2zDQwIDAQAB
-----END PUBLIC KEY-----

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDptIkqrXhx7YVGsBZ5fY/Lz0il0LXJrhUY43V/lLWdRf7JXY6t
cgA5AmwNGZtJRyH79QXCJn+BAHUtl6gX2gvjs8N2B5u4m0LtXyaFWtbQV9+hY3JR
LOBiydPeXLgsnLwKiJ9v4CNXSNA5wT8vYGXiqq0BUS89y0M909ZTj2zDQwIDAQAB
AoGALNmBrVgHEk4T0qH+XihTjThlZ7Tq/h5TXChipy5BwEHriHdU50JGeqpVVBpC
68gj5Hd8OGss8vPEiRBeqN0mhJlRaX5ijyFp2n8+7DhfOIVhCd1MXCGQPTrdXIo5
OOQECSplnALZfKr0VC4TBeW+oUZGMoG4rRSM5DfyPFJtlzECQQD8DkWBkhRsP1An
3qfZR8oUkvbaVg9jsCNvoBazYSS3OhsZ96ZSTyf9hJn28wGJmShuZA2eL5XjuTY4
m0fQDhj5AkEA7VzAqKOx5zlFTWXMIzn29uB59m4yJ7UwCyc7tisQA16I8B2HzJzZ
saipkpU2RUYaBrjtWaiVNtyXvZ7mccJpGwJBAMyE4/8bwfiHcwm2z+ktKBqDmUtW
E0ynKkmz01ef1kPaIQ1z9f/JfMBnrOpFCZVVsgnIo4gcQnox2X4a+S0nkzkCQBre
xCSTG2Gclx7S5lAakL2T3dqq0Nyz4zNwBo9xwodPHVtpTGU6YF5/RGsGnzUqYWnf
Z2cd8X5bbIYXxeic5H8CQQCcBOtOdrq9FXsEnyhG5gQXvGdxEAmM2eUs1g8E8kgx
KBTHOaBRQMgvjsdA/obrs7D0HrEbQqGOy7JBYGWZTsiI
-----END RSA PRIVATE KEY-----

--------------------------------- Step #2 -----------------------------------

*** Request: publishing agent -> PaySwarm Authority

GET /payswarm-v1-config HTTP/1.1
Host: payswarm.example.com
Accept: application/ld+json,*/*;q=0.1

*** Response: publishing agent <- PaySwarm Authority

HTTP/1.1 200 OK
Connection: close
Content-Length: 6075
Content-Type: application/ld+json
Date: Wed, 21 Sep 2012 22:30:16 GMT
Host: payswarm.example.com
Server: Apache/2.2.19 (Debian)

{
   "@context": "http://purl.org/payswarm/v1",
   "@subject": "http://payswarm.example.com/i/authority",
   "ps:registrationService": "http://payswarm.example.com/api/v1/applications",
   "ps:publicKeyService": "http://payswarm.example.com/api/v1/keys",
   "ps:licenseService": "http://payswarm.example.com/api/v1/licenses",
   "ps:contractsService": "http://payswarm.example.com/api/v1/contracts"
}

--------------------------------- Step #3 -----------------------------------

*** Redirect: user agent <- publishing agent

HTTP/1.1 303 See Other
Location: https://payswarm.example.com/api/v1/keys?public-key=↩
-----BEGIN+PUBLIC+KEY-----%0A↩
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDptIkqrXhx7YVGsBZ5fY%2FLz0il%0A↩
0LXJrhUY43V%2FlLWdRf7JXY6tcgA5AmwNGZtJRyH79QXCJn%2BBAHUtl6gX2gvjs8N2%0A↩
B5u4m0LtXyaFWtbQV9%2BhY3JRLOBiydPeXLgsnLwKiJ9v4CNXSNA5wT8vYGXiqq0B%0A↩
US89y0M909ZTj2zDQwIDAQAB%0A↩
-----END+PUBLIC+KEY-----↩
&registration-callback=http%3A%2F%2Fpublisher.example.org%2Fregistration-complete?nonce=pn9sueh43jefa
Content-Type: text/html
Content-Length: 174

<html>
 <head>
  <title>Identity Registration</title>
 </head>
 <body>
  <h1>Public Key Registration</h1>
   <p>You must now go to your PaySwarm Authority and 
    <a href="http://payswarm.example.com/api/v1/keys?public-key=↩
-----BEGIN+PUBLIC+KEY-----%0A↩
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDptIkqrXhx7YVGsBZ5fY%2FLz0il%0A↩
0LXJrhUY43V%2FlLWdRf7JXY6tcgA5AmwNGZtJRyH79QXCJn%2BBAHUtl6gX2gvjs8N2%0A↩
B5u4m0LtXyaFWtbQV9%2BhY3JRLOBiydPeXLgsnLwKiJ9v4CNXSNA5wT8vYGXiqq0B%0A↩
US89y0M909ZTj2zDQwIDAQAB%0A↩
-----END+PUBLIC+KEY-----↩
&registration-callback=http%3A%2F%2Fpublisher.example.org%2Fregistration-complete?nonce=pn9sueh43jefa">
    register your identification information</a> 
    there.</p>
 </body>
</html>

--------------------------------- Step #4 -----------------------------------

*** This step consists of a series of UI interactions and is thus not
*** specified in this specification.

--------------------------------- Step #5 -----------------------------------

*** The PaySwarm Authority creates a configuration object to return back
*** to the publishing agent

{
   "@type": "ps:Preferences"
   "com:currency": "USD",
   "com:minimumAmount": "0.05",
   "com:maximumRate": "10.0",
   "com:destination": "https://example.com/people/manu/accounts/article-sales",
   "sec:publicKey": "http://payswarm.example.com/i/manu/keys/23",
   "ps:license": "http://purl.org/payswarm/licenses/blogging",
   "ps:licenseHash": "961ec496092bf6ee08d6255d96069b5186332689",
}

*** The configuration object is then encrypted and sent to the 
*** registration-callback specified in the registration request above.

POST registration-complete?nonce=pn9sueh43jefa HTTP/1.1
Host: publisher.example.org
Content-Length: 47
Content-Type: application/ld+json

{
   "@type": "sec:EncryptedMessage",
   "sec:data": "VTJGc2RHVmtYMThOY3h2dnNVN290Zks1dmxWc3labi9sYkU0TGloRTdxY0dpblE4OHgrUXFNNi9l\n↩
a1JMWjdXOApRSGtrbzh6UG5XOFo3WWI4djJBUG1abnlRNW5CVGViWkRGdklpMEliczNWSzRQTGdB\n↩
UFhxYTR2aWFtemwrWGV3Cmw0eFF4ancvOW85dTlEckNURjMrMDBKMVFubGdtci9abkFRSmc5UjdV\n↩
Rk55ckpYalIxZUJuKytaQ0luUTF2cUwKcm5vcDU1eWk3RFVqVnMrRXZZSkx6RVF1VlBVQ0xxdXR4\n↩
L3lvTWd4bkdhSksxOG5ZakdiekJxSGxOYm9pVStUNwpwOTJ1Q0Y0Q2RiR1NqL0U3OUp4Vmh6OXQr\n↩
Mjc2a1V3RUlNY3o2Z3FadXZMU004KzRtWkZiakh6K2N5a1VVQ2xHCi9RcTk3b2o3N2UrYXlhZjhS\n↩
ZmtEZzlUeWk3Q2szREhSblprcy9WWDJWUGhUOEJ5c3RiYndnMnN4eWc5TXhkbHoKUkVESzFvR0FJ\n↩
UDZVQ09NeWJLTGpBUm0zMTRmcWtXSFdDY29mWFNzSGNPRmM2cnp1Wko0RnVWTFNQMGROUkFRRgpB\n↩
bFQ0QUpPbzRBZHpIb2hpTy8vVGhNOTl1U1ZER1NPQ3graFAvY3V4dGNGUFBSRzNrZS8vUk1MVFZO\n↩
YVBlaUp2Ckg4L1ZWUVU4L3dLZUEyeTQ1TzQ2K2lYTnZsOGErbGg0NjRUS3RabktFb009Cg==",
   "sec:encryptionKey": "uATtey0c4nvZIsDIfpFffuCyMYGPKRLIVJCsvedE013SpEJ+1uO7x6SK9hIG9zLWRlPpwmbar2bt\n↩
gTX5NBzYC5+c5ZkXtM1O8REwIJ7wmtLdumRYEbr/TghFl3pAgXhv0mVt8XZ+KLWlxMqXnrT+ByNw\n↩
z7u3IxpqNVcXHExjXQE=",
   "sec:cipher": "aes-128-cbc",
   "sec:iv": "vcDU1eWTy8vVGhNOszREhSblFVqVnGpBUm0zMTRmcWtMrRX==",
   "sec:publicKey": "http://payswarm.example.com/i/manu/keys/23"
}

5.4 Security Concerns for Registration

6. The Purchase Process

The simplest purchase process includes four distinct steps; publishing an asset, publishing a license, publishing a listing and performing the purchase. Typically, the vendor publishes the asset description and the listing. Anyone may publish a license that is used in a listing. The purchase is performed via a PaySwarm Authority.

While it is possible to express assets, licenses, and listings on the Web in many different machine-readable formats, to ensure that implementations do not become more complicated than necessary, all assets, licenses and listing must be expressed in HTML+RDFa [HTML-RDFA] format. The example markup that is expressed in many of the following sections below will use [JSON-LD] for the sake of brevity. In many cases, the information expressed via JSON-LD is expected to be express via RDFa on a Web page. There is a clear mapping from RDFa to JSON-LD, so the data expressed in the sections below can be losslessly expressed via RDFa on an HTML Web page.

6.1 Publishing an Asset

An asset describes a particular item that is provided as a part of a commercial transaction. It is usually an item that can be accessed or acquired on the basis of a sale or rental under the terms of a particular license. Examples of assets include web pages, music files, video streams, virtual machines intended to be paid for by the CPU-hour, 3D printer files for on-demand manufacturing, radio spectrum and crowd-funded loans and grants.

The following example describes a web page asset with the title "PaySwarm in Practice". The article was created by "Digital Bazaar, Inc." and the information in the asset is valid from November 28th, 2010 to November 28th, 2011. The asset is digitally signed by the organization providing it and thus can be cached, stored and then presented to someone else in a manner that is verifiable by the receiving party.

{
   "@context": "http://purl.org/payswarm/v1",
   "@subject": "http://example.org/articles/1#asset",
   "@type": ["ps:Asset", "ps:WebPage"],
   "dc:title": "PaySwarm in Practice",
   "dc:description": "This article covers how to use PaySwarm on your Website.",
   "dc:creator": 
   {
      "@type": "foaf:Organization",
      "foaf:name": "Digital Bazaar, Inc.",
   }
   "ps:contentUrl": "http://example.org/articles/1",
   "ps:validFrom": "2010-11-28T00:00:00Z",
   "ps:validUntil": "2011-11-28T00:00:00Z"
   "sec:signature": 
   {
       "@type": "sec:JsonLdSignature",
       "dc:created": "2010-11-28T00:00:00Z",
       "sec:signer": "https://payswarm.example.com/i/digital-bazaar#key-5",
       "sec:signatureValue": "OWM3YzI4OGQzNGVkMzV...IyZTk2MzQzNmExMgo="
   }
}
        

In order to publish this asset on a Web page, a vendor must mark the data up in RDFa and place it into an HTML file. For example, assume that the following file is served from the http://example.org/articles/1-purchase IRI:

<html>
 <head>
   <title>Buy: PaySwarm in Practice</title>
 </head>
 <body prefix="dc: http://purl.org/dc/terms/ 
               foaf: http://xmlns.com/foaf/0.1/ 
               ps: http://purl.org/payswarm#
               sec: http://purl.org/security#
               xsd: http://www.w3.org/2001/XMLSchema#">

   <article about="http://example.org/articles/1#asset" typeof="ps:Asset ps:WebPage">
     <h1 property="dc:title">PaySwarm in Practice</h1>
     by
     <h2 property="dc:creator" typeof="foaf:Organization">
       <span property="foaf:name">Digital Bazaar, Inc.</span>
     </h2>

     <p property="dc:description">This article covers how to use PaySwarm on your Website.</p>
     <a property="ps:contentUrl" href="http://example.org/articles/1">permalink</a>
     
     <input type="button" onclick="doPurchase();">Purchase Access to the Article</input>
     
     <input type="button" onclick="toggleDetails();">Details</input>
     <div class="article-details hidden-by-default">
       This asset publication is valid from
       <span property="ps:validFrom" content="2010-11-28T00:00:00Z" datatype="xsd:dateTime">today</span>
       until a 
       <span property="ps:validTo" content="2011-11-28T00:00:00Z" datatype="xsd:dateTime">year from today</span>.
       <div property="sec:signature" typeof="sec:JsonLdSignature">
         Signed on 
         <span property="dc:created" content="2010-11-28T00:00:00Z" datatype="xsd:dateTime">November 28th 2010</span>
         by
         <a property="sec:signer" href="https://payswarm.example.com/i/digital-bazaar#key-5">Digital Bazaar</a>:
         <span property="sec:signatureValue">OWM3YzI4OGQzNGVkMzV...IyZTk2MzQzNmExMgo=</span>
       </div>
      </div>
   </article>
 </body>
</html>
        

It may not initially be clear why an asset would need to be digitally signed. There are two major reasons that assets must be digitally signed in order to take part in a secure financial system. The first is to ensure, from a legal standpoint, that the person or organization claiming ownership over the asset is clear. The second is to ensure that forgery cannot occur on any of the asset information claimed by the owner of the asset. For example, if the asset were listed on an non-secure HTTP-based Web site, the information could be easily modified in transit.

The example above demonstrates how the information expressed as [JSON-LD] earlier in this section can be expressed as HTML+RDFa [HTML-RDFA]. The rest of this specification will not express information using both mechanisms, but will use [JSON-LD] markup for the sake of brevity even if the information being expressed is meant to be expressed in RDFa.

6.2 Publishing a License

A license is a legal description of a licensee's rights to a particular asset. Licenses are usually included as a part of a contract to express what a buyer may do with an asset that has been purchased. A license can include a number of rights bestowed upon the licensesee as well as further limitations on those rights. For example, how an asset may be re-broadcast, how often a digital asset may be physically reproduced, what an asset may specifically not be used for, and liability limitations when using the asset are but a few of the rights and obligations expressible via a license.

The following example describes a very simple license for personal use.

{
   "@context": "http://purl.org/payswarm/v1",
   "@subject": "http://payswarm.example.com/licenses/personal-use",
   "@type": "ps:License",
   "dc:format": "text/html",
   "ps:licenseTemplate": "This personal use license allows you to save the 
      purchased asset onto any device that you own for your personal enjoyment
      and make up to <span property=\"ex:physicalCopies\" /> printed
      copies of the work for personal use."
   "ps:licenseTerms": 
   {
      "ex:physicalCopies": 5
   }
}

Licenses do not need to be created for each site on the Web. In many cases, common licenses can be placed on a website and re-used by a large number of sites that sell assets under similar license terms.

6.3 Publishing a Listing

A listing describes the combination of an asset that is for sale under a specific license and a set of payment terms that must be fulfilled in order to access the asset. Listings are often published on websites that sell assets via PaySwarm as a way to express things that are for sale, in a decentralized manner.

The following example describes an asset for sale for $0.05 USD under a license that covers acceptable use of blog posts. The offer is valid from March 2nd 2011 to March 3rd 2011. The only restriction on additional payees is that the PaySwarm Authority (the organization processing the payment) may only take a maximum of 10% of the final sale price to cover their fees.

{
   "@context": "http://purl.org/payswarm/v1",
   "@subject": "http://example.com/articles/1#listing",
   "@type": ["gr:Offering", "ps:Listing"],
   "com:payee": 
   [
      {
         "@subject": "http://example.com/articles/1#listing-payee",
         "@type": "com:Payee",
         "com:currency": "USD",
         "com:destination": "https://payswarm.example.com/i/bob/accounts/primary",
         "com:rate": "0.05",
         "com:rateType": "com:FlatAmount",
         "rdfs:comment": "Payment for PaySwarm in Practice by Digital Bazaar."
      }
   ],
   "com:payeeRule": 
   [
      {
         "@type": "com:PayeeRule",
         "com:destinationOwnerType": "ps:Authority",
         "com:maximumRate": "10",
         "com:rateType": "com:InclusivePercentage"
      }
   ],
   "ps:asset": "http://example.com/articles/1#asset",
   "ps:assetHash": "14618b56ff597a2fed560db9aa0610fe442106a4",
   "ps:license": "http://payswarm.example.com/licenses/blogging",
   "ps:licenseHash": "0d8866836917f8ef58af44accb6efab9a10610ad",
   "sec:signature": 
   {
      "@type": "ps:JsonLdSignature",
      "dc:created": "2011-03-02T00:00:00Z",
      "dc:creator": "https://payswarm.example.com/i/bob/keys/4",
      "sec:signatureValue": "KXtwA5kXZBJzj1rkPMJmGDROjM+fpi2cJIB+Xqf10="
   },
   "ps:validFrom": "2011-03-02T00:00:00+0000",
   "ps:validUntil": "2011-03-03T00:00:00+0000"
}

6.4 Performing a Purchase

A normal purchase, as opposed to an automatic purchase, is typically performed via a Web browser-based user agent when the buyer has never performed a purchase with the vendor's website. The process consists of re-directing the Web browser to the buyer's PaySwarm Authority for the purposes of authorizing payment to the vendor for a particular listing. If a payment authorization is not approved, the user agent is re-directed back to the vendor's website with an error. If the payment authorization is approved, the user agent is re-directed bakc to the vendor's website with a short-form contract, which is used as a proof-of-purchase for the vendor's listing.

6.4.1 Purchase Terms

There are a number of terms that are used during the course of the purchase process.

listing hash
An identifier created by processing a listing expressed as JSON-LD through the JSON-LD Universal Graph Normalization Algorithm (UGNA2011) and then generating a SHA-1 hash of the result.
purchase callback
An IRI that will be on the receiving end of an HTTP POST from the PaySwarm Authority with the result of a purchase request.
reference identifier
A string value that must be greater than one character and less than 256 characters used by the vendor to track purchases. These identifiers can be used to ensure that asset that can be purchased multiple times, like game tokens, can be tracked by the vendor. These identifiers also allow the vendor to protect against unintended double-purchasing due to network failures.
receipt
The resulting value of a purchase request, typically sent from the PaySwarm Authority to the publishing agent. The object typically contains a short-form contract as well as other information that may be pertinent to the transaction.

6.4.2 The Purchase Algorithm

The normative algorithm for performing a purchase is expressed below.

  1. The publishing agent initiates a purchase request for a specific listing by re-directing the user agent to the contracts service endpoint:
    1. Generate the purchase request IRI by concatenating the contracts service and the following IRI parameters:
      listing
      The URL-encoded listing IRI.
      listing-hash
      A SHA-1 hash of the listing after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
      callback
      A de-referenceable IRI that must be able to process an HTTP POST request from the PaySwarm Authority with the result of a purchase request.
      reference
      An optional, internal reference identifier used by the publishing agent to keep track of the purchase.
      nonce
      An optional cryptographic value that will be used in the encrypted response to the vendor. The response nonce is utilized to prevent replay attacks on the vendor.
    2. Perform an HTTP 303 redirect via the user agent to the purchase request IRI.
  2. The PaySwarm Authority processes the purchase request ending in either an error message or a short-form contract:
    1. If the purchase was denied or failed for any reason, the PaySwarm Authority performs an HTTP POST via the user agent back to the callback IRI supplied by the vendor during the initiation of the purchase request.
    2. If the purchase was successful, then a receipt is generated and transmitted to the vendor:
      1. To generate the receipt in JSON-LD format, the following pieces of information must be expressed:
        @context
        A single value containing the string http://purl.org/payswarm/v1 or a list containing that context IRI as the first member, where subsequent context declarations must not override any values in the first member.
        @type
        The value ps:Receipt.
        ps:preference
        An array of preferences that are requested by either the PaySwarm Authority or the buyer. All valid options are listed below:
        ps:preAuthorization - The buyer has pre-authorized future purchases for the vendor and thus the Automatic Purchasing Algorithm may be used for future purchases. If this preference setting is mentioned, the publishing agent should store the buyer's information, including the PaySwarm Authority IRI, for use in future automatic transactions.
        ps:contract
        The contract used in the receipt is a summary of the digital contract that was finalized via the PaySwarm Authority. It includes the minimum amount of information necessary for the publishing agent to correctly identify the listing that was transacted:
        @type
        The value ps:Contract.
        ps:asset
        An IRI to the asset that was purchased.
        ps:assetHash
        The SHA-1 hash of the asset information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
        com:reference
        The reference identifier, if one was suppied via the purchase request.
        ps:license
        An IRI to the license describing the rights associated with the asset that was purchased.
        ps:licenseHash
        The SHA-1 hash of the license information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
        ps:listing
        An IRI to the listing that was purchased.
        ps:listingHash
        The SHA-1 hash of the listing information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
        ps:assetAcquirer
        An IRI to the identity that acquired the asset.
      2. The PaySwarm Authority initiates an HTTP POST via the user agent back to the callback IRI supplied by the publishing agent during the initiation of the purchase request. The POST data is digitally signed according to the Request Signature Algorithm, using the public key of the PaySwarm Authority.
    3. The publishing agent acts upon the callback by granting access to the asset if the purchase was successful, or providing a page detailing why the purchase failed. The publishing agent should note any preferences in the receipt and utilize those preferences when processing future purchases from the buyer.

6.5 Performing Automatic Purchases

An automatic purchase is one where a vendor has been previously authorized by a buyer to perform purchases with the buyer's pre-authorized consent. This is typically used when the vendor is trusted, or when the buyer has set a spending limit with the vendor and does not want to be bothered unless that spending limit is reached. Automatic purchases are designed to get out of the way of the buyer and make the transactional flow as friction-free as possible.

6.5.1 Purchase Terms

There are a number of terms that are used during the course of the purchase process.

purchase request
A message consisting of a listing IRI, a listing hash, a buyer identity IRI, and an optional reference identifier. The message is typically sent by a publishing agent to a buyer's PaySwarm Authority for processing.

6.5.2 The Automatic Purchase Algorithm

The automatic purchase algorithm is outlined below:

  1. The publishing agent prepares a purchase request by constructing a JSON-LD message. The following pieces of information must be expressed:
    @context
    A single value containing the string http://purl.org/payswarm/v1 or a list containing that context IRI as the first member, where subsequent context declarations must not override any values in the first member.
    @type
    The value ps:PurchaseRequest.
    ps:listing
    An IRI to the listing that was purchased.
    ps:listingHash
    The SHA-1 hash of the listing information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
    ps:assetAcquirer
    An IRI to the identity that acquired the asset.
    com:reference
    The reference identifier, if one was suppied via the purchase request.
  2. The purchase request is digitally signed by the publishing agent according to the Request Signature Algorithm using the private key associated with the listing in the purchase request. The purchase request is sent to the PaySwarm Authority of the buyer via an HTTPS connection. The HTTPS protocol must be used for transmission of the request and retrieval of the response to prevent replay attacks.
  3. The PaySwarm Authority checks to ensure that the publishing agent is authorized to perform an automatic purchase on behalf of the provided buyer identity IRI and responds to the publishing agent:
    1. If the transaction fails, the exception details are placed into a JSON-LD message and sent to the publishing agent.
      Determine how PaySwarm will handle response exceptions.
    2. If the transaction is successful, a receipt is generated for the publishing agent. The following fields must be placed into the response:
      @context
      A single value containing the string http://purl.org/payswarm/v1 or a list containing that context IRI as the first member, where subsequent context declarations must not override any values in the first member.
      @type
      The value ps:Receipt.
      ps:contract
      The contract used in the receipt is a summary of the digital contract that was finalized via the PaySwarm Authority. It includes the minimum amount of information necessary for the publishing agent to correctly identify the listing that was transacted:
      @type
      The value ps:Contract.
      ps:asset
      An IRI to the asset that was purchased.
      ps:assetHash
      The SHA-1 hash of the asset information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
      com:reference
      The reference identifier, if one was suppied via the purchase request.
      ps:license
      An IRI to the license describing the rights associated with the asset that was purchased.
      ps:licenseHash
      The SHA-1 hash of the license information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
      ps:listing
      An IRI to the listing that was purchased.
      ps:listingHash
      The SHA-1 hash of the listing information after being normalized using the JSON-LD Universal Graph Normalization Algorithm (UGNA2011).
      ps:assetAcquirer
      An IRI to the identity that acquired the asset.
    3. The receipt is encrypted according to the Response Encryption Algorithm, using the public key associated with the private key that digitally signed the listing. The encrypted receipt is sent to the publishing agent.
  4. The publishing agent receives the response, which will either be an exception or a receipt, and responds accordingly to the user agent.

6.6 The Contract

A contract is the result of a commercial transaction in PaySwarm and contains information such as the listing, the asset that was purchased, the parties involved in the transaction, the license outlining the rights to the asset, and payment information associated with the transaction.

The following example describes a purchase that occurred on March 2nd 2011 for a Web-based article called "PaySwarm in Practice". The article was authored and listed for sale by Bob Smith and a personal use license was acquired by Jane, who may now peruse the article.

{
   "@context": "http://purl.org/payswarm/v1",
   "@subject": "http://payswarm.example.com/contracts/28394729347",
   "@type": ["ps:Transaction", "ps:Contract"],
   "com:amount": "0.05",
   "com:currency": "USD",
   "dc:created": "2011-03-02T03:00:53Z",
   "com:payee": 
   [
      {
         "@type": "com:Payee",
         "com:currency": "USD",
         "com:destination": "https://payswarm.example.com/i/authority/accounts/main",
         "com:payeePosition": 0,
         "com:rate": "10.00",
         "com:rateContext": "com:TaxExempt",
         "com:rateType": "com:InclusivePercentage",
         "rdfs:comment": "PaySwarm Authority Transaction Processing"
      }
   ],
   "com:transfer": 
   [
      {
         "@type": "com:Transfer",
         "com:amount": "0.045",
         "com:currency": "USD",
         "com:destination": "https://payswarm.example.com/i/bob/accounts/primary",
         "com:forTransaction": "http://payswarm.example.com/contracts/28394729347",
         "com:source": "https://payswarm.example.com/i/jane/accounts/primary",
         "rdfs:comment": "Payment for PaySwarm in Practice by Bob Smith."
      },
      {
         "@type": "com:Transfer",
         "com:amount": "0.005",
         "com:currency": "USD",
         "com:destination": "https://payswarm.example.com/i/authority/accounts/main",
         "com:forTransaction": "http://payswarm.example.com/contracts/28394729347",
         "com:source": "https://payswarm.example.com/i/jane/accounts/primary",
         "rdfs:comment": "PaySwarm Authority Transaction Processing"
      }
   ],
   "dc:created": "2011-03-02T03:00:53Z",
   "ps:asset": 
   {
      "@subject": "http://example.com/articles/1#asset",
      "@type": ["ps:Asset", "ps:WebPage"],
      "dc:creator": 
      {
         "foaf:name": "Bob Smith"
      },
      "dc:title": "PaySwarm in Practice",
      "ps:assetProvider": "https://payswarm.example.com/i/bob",
      "ps:authority": "https://payswarm.example.com/client-config",
      "ps:contentUrl": "http://example.com/articles/1",
      "sec:signature": 
      {
         "@type": "ps:JsonLdSignature",
         "dc:created": "2011-03-02T00:00:00Z",
         "dc:creator": "https://payswarm.example.com/i/bob/keys/4",
         "sec:signatureValue": "XuLEGuq+ne56Qsc5Nic8I="
      }
   },
   "ps:assetAcquirer": "https://payswarm.example.com/i/jane",
   "ps:assetProviderIdentity": 
   {
      "ps:identityHash": "df913752be56fe0d37dcedc2d7f44708373d2a68"
   },
   "ps:license": 
   {
      "@subject": "http://payswarm.example.com/licenses/blogging",
      "@type": "ps:License",
      "dc:format": "text/html",
      "ps:licenseTemplate": "Personal Use License ..."
   },
   "ps:listing": 
   {
      "@subject": "http://example.com/articles/1#listing",
      "@type": ["gr:Offering", "ps:Listing"],
      "com:payee": 
      [
         {
            "@subject": "http://example.com/articles/1#listing-payee",
            "@type": "com:Payee",
            "com:currency": "USD",
            "com:destination": "https://payswarm.example.com/i/bob/accounts/primary",
            "com:rate": "0.05",
            "com:rateType": "com:FlatAmount",
            "rdfs:comment": "Payment for PaySwarm in Practice by Digital Bazaar."
         }
      ],
      "com:payeeRule": 
      [
         {
            "@type": "com:PayeeRule",
            "com:destinationOwnerType": "ps:Authority",
            "com:maximumRate": "10",
            "com:rateType": "com:InclusivePercentage"
         }
      ],
      "ps:asset": "http://example.com/articles/1#asset",
      "ps:assetHash": "14618b56ff597a2fed560db9aa0610fe442106a4",
      "ps:license": "http://payswarm.example.com/licenses/blogging",
      "ps:licenseHash": "0d8866836917f8ef58af44accb6efab9a10610ad",
      "sec:signature": 
      {
         "@type": "ps:JsonLdSignature",
         "dc:created": "2011-03-02T00:00:00Z",
         "dc:creator": "https://payswarm.example.com/i/bob/keys/4",
         "sec:signatureValue": "KXtwA5kXZBJzj1rkPMJmGDROjM+fpi2cJIB+Xqf10="
      },
      "ps:validFrom": "2011-03-02T00:00:00+0000",
      "ps:validUntil": "2011-03-03T00:00:00+0000"
   },
   "ps:listingHash": "1acbd23c3a7d8827270a959a2760f7c4ded98022",
   "sec:signature": 
   {
      "@type": "ps:JsonLdSignature",
      "dc:created": "2011-03-02T03:00:53Z",
      "dc:creator": "https://payswarm.example.com/i/authority/keys/1",
      "sec:signatureValue": "ZnGaAs0QCIfEAvCsj2TxRTs8ekQrbbQUXvTLWcQ0kQ=="
   }
}

6.7 Verifying a Purchase

7. The PaySwarm API

8. Implementation Details

8.1 Digital Signatures

8.1.1 Signing

8.1.2 Verifying

9. Data Portability

One of the freedoms that is ensured by this specification is the freedom to own your data and move it to a PaySwarm Authority of your choosing. That is, your transaction history is your property and therefore you must be able to move it to a location of your choosing at will. In order to ensure that this freedom is protected, data portability must be implemented by all conforming implementations of this specification.

9.1 Transfering Purchase History

10. Security Concerns

10.1 Identity Management

10.2 Digital Signatures

10.3 Identifying and Removing Troublemakers

10.4 Halting Asset Distribution

A. References

A.1 Normative references

[FIPS-197]
Information Technology Laboratory. Specification for the ADVANCED ENCRYPTION STANDARD (AES) November 26th, 2001. Department of Commerce, National Institute of Standards and Technology. URL: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
[HTML-RDFA]
Manu Sporny; et al. HTML+RDFa 04 March 2010. W3C Working Draft. URL: http://www.w3.org/TR/rdfa-in-html/
[IRI]
M. Duerst, M. Suignard. Internationalized Resource Identifiers (IRI). January 2005. Internet RFC 3987. URL: http://www.ietf.org/rfc/rfc3987.txt
[JSON-LD]
Manu Sporny; Gregg Kellogg; Dave Longley; et al. JSON-LD latest. W3C Community Group Working Draft. URL: http://json-ld.org/spec/latest/
[RDFA-CORE]
Shane McCarron; et al. RDFa Core 1.1: Syntax and processing rules for embedding RDF through attributes. 31 March 2011. W3C Working Draft. URL: http://www.w3.org/TR/2011/WD-rdfa-core-20110331

A.2 Informative references

[AES]
NIST FIPS 197: Advanced Encryption Standard (AES). November 2001. URL: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
[REST]
Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures 2000. University of California, Irvine. URL: http://www.ics.uci.edu/~fielding/pubs/dissertation/